生活随笔
收集整理的這篇文章主要介紹了
iOS中的图像处理(一)——基础滤镜
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近在稍微做一些整理,翻起這部分的代碼,發現是兩個多月前的了。
這里討論的是基于RGBA模型下的圖像處理,即將變換作用在每個像素上。
代碼是以UIImage的category形式存在的:
?
[cpp] view plaincopy
typedef?struct?_singleRGBA??{??????unsigned?char?red;??????unsigned?char?green;??????unsigned?char?blue;??????unsigned?char?alpha;??}?RGBA;????@interface?UIImage?(ImageFilter)??
首先,我們需要獲得目標圖像的位圖信息;然后對每個像素進行變換;最后再生成圖像。
?
[cpp] view plaincopy
-?(UIImage*)applyFilter:(FilterFunction)filter?context:(void*)context??{??????CGImageRef?inImage?=?self.CGImage;??????CFDataRef?m_DataRef?=?CGDataProviderCopyData(CGImageGetDataProvider(inImage));??????UInt8?*m_PixelBuf?=?(UInt8?*)CFDataGetBytePtr(m_DataRef);????????????int?length?=?CFDataGetLength(m_DataRef);????????????for?(int?i=0;?i<length;?i+=4)?{??????????filter(m_PixelBuf,?i,?context);??????}????????????CGContextRef?ctx?=?CGBitmapContextCreate(m_PixelBuf,???????????????????????????????????????????????CGImageGetWidth(inImage),???????????????????????????????????????????????CGImageGetHeight(inImage),???????????????????????????????????????????????CGImageGetBitsPerComponent(inImage),???????????????????????????????????????????????CGImageGetBytesPerRow(inImage),???????????????????????????????????????????????CGImageGetColorSpace(inImage),???????????????????????????????????????????????CGImageGetBitmapInfo(inImage)???????????????????????????????????????????????);????????????CGImageRef?imageRef?=?CGBitmapContextCreateImage(ctx);??????CGContextRelease(ctx);??????UIImage?*finalImage?=?[UIImage?imageWithCGImage:imageRef];??????CGImageRelease(imageRef);??????CFRelease(m_DataRef);????????????return?finalImage;??}??
其中,FilterFunction聲明如下:
?
[cpp] view plaincopy
typedef?void?(*FilterFunction)(UInt8?*pixelBuf,?UInt32?offset,?void?*context);?? 在此基礎上,我們可以把每個變換操作獨立出來,比如調整亮度、對比度、色調、透明度等:
?
[cpp] view plaincopy
void?filterOpacity(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????double?val?=?*((double*)context);????????????int?a?=?offset+3;????????????int?alpha?=?pixelBuf[a];????????????pixelBuf[a]?=?SAFECOLOR(alpha?*?val);??}????void?filterBrightness(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????double?t?=?*((double*)context);????????????int?r?=?offset;??????int?g?=?offset+1;??????int?b?=?offset+2;????????????int?red?=?pixelBuf[r];??????int?green?=?pixelBuf[g];??????int?blue?=?pixelBuf[b];????????????pixelBuf[r]?=?SAFECOLOR(red?*?t);??????pixelBuf[g]?=?SAFECOLOR(green?*?t);??????pixelBuf[b]?=?SAFECOLOR(blue?*?t);??}????void?filterSaturation(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????double?t?=?*((double*)context);???????????int?r?=?offset;??????int?g?=?offset+1;??????int?b?=?offset+2;????????????int?red?=?pixelBuf[r];??????int?green?=?pixelBuf[g];??????int?blue?=?pixelBuf[b];????????????red?=?red?*?(0.3086?*?(1-t)?+?t)?+?green?*?(0.6094?*?(1-t))?+?blue?*?(0.0820?*?(1-t));??????green?=?red?*?(0.3086?*?(1-t))?+?green?*?((0.6094?*?(1-t))?+?t)?+?blue?*?(0.0820?*?(1-t));??????blue?=?red?*?(0.3086?*?(1-t))?+?green?*?(0.6094?*?(1-t))?+?blue?*?((0.0820?*?(1-t))?+?t);????????????pixelBuf[r]?=?SAFECOLOR(red);??????pixelBuf[g]?=?SAFECOLOR(green);??????pixelBuf[b]?=?SAFECOLOR(blue);??}????void?filterContrast(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????double?t?=?*((double*)context);???????????int?r?=?offset;??????int?g?=?offset+1;??????int?b?=?offset+2;????????????int?red?=?pixelBuf[r];??????int?green?=?pixelBuf[g];??????int?blue?=?pixelBuf[b];????????????red?=?red?*?t?+?128?*?(1-t);??????green?=?green?*?t?+?128?*?(1-t);??????blue?=?blue?*?t?+?128?*?(1-t);????????????pixelBuf[r]?=?SAFECOLOR(red);??????pixelBuf[g]?=?SAFECOLOR(green);??????pixelBuf[b]?=?SAFECOLOR(blue);??}????void?filterPosterize(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????double?levels?=?*((double*)context);??????if?(levels?==?0)?levels?=?1;?????int?step?=?255?/?levels;????????????int?r?=?offset;??????int?g?=?offset+1;??????int?b?=?offset+2;????????????int?red?=?pixelBuf[r];??????int?green?=?pixelBuf[g];??????int?blue?=?pixelBuf[b];????????????pixelBuf[r]?=?SAFECOLOR((red?/?step)?*?step);??????pixelBuf[g]?=?SAFECOLOR((green?/?step)?*?step);??????pixelBuf[b]?=?SAFECOLOR((blue?/?step)?*?step);??}????void?filterDesaturate(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????int?r?=?offset;??????int?g?=?offset+1;??????int?b?=?offset+2;????????????int?red?=?pixelBuf[r];??????int?green?=?pixelBuf[g];??????int?blue?=?pixelBuf[b];????????????red?=?red?*?0.3086?+?green?*?0.6094?+?blue?*?0.0820;??????green?=?red?*?0.3086?+?green?*?0.6094?+?blue?*?0.0820;??????blue?=?red?*?0.3086?+?green?*?0.6094?+?blue?*?0.0820;????????????pixelBuf[r]?=?SAFECOLOR(red);??????pixelBuf[g]?=?SAFECOLOR(green);??????pixelBuf[b]?=?SAFECOLOR(blue);??}????void?filterInvert(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????int?r?=?offset;??????int?g?=?offset+1;??????int?b?=?offset+2;????????????int?red?=?pixelBuf[r];??????int?green?=?pixelBuf[g];??????int?blue?=?pixelBuf[b];????????????pixelBuf[r]?=?SAFECOLOR(255-red);??????pixelBuf[g]?=?SAFECOLOR(255-green);??????pixelBuf[b]?=?SAFECOLOR(255-blue);??}????void?filterTint(UInt8?*pixelBuf,?UInt32?offset,?void?*context)??{??????RGBA?*rgbaArray?=?(RGBA*)context;??????RGBA?maxRGBA?=?rgbaArray[0];??????RGBA?minRGBA?=?rgbaArray[1];????????????int?r?=?offset;??????int?g?=?offset+1;??????int?b?=?offset+2;????????????int?red?=?pixelBuf[r];??????int?green?=?pixelBuf[g];??????int?blue?=?pixelBuf[b];????????????pixelBuf[r]?=?SAFECOLOR((red?-?minRGBA.red)?*?(255.0?/?(maxRGBA.red?-?minRGBA.red)));??????pixelBuf[g]?=?SAFECOLOR((green?-?minRGBA.green)?*?(255.0?/?(maxRGBA.green?-?minRGBA.green)));??????pixelBuf[b]?=?SAFECOLOR((blue?-?minRGBA.blue)?*?(255.0?/?(maxRGBA.blue?-?minRGBA.blue)));??}??
其中SAFECOLOR宏如下:
[cpp] view plaincopy
#define?SAFECOLOR(color)?MIN(255,MAX(0,color))?? 最后,拿一張帥氣的Andy照片來實踐下,希望沒有侵犯到肖像權。
原圖如下:
通過以下四種變換,可以分別得到四張處理過的圖片:
?
[cpp] view plaincopy
return?[originImage?changeOpacityByFactor:0.5];?? [cpp] view plaincopy
return?[originImage?changeBrightnessByFactor:1.2];?? [cpp] view plaincopy
return?[originImage?changeSaturationByFactor:2.0];?? [cpp] view plaincopy
return?[originImage?tintWithMaxRGBA:(RGBA){190,?190,?230}?minRGBA:(RGBA){50,?35,?10}];?? ??
?
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
總結
以上是生活随笔為你收集整理的iOS中的图像处理(一)——基础滤镜的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。