iOS --- 通過CPU實現的簡單濾鏡效果

來源:互聯網
上載者:User

iOS --- 通過CPU實現的簡單濾鏡效果

iOS中使用CPU實現濾鏡效果的原理很簡單, 即將圖片轉換成像素資料, 然後對每一個像素進行相應的濾鏡效果計算, 然後重新得到過濾後的圖片.
CPU濾鏡效果代碼如下:

標頭檔
//  CPUImageFilterUtil.h#import #import #import #import //LOMOstatic const float colormatrix_lomo[] = {  1.7f,  0.1f, 0.1f, 0, -73.1f,  0,  1.7f, 0.1f, 0, -73.1f,  0,  0.1f, 1.6f, 0, -73.1f,  0,  0, 0, 1.0f, 0 };//黑白static const float colormatrix_heibai[] = {  0.8f,  1.6f, 0.2f, 0, -163.9f,  0.8f,  1.6f, 0.2f, 0, -163.9f,  0.8f,  1.6f, 0.2f, 0, -163.9f,  0,  0, 0, 1.0f, 0 };//複古static const float colormatrix_huajiu[] = {  0.2f,0.5f, 0.1f, 0, 40.8f,  0.2f, 0.5f, 0.1f, 0, 40.8f,  0.2f,0.5f, 0.1f, 0, 40.8f,  0, 0, 0, 1, 0 };//哥特static const float colormatrix_gete[] = {  1.9f,-0.3f, -0.2f, 0,-87.0f,  -0.2f, 1.7f, -0.1f, 0, -87.0f,  -0.1f,-0.6f, 2.0f, 0, -87.0f,  0, 0, 0, 1.0f, 0 };//銳利化static const float colormatrix_ruise[] = {  4.8f,-1.0f, -0.1f, 0,-388.4f,  -0.5f,4.4f, -0.1f, 0,-388.4f,  -0.5f,-1.0f, 5.2f, 0,-388.4f,  0, 0, 0, 1.0f, 0 };//淡雅static const float colormatrix_danya[] = {  0.6f,0.3f, 0.1f, 0,73.3f,  0.2f,0.7f, 0.1f, 0,73.3f,  0.2f,0.3f, 0.4f, 0,73.3f,  0, 0, 0, 1.0f, 0 };//酒紅static const float colormatrix_jiuhong[] = {  1.2f,0.0f, 0.0f, 0.0f,0.0f,  0.0f,0.9f, 0.0f, 0.0f,0.0f,  0.0f,0.0f, 0.8f, 0.0f,0.0f,  0, 0, 0, 1.0f, 0 };//清寧static const float colormatrix_qingning[] = {  0.9f, 0, 0, 0, 0,  0, 1.1f,0, 0, 0,  0, 0, 0.9f, 0, 0,  0, 0, 0, 1.0f, 0 };//浪漫static const float colormatrix_langman[] = {  0.9f, 0, 0, 0, 63.0f,  0, 0.9f,0, 0, 63.0f,  0, 0, 0.9f, 0, 63.0f,  0, 0, 0, 1.0f, 0 };//光暈static const float colormatrix_guangyun[] = {  0.9f, 0, 0,  0, 64.9f,  0, 0.9f,0,  0, 64.9f,  0, 0, 0.9f,  0, 64.9f,  0, 0, 0, 1.0f, 0 };//藍調static const float colormatrix_landiao[] = {  2.1f, -1.4f, 0.6f, 0.0f, -31.0f,  -0.3f, 2.0f, -0.3f, 0.0f, -31.0f,  -1.1f, -0.2f, 2.6f, 0.0f, -31.0f,  0.0f, 0.0f, 0.0f, 1.0f, 0.0f};//夢幻static const float colormatrix_menghuan[] = {  0.8f, 0.3f, 0.1f, 0.0f, 46.5f,  0.1f, 0.9f, 0.0f, 0.0f, 46.5f,  0.1f, 0.3f, 0.7f, 0.0f, 46.5f,  0.0f, 0.0f, 0.0f, 1.0f, 0.0f};//夜色static const float colormatrix_yese[] = {  1.0f, 0.0f, 0.0f, 0.0f, -66.6f,  0.0f, 1.1f, 0.0f, 0.0f, -66.6f,  0.0f, 0.0f, 1.0f, 0.0f, -66.6f,  0.0f, 0.0f, 0.0f, 1.0f, 0.0f};static const float colormatrixs[][20]={  {    0.8f,  1.6f, 0.2f, 0, -163.9f,    0.8f,  1.6f, 0.2f, 0, -163.9f,    0.8f,  1.6f, 0.2f, 0, -163.9f,    0,  0, 0, 1.0f, 0  },  {    0.2f,0.5f, 0.1f, 0, 40.8f,    0.2f, 0.5f, 0.1f, 0, 40.8f,    0.2f,0.5f, 0.1f, 0, 40.8f,    0, 0, 0, 1, 0  },  {    1.9f,-0.3f, -0.2f, 0,-87.0f,    -0.2f, 1.7f, -0.1f, 0, -87.0f,    -0.1f,-0.6f, 2.0f, 0, -87.0f,    0, 0, 0, 1.0f, 0  },  {    4.8f,-1.0f, -0.1f, 0,-388.4f,    -0.5f,4.4f, -0.1f, 0,-388.4f,    -0.5f,-1.0f, 5.2f, 0,-388.4f,    0, 0, 0, 1.0f, 0  },  {    0.6f,0.3f, 0.1f, 0,73.3f,    0.2f,0.7f, 0.1f, 0,73.3f,    0.2f,0.3f, 0.4f, 0,73.3f,    0, 0, 0, 1.0f, 0  },  {    1.2f,0.0f, 0.0f, 0.0f,0.0f,    0.0f,0.9f, 0.0f, 0.0f,0.0f,    0.0f,0.0f, 0.8f, 0.0f,0.0f,    0, 0, 0, 1.0f, 0  },  {    0.9f, 0, 0, 0, 0,    0, 1.1f,0, 0, 0,    0, 0, 0.9f, 0, 0,    0, 0, 0, 1.0f, 0  },  {    0.9f, 0, 0, 0, 63.0f,    0, 0.9f,0, 0, 63.0f,    0, 0, 0.9f, 0, 63.0f,    0, 0, 0, 1.0f, 0  },  {    0.9f, 0, 0,  0, 64.9f,    0, 0.9f,0,  0, 64.9f,    0, 0, 0.9f,  0, 64.9f,    0, 0, 0, 1.0f, 0  },  {    2.1f, -1.4f, 0.6f, 0.0f, -31.0f,    -0.3f, 2.0f, -0.3f, 0.0f, -31.0f,    -1.1f, -0.2f, 2.6f, 0.0f, -31.0f,    0.0f, 0.0f, 0.0f, 1.0f, 0.0f  },  {    0.8f, 0.3f, 0.1f, 0.0f, 46.5f,    0.1f, 0.9f, 0.0f, 0.0f, 46.5f,    0.1f, 0.3f, 0.7f, 0.0f, 46.5f,    0.0f, 0.0f, 0.0f, 1.0f, 0.0f  },  {    1.0f, 0.0f, 0.0f, 0.0f, -66.6f,    0.0f, 1.1f, 0.0f, 0.0f, -66.6f,    0.0f, 0.0f, 1.0f, 0.0f, -66.6f,    0.0f, 0.0f, 0.0f, 1.0f, 0.0f  }};@interface CPUImageFilterUtil : NSObject+ (UIImage *)imageWithImage:(UIImage *)inImage withColorMatrix:(const float*)f;@end
實現檔案
//  CPUImageFilterUtil.m#import CPUImageFilterUtil.h@implementation CPUImageFilterUtil// 返回一個使用RGBA通道的位元影像上下文static CGContextRef CreateRGBABitmapContext (CGImageRef inImage){  CGContextRef context = NULL;  CGColorSpaceRef colorSpace;  //記憶體空間的指標,該記憶體空間的大小等於映像使用RGB通道所佔用的位元組數。  void *bitmapData;   int bitmapByteCount;  int bitmapBytesPerRow;  //擷取橫向的像素點的個數  size_t pixelsWide = CGImageGetWidth(inImage);  size_t pixelsHigh = CGImageGetHeight(inImage); //縱向  //每一行的像素點佔用的位元組數,每個像素點的ARGB四個通道各佔8個bit(0-255)的空間  bitmapBytesPerRow = (int)(pixelsWide * 4);   //計算整張圖佔用的位元組數  bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh);  //建立依賴於裝置的RGB通道  colorSpace = CGColorSpaceCreateDeviceRGB();  //分配足夠容納圖片位元組數的記憶體空間  bitmapData = malloc(bitmapByteCount);   //建立CoreGraphic的圖形上下文,該上下文描述了bitmaData指向的記憶體空間需要繪製的映像的一些繪製參數    context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);  //Core Foundation中通過含有Create、Alloc的方法名字建立的指標,需要使用CFRelease()函數釋放  CGColorSpaceRelease( colorSpace );  return context;}// 返回一個指標,該指標指向一個數組,數組中的每四個元素都是映像上的一個像素點的RGBA的數值(0-255),用無符號的char是因為它正好的取值範圍就是0-255static unsigned char *RequestImagePixelData(UIImage *inImage){  CGImageRef img = [inImage CGImage];  CGSize size = [inImage size];  //使用上面的函數建立上下文  CGContextRef cgctx = CreateRGBABitmapContext(img);   CGRect rect = {{0,0},{size.width, size.height}};  //將靶心圖表像繪製到指定的上下文,實際為上下文內的bitmapData。  CGContextDrawImage(cgctx, rect, img);   unsigned char *data = CGBitmapContextGetData (cgctx);  //釋放上面的函數建立的上下文  CGContextRelease(cgctx);  return data;}static void changeRGBA(int *red,int *green,int *blue,int *alpha, const float* f)//修改RGB的值{  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[0+5] * redV + f[1+5] * greenV + f[2+5] * blueV + f[3+5] * alphaV + f[4+5];  *blue = f[0+5*2] * redV + f[1+5*2] * greenV + f[2+5*2] * blueV + f[3+5*2] * alphaV + f[4+5*2];  *alpha = f[0+5*3] * redV + f[1+5*3] * greenV + f[2+5*3] * blueV + f[3+5*3] * alphaV + f[4+5*3];  if (*red > 255)  {    *red = 255;  }  if(*red < 0)  {    *red = 0;  }  if (*green > 255)  {    *green = 255;  }  if (*green < 0)  {    *green = 0;  }  if (*blue > 255)  {    *blue = 255;  }  if (*blue < 0)  {    *blue = 0;  }  if (*alpha > 255)  {    *alpha = 255;  }  if (*alpha < 0)  {    *alpha = 0;  }}+ (UIImage*)imageWithImage:(UIImage*)inImage withColorMatrix:(const float*) f{  unsigned char *imgPixel = RequestImagePixelData(inImage);  CGImageRef inImageRef = [inImage CGImage];  GLuint w = (GLuint)CGImageGetWidth(inImageRef);  GLuint h = (GLuint)CGImageGetHeight(inImageRef);  int wOff = 0;  int pixOff = 0;  //雙層迴圈按照長寬的像素個數迭代每個像素點  for(GLuint y = 0;y< h;y++)  {    pixOff = wOff;    for (GLuint x = 0; x
使用方法
UIImage *originImage = [UIImage imageNamed:@testImage];const float *colorMatrix = colormatrix_lomo;UIImage *filteredImage = [CPUImageFilterUtil imageWithImage:originImage withColorMatrix:colorMatrix];

效果如下:

效果1 效果2

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.