首先什么是位圖其掂?
****位圖圖像(bitmap), 亦稱為點(diǎn)陣圖像或繪制圖像,是由稱作像素(圖片元素)的單個點(diǎn)組成的(百度百科)。****
由于在iOS開發(fā)中使用的位圖大部分是32位RGBA模式碍彭,所以我們之說下這種模式的簡單圖像處理。
首先我們需要知道什么是32位RGBA模式的位圖悼潭。32位就表示一個這種模式位圖的一個像素所占內(nèi)存為32位庇忌,也就是4個字節(jié)的長度。R舰褪、G皆疹、B、A分別代表red占拍,green略就,blue和alpha捎迫,也就是顏色組成的三原色與透明度值。RGBA每一個占用一個字節(jié)的內(nèi)存表牢。
知道了上面這些窄绒,我們就有了思路:通過改變每一個像素中的RGBA值來進(jìn)行一些位圖圖像的處理了。
首先我們試著把下面這張圖轉(zhuǎn)化為一張紅色的圖崔兴。
我們首先了解一下CGImageRef的結(jié)構(gòu)
CGImageRef CGImageCreate (
size_t width, //圖片的寬度
size_t height, //圖片的高度
size_t bitsPerComponent, //圖片每個顏色的bits
size_t bitsPerPixel, //每一個像素占用的bits彰导,156位24位 32位等等
size_t bytesPerRow, //每一行占用多少bytes 注意是bytes不是bits 1byte = 8bit
CGColorSpaceRef colorspace, //顏色空間,比如rgb
CGBitmapInfo bitmapInfo, //layout 敲茄,像素中bit的布局位谋, 是rgba還是 argb
CGDataProviderRef provider, //數(shù)據(jù)源提供者,url或者內(nèi)存...
const CGFloat decode[], //一個解碼數(shù)組
bool shouldInterpolate, //抗鋸齒參數(shù)
CGColorRenderingIntent intent //圖片渲染相關(guān)參數(shù)
}
了解了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);
}
});
});
}
這樣我們就得到了一張紅色的圖像
當(dāng)然我們還可以改變很多
我們把這段代碼
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;
}