#include <sys/time.h>ios
#include <math.h>數組
#include <stdio.h>ide
#include <string.h>函數
// 1返回一個使用RGBA通道的位圖上下文 ui
static CGContextRef CreateRGBABitmapContext (CGImageRef inImage) spa
{指針
CGContextRef context = NULL; orm
CGColorSpaceRef colorSpace; 索引
void *bitmapData; //內存空間的指針,該內存空間的大小等於圖像使用RGB通道所佔用的字節數。圖片
int bitmapByteCount;
int bitmapBytesPerRow;
size_t pixelsWide = CGImageGetWidth(inImage); //獲取橫向的像素點的個數
size_t pixelsHigh = CGImageGetHeight(inImage);
bitmapBytesPerRow = (pixelsWide * 4); //每一行的像素點佔用的字節數,每一個像素點的ARGB四個通道各佔8個bit(0-255)的空間
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); //計算整張圖佔用的字節數
colorSpace = CGColorSpaceCreateDeviceRGB();//建立依賴於設備的RGB通道
//分配足夠容納圖片字節數的內存空間
bitmapData = malloc( bitmapByteCount );
//建立CoreGraphic的圖形上下文,該上下文描述了bitmaData指向的內存空間須要繪製的圖像的一些繪製參數
context = CGBitmapContextCreate (bitmapData,
pixelsWide,
pixelsHigh,
8,
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast);
//Core Foundation中經過含有Create、Alloc的方法名字建立的指針,須要使用CFRelease()函數釋放
CGColorSpaceRelease( colorSpace );
return context;
}
// 2返回一個指針,該指針指向一個數組,數組中的每四個元素都是圖像上的一個像素點的RGBA的數值(0-255),用無符號的char是由於它正好的取值範圍就是0-255
static 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;
}
//3修改RGB的值
static void changeRGBA(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[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;
}
}
#pragma mark -
@implementation ImageUtil
#pragma mark -
+ (UIImage*)processImage:(UIImage*)inImage withColorMatrix:(const float*) f
{
unsigned char *imgPixel = RequestImagePixelData(inImage);
CGImageRef inImageRef = [inImage CGImage];
GLuint w = CGImageGetWidth(inImageRef);
GLuint h = CGImageGetHeight(inImageRef);
int wOff = 0;
int pixOff = 0;
//雙層循環按照長寬的像素個數迭代每一個像素點
for(GLuint y = 0;y< h;y++)
{
pixOff = wOff;
for (GLuint x = 0; x<w; x++)
{
int red = (unsigned char)imgPixel[pixOff];
int green = (unsigned char)imgPixel[pixOff+1];
int blue = (unsigned char)imgPixel[pixOff+2];
int alpha=(unsigned char)imgPixel[pixOff+3];
changeRGBA(&red, &green, &blue, &alpha, f);
//回寫數據
imgPixel[pixOff] = red;
imgPixel[pixOff+1] = green;
imgPixel[pixOff+2] = blue;
imgPixel[pixOff+3] = alpha;
//將數組的索引指向下四個元素
pixOff += 4;
}
wOff += w * 4;
}
NSInteger dataLength = w*h* 4;
//下面的代碼建立要輸出的圖像的相關參數
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);
// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * w;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
//建立要輸出的圖像
CGImageRef imageRef = CGImageCreate(w, h,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
provider,
NULL, NO, renderingIntent);
UIImage *my_Image = [UIImage imageWithCGImage:imageRef];
CFRelease(imageRef);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
return my_Image;
}
//-----------顏色處理-----
#ifndef ImageProcessing_ColorMatrix_h
#define ImageProcessing_ColorMatrix_h
//ColorMatrix From Android
//lomo
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 };
//黑白
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 };
//舊化
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 };
//哥特
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 };
//銳色
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 };
//淡雅
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 };
//酒紅
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 };
//清寧
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 };
//浪漫
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 };
//光暈
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 };
//藍調
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
};
//夢幻
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
};
//夜色
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
};
#endif
#ifndef ImageProcessing_ColorMatrix_h
#define ImageProcessing_ColorMatrix_h
//ColorMatrix From Android
//lomo
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 };
//黑白
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 };
//舊化
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 };
//哥特
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 };
//銳色
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 };
//淡雅
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 };
//酒紅
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 };
//清寧
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 };
//浪漫
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 };
//光暈
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 };
//藍調
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
};
//夢幻
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
};
//夜色
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
};
#endif
#ifndef ImageProcessing_ColorMatrix_h
#define ImageProcessing_ColorMatrix_h
//ColorMatrix From Android
//lomo
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 };
//黑白
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 };
//舊化
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 };
//哥特
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 };
//銳色
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 };
//淡雅
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 };
//酒紅
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 };
//清寧
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 };
//浪漫
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 };
//光暈
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 };
//藍調
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
};
//夢幻
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
};
//夜色
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
};
#endif
----調用-----
outImage = [ImageUtil processImage:_tempImage withColorMatrix:colormatrix_landiao];