首先什么是位图?
****位图图像(bitmap), 亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的(百度百科)。****
由于在iOS开发中使用的位图大部分是32位RGBA模式,所以我们之说下这种模式的简单图像处理。
首先我们需要知道什么是32位RGBA模式的位图。32位就表示一个这种模式位图的一个像素所占内存为32位,也就是4个字节的长度。R、G、B、A分别代表red,green,blue和alpha,也就是颜色组成的三原色与透明度值。RGBA每一个占用一个字节的内存。
知道了上面这些,我们就有了思路:通过改变每一个像素中的RGBA值来进行一些位图图像的处理了。
首先我们试着把下面这张图转化为一张红色的图。
原图我们首先了解一下CGImageRef的结构
CGImageRef CGImageCreate (
size_t width, //图片的宽度
size_t height, //图片的高度
size_t bitsPerComponent, //图片每个颜色的bits
size_t bitsPerPixel, //每一个像素占用的buts,15 位24位 32位等等
size_t bytesPerRow, //每一行占用多少bytes 注意是bytes不是bits 1byte = 8bit
CGColorSpaceRef colorspace, //颜色空间,比如rgb
CGBitmapInfo bitmapInfo, //layout ,像素中bit的布局, 是rgba还是 argb
CGDataProviderRef provider, //数据源提供者,url或者内存...
const CGFloat decode[], //一个解码数组
bool shouldInterpolate, //抗锯齿参数
CGColorRenderingIntent intent //图片渲染相关参数
}
了解了image的效果我们就可以撸代码了
- (void)HandleImage:(UIImage *)img complite:(void(^)(UIImage *img))complite
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
CGImageRef imgref = img.CGImage;
size_t width = CGImageGetWidth(imgref);
size_t height = CGImageGetHeight(imgref);
size_t bitsPerComponent = CGImageGetBitsPerComponent(imgref);
size_t bitsPerPixel = CGImageGetBitsPerPixel(imgref);
size_t bytesPerRow = CGImageGetBytesPerRow(imgref);
CGColorSpaceRef colorSpace = CGImageGetColorSpace(imgref);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imgref);
bool shouldInterpolate = CGImageGetShouldInterpolate(imgref);
CGColorRenderingIntent intent = CGImageGetRenderingIntent(imgref);
CGDataProviderRef dataProvider = CGImageGetDataProvider(imgref);
CFDataRef data = CGDataProviderCopyData(dataProvider);
UInt8 *buffer = (UInt8*)CFDataGetBytePtr(data);//Returns a read-only pointer to the bytes of a CFData object.// 首地址
NSUInteger x, y;
// 像素矩阵遍历,改变成自己需要的值
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
UInt8 *tmp;
tmp = buffer + y * bytesPerRow + x * 4;
UInt8 alpha;
alpha = *(tmp + 3);
if (alpha) {// 透明不处理 其他变成红色
*tmp = 255;//red
*(tmp + 1) = 0;//green
*(tmp + 2) = 0;// Blue
}
}
}
CFDataRef effectedData = CFDataCreate(NULL, buffer, CFDataGetLength(data));
CGDataProviderRef effectedDataProvider = CGDataProviderCreateWithCFData(effectedData);
// 生成一张新的位图
CGImageRef effectedCgImage = CGImageCreate(
width, height,
bitsPerComponent, bitsPerPixel, bytesPerRow,
colorSpace, bitmapInfo, effectedDataProvider,
NULL, shouldInterpolate, intent);
UIImage *effectedImage = [[UIImage alloc] initWithCGImage:effectedCgImage];
CGImageRelease(effectedCgImage);
CFRelease(effectedDataProvider);
CFRelease(effectedData);
CFRelease(data);
dispatch_async(dispatch_get_main_queue(), ^{
if (complite) {
complite(effectedImage);
}
});
});
}
这样我们就得到了一张红色的图像
红色图像当然我们还可以改变很多
我们把这段代码
UInt8 *tmp;
tmp = buffer + y * bytesPerRow + x * 4;
UInt8 alpha;
alpha = *(tmp + 3);
if (alpha) {// 透明不处理 其他变成红色
*tmp = 255;//red
*(tmp + 1) = 0;//green
*(tmp + 2) = 0;// Blue
}
换成
UInt8 *tmp;
tmp = buffer + y * bytesPerRow + x * 4;
UInt8 alpha;
alpha = *(tmp + 3);
UInt8 temp = *tmp;// 取red值
if (alpha) {// 透明不处理 其他变成红色
// 将green和blue都改成red的值,获取灰色图
*(tmp + 1) = temp;
*(tmp + 2) = temp;
}
灰色图
网友评论