图像处理是软件开发中很重要的一门技术,像ps,各种美颜app,主要就是运用到它。
在apple相关开发领域,图像处理主要有下面几种技术:
. 直接修改位图图像
. 使用Core Graphics库
. 使用Core Image库
. 使用GPUImage第三方库
. 使用OpenCV第三方库
其中,直接修改位图图像是图像处理的基础,不管你多高明的算法,归根结底是要修改原图每个像素的颜色值和透明度。
下面的方法创建一个图片的缓存数据,把各个像素的颜色值存进一个数组里以供修改。
- (void)createImageBuffer:(UIImage*)source{
CGImageRef inputImage = source.CGImage;
NSUInteger width = source.size.width;
NSUInteger height = source.size.height;
NSUInteger bytesPerPixel =4;// 每个像素4个字节表示
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;// 应该是每个颜色通道由8个bit位表示
UInt32* pixels;
pixels = (UInt32*)calloc(width * height,sizeof(UInt32));
CGColorSpaceRefcolorSpace =CGColorSpaceCreateDeviceRGB();
CGContextRefcontext =CGBitmapContextCreate(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpace,kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Big);
// 创建一个容器CGBitmapContext,将像素指针参数传递到容器中
CGContextDrawImage(context,CGRectMake(0,0, width, height), inputImage);
// 这句要有,不然数据写不到pixels数组中
}
pixels数组里就是图片数据,可以通过如下方式修改:
for(NSUIntegerj =0; j < height; j++) {
for(NSUIntegeri =0; i < width; i++) {
UInt32* currentPixel = pixels + (j * width) + i;
UInt32color = *currentPixel;
UInt32thisR,thisG,thisB,thisA;
//这里直接移位获得RBGA的值
thisR=R(color);
thisG=G(color);
thisB=B(color);
thisA=A(color) *.5;// 这里是通过把每个像素的透明度乘以.5以改变整个图的透明度
*currentPixel =RGBAMake(thisR, thisG, thisB, thisA);
}
}
修改图片数据后,可以通过
CGImageRef ref =CGBitmapContextCreateImage(context);
UIImage* image = [UIImageimageWithCGImage:ref];
获取到修改后的图片
当然,完成后还要释放相关变量
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
free(pixels);
需要用到这些宏定义:
#define Mask8(x) ( (x) &0xFF)
#define R(x) ( Mask8(x) )
#define G(x) ( Mask8(x >>8) )
#define B(x) ( Mask8(x >>16) )
#define A(x) ( Mask8(x >> 24) )
#define RGBAMake(r, g, b, a) ( Mask8(r) | Mask8(g) << 8 | Mask8(b) << 16 | Mask8(a) << 24 )
关于原点坐标的问题:
UIImage和UIView使用的是左上原点坐标,NSImage,NSView,Core Image和Core Graphics使用的是左下原点坐标
关于渲染的问题:
1 当前屏幕渲染:在GPU的当前屏幕缓冲区中进行的渲染
2 离屏渲染:在GPU当前屏幕缓冲区外另建缓冲区渲染
3 CPU渲染:如重写drawRect,用到core graphics技术绘图(特殊的离屏渲染)
.. 2比1效率低,因为要新建缓冲区,要切换缓冲区的上下文
.. 3比起1,2,缺点是CUP的浮点运算能力比GPU差
.. 尽量用1,对于简单的效果,3又比2强,因为运算能力的略势比不上创建缓冲区和切换上下文的消耗
网友评论