一张图片是像素点的集合,每一个像素都有独立、明了的颜色。图像一般情况下都存储成数组,可以理解为二维数组。
当成千上万个像素集合到一起时,就构成了图像。
表示图形的方式有很多种,最简单的是32位RGBA模式。
图片压缩
png:UIImagePNGRepresentation(image)
jpg:UIImageJPEGRepresentation(image, 1.0)
jpg的压缩效果较png好,且可以设置压缩比例。系统的png压缩方法甚至会发生压缩后的图片大小远远大于压缩前。原因是bitmap渲染时,会按照宽高位计算得出图片内存,压缩的是图片内容(像素)而非文件格式。
上下文压缩
- (UIImage *)scaleImage:(UIImage *)image size:(CGSize)imageSize {
UIGraphicsBeginImageContext(imageSize);
[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
根据上下文绘制后再压缩,结果图片会更小,且不会出现图片大小大于原图的情况
图片过滤
从图片文件中把图片数据的像素拿出来(RGBA),对像素进行转换操作(Bitmap(GPU)),修改完之后还原
- (UIImage *)filterImage:(UIImage *)image {
CGImageRef imageRef = image.CGImage;
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
size_t bits = CGImageGetBitsPerComponent(imageRef);
size_t bitsPerrow = CGImageGetBitsPerComponent(imageRef);
// 颜色空间
CGColorSpaceRef colorSpaceRef = CGImageGetColorSpace(imageRef);
// bitmap 数据
CGDataProviderRef providerRef = CGImageGetDataProvider(imageRef);
CFDataRef bitmapData = CGDataProviderCopyData(providerRef);
NSInteger pixLength = CFDataGetLength(bitmapData);
Byte *pixbuf = CFDataGetMutableBytePtr(bitmapData);
for (int i = 0; i < pixLength; i += 4) {
[self imageFilePixBuf:pixbuf offset:i];
}
// 绘制图片 bitmap 生成上下文 再通过上下文生成图片
CGContextRef contextRef = CGBitmapContextCreate(pixbuf, width, height, bits, bitsPerrow, colorSpaceRef, CGImageGetAlphaInfo(imageRef));
CGImageRef filterImageRef = CGBitmapContextCreateImage(contextRef);
UIImage *filterImage = [UIImage imageWithCGImage:filterImageRef];
return filterImage;
}
// RGBA为一个单元 彩色变黑白
- (void)imageFilePixBuf:(Byte *)pixBuf offset:(int)offset {
int offsetR = offset;
int offsetG = offset + 1;
int offsetB = offset + 2;
// int offsetA = offset + 3;
int red = pixBuf[offsetR];
int green = pixBuf[offsetG];
int blue = pixBuf[offsetB];
// int alpha = pixBuf[offsetA];
int gray = (red + green + blue) / 3;
pixBuf[offsetR] = gray;
pixBuf[offsetG] = gray;
pixBuf[offsetB] = gray;
}
裁剪图片
- (UIImage *)clipImage:(UIImage *)image {
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
CGContextRef contexRef = UIGraphicsGetCurrentContext();
// 规则裁剪
/*
CGRect rect = CGRectMake(0, 0, 200, 200);
CGContextAddEllipseInRect(contexRef, rect);
CGContextClip(contexRef);
[image drawInRect:CGRectMake(0, 0, 200, 200)];
*/
// 非规则裁剪
CGMutablePathRef pathRef = CGPathCreateMutable();
CGPoint lines[] = {
CGPointMake(0, 0),
CGPointMake(150, 70),
CGPointMake(200, 200),
CGPointMake(50, 120),
CGPointMake(0, 0)
};
CGPathAddLines(pathRef, NULL, lines, 5);
CGContextAddPath(contexRef, pathRef);
CGContextClip(contexRef);
[image drawInRect:CGRectMake(0, 0, 200, 200)];
// 这个上下文获取的是传进来的image,非drawInRect处理后的image,所以drawInRect方法应该写在裁剪处理之后才有效果
UIImage *clipImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return clipImage;
}
渲染
- (UIImage *)blendImage:(UIImage *)image {
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
CGContextRef contexRef = UIGraphicsGetCurrentContext();
[image drawInRect:CGRectMake(0, 0, 200, 200)];
UIColor *redColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.5];
CGContextSetFillColorWithColor(contexRef, redColor.CGColor);
CGContextSetBlendMode(contexRef, kCGBlendModeNormal);
CGContextFillRect(contexRef, CGRectMake(0, 0, 200, 200));
CGImageRef imageRef = CGBitmapContextCreateImage(contexRef);
UIImage *backImage = [UIImage imageWithCGImage:imageRef];
UIGraphicsEndImageContext();
return backImage;
}
截屏
- (UIImage *)imageFromFullView {
UIGraphicsBeginImageContext(self.view.frame.size);
CGContextRef contexRef = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:contexRef];
CGImageRef imageRef = CGBitmapContextCreateImage(contexRef);
UIImage *backImage = [UIImage imageWithCGImage:imageRef];
UIGraphicsEndImageContext();
return backImage;
}
网友评论