前言
女孩子都喜歡用美圖工具進行圖片美容,近來無事時,特意為某人寫了個自定義圖片濾鏡生成器,安裝到手機即可完成自定義濾鏡渲染照片。app獨一無二,雖簡亦繁。
JH定律:
魔鏡:最漂亮的女人是你老婆
魔鏡:程序員不是木頭人
核心技術
圖片濾鏡核心技術的基本思路如下:
核心技術流程
具體流程
1、創建一個圖像處理工具類
注:該類實例包括一個圖像處理方法,該方法在傳入原始圖像和一個顏色矩陣後生成一個處理好的圖像。
@interface JHFeilterManager : NSObject @property (nonatomic,copy)imageBlock imageBLOCK; - (UIImage *)createImageWithImage:(UIImage *)inImage colorMatrix:(const float *)f;
2、獲取圖像的每個像素點的RGBA值數組
注:該c方法返回一個指針,該指針指向一個數組,數組中的每四個元素都是圖像上的一個像素點的RGBA的數值(0-255),用無符號的char是因為它正好的取值范圍就是0-255
static unsigned char *RequestImagePixelData(UIImage * inImage){ CGImageRef img = [inImage CGImage]; CGSize size = [inImage size]; //使用上面的函數創建上下文 CGContextRef cgctx = CreateRGBABitmapContex(img); CGRect rect = {{0,0},{size.width,size.height}}; //將目標圖像繪制到指定的上下文,實際為上下文內的bitmapData。 CGContextDrawImage(cgctx, rect, img); unsigned char *data = CGBitmapContextGetData(cgctx); //釋放上面的函數創建的上下文 CGContextRelease(cgctx); cgctx = NULL; return data; }
3、調整一個像素點的RGBA值
注:如下方法傳入參數為數值指針和一個顏色矩陣,通過顏色矩陣調整指針指向地址存儲的數值
static void changeRGB(int *red,int* green,int*blue,int*alpha ,const float *f){ int redV = *red; int greenV = *green; int blueV = *blue; int alphaV = *alpha; //色值重新計算 計算規則如下 *red = f[0] * redV + f[1]*greenV + f[2]*blueV + f[3] * alphaV + f[4]; *green = f[5] * redV + f[6]*greenV + f[7]*blueV + f[8] * alphaV+ f[9]; *blue = f[10] * redV + f[11]*greenV + f[12]*blueV + f[11] * alphaV+ f[14]; *alpha = f[15] * redV + f[16]*greenV + f[17]*blueV + f[18] * alphaV+ f[19]; *red < 0 ? (*red = 0):(0); *red > 255 ? (*red = 255):(0); *green < 0 ? (*green = 0):(0); *green > 255 ? (*green = 255):(0); *blue < 0 ? (*blue = 0):(0); *blue > 255 ? (*blue = 255):(0); *alpha < 0 ? (*alpha = 0):(0); *alpha > 255 ? (*alpha = 255):(0); }
4、遍歷每個像素,調整色值
注意!!!
在以下方法中,不要立刻釋放malloc方法生成的bitmapData內存空間指針,(可能有的朋友覺得已經把內存空間地址給了位圖上下文就可以立馬釋放掉了,但是實際上,由於位圖上下文在後來的圖像渲染時,仍然需要這一塊內存,因此不能在此處立馬釋放掉內存,之前拜讀的幾篇博客索性就不釋放內存了,因此會導致內存洩漏,處理一些高清圖像時,手機內存會輕易飙升到1G以上,而導致程序掛掉)不然會導致位圖上下文的內容數據不能正常存在而導致圖片生成失敗,在這裡需要一個全局內存指針來指向它,並且在合適的時候釋放內存。
該方法中需要傳入一個原始圖片信息和一個顏色矩陣,顏色矩陣決定了圖像的渲染效果,因此不同的濾鏡效果可以通過設置不同的顏色矩陣進行轉換,如果您不了解顏色矩陣,點擊這裡進行了解
- (UIImage *)createImageWithImage:(UIImage *)inImage colorMatrix:(const float *)f{ /* 圖片位圖像素值數組 */ unsigned char *imgPixel = RequestImagePixelData(inImage); CGImageRef inImageRef = [inImage CGImage]; /* 獲取像素的橫向和縱向個數 */ long w = CGImageGetWidth(inImageRef); long h = CGImageGetHeight(inImageRef); int wOff = 0; int pixOff = 0; /* 遍歷修改位圖像素值 */ for (long y = 0; y5、UI搭建
UI界面非常簡單,就是一張大圖、20個顏色矩陣的信息錄入框和兩個按鈕組成,代碼就不過多贅述了,有需要的話可以到這裡下載demo,喜歡的話不防給個star哦。
成果展示
成型的demo就是這個樣子喽!