iOS中的图像处理(一)——基础滤镜

原创 2012年08月16日 19:05:54

最近在稍微做一些整理,翻起这部分的代码,发现是两个多月前的了。

这里讨论的是基于RGBA模型下的图像处理,即将变换作用在每个像素上。

代码是以UIImage的category形式存在的:

typedef struct _singleRGBA
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
    unsigned char alpha;
} RGBA;

@interface UIImage (ImageFilter)


首先,我们需要获得目标图像的位图信息;然后对每个像素进行变换;最后再生成图像。

- (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声明如下:

typedef void (*FilterFunction)(UInt8 *pixelBuf, UInt32 offset, void *context);

在此基础上,我们可以把每个变换操作独立出来,比如调整亮度、对比度、色调、透明度等:

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); // t (- [0, 2]
	
	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); // t (- [0, 10]
	
	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; // avoid divide by zero
	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宏如下:

#define SAFECOLOR(color) MIN(255,MAX(0,color))

最后,拿一张帅气的Andy照片来实践下,希望没有侵犯到肖像权。
原图如下:


通过以下四种变换,可以分别得到四张处理过的图片:

return [originImage changeOpacityByFactor:0.5];

return [originImage changeBrightnessByFactor:1.2];

return [originImage changeSaturationByFactor:2.0];

return [originImage tintWithMaxRGBA:(RGBA){190, 190, 230} minRGBA:(RGBA){50, 35, 10}];

  

 



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

iOS-实现滤镜效果的四种方式

IOS--实现滤镜效果 使用CIFilter,GPUImage,vImage。 IOS8之后,使用UIVisualEffectView。

iOS中线程Call Stack的捕获和解析(一)

这里对上个月做的一个技术项目做部分技术小结,这篇文章描述的功能和我们在使用Xcode进行调试时点击暂停的效果类似。一、获取任意一个线程的Call Stack如果要获取当前线程的调用栈,可以直接使用现有...

iOS中线程Call Stack的捕获和解析(二)

上接iOS中线程Call Stack的捕获和解析(一)。1. 部分参考资料做这一块时也是查阅了很多链接和书籍,包括但不限于: 《OS X ABI Mach-O File Format Referenc...

从NSTimer的失效性谈起(一):关于NSTimer和NSRunLoop

一、NSTimer的失效性在iOS中要设置一个定时器的通常做法是调用如下API:+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)...

iOS中的图像处理(三)——混合运算

有时候,单独对一张图像进行处理是很难或者根本达不到我们想要的效果的。一个好的滤镜效果的诞生,往往要经过很多复杂步骤、细致微调、图片应用效果观察以及很多图层叠加。 我在JSWidget上发现了一些常用...

iOS中的图像处理(二)——卷积运算

关于图像处理中的卷积运算,这里有两份简明扼要的介绍:文一,文二。 其中,可能的一种卷积运算代码如下: - (UIImage*)applyConvolution:(NSArray*)kernel...

使用Xcode GPU Frame Caputre教程

 使用Xcode GPU Frame Caputre教程 http://blog.manbolo.com/2012/11/20/using-xcode-opengl-es-fr...

开源IOS 客户端直播SDK自带美颜功能

当前视频直播非常火爆,手机端的视频直播也非常火爆,PGC、UGC的视频直播门槛都降低了很多。 本文介绍一个:IOS 客户端直播的SDK,代码完全开源。 直播时代:让IOS普通开发者一天内做...

iOS中的图像处理(一)——基础滤镜

最近在稍微做一些整理,翻起这部分的代码,发现是两个多月前的了。 这里讨论的是基于RGBA模型下的图像处理,即将变换作用在每个像素上。 代码是以UIImage的category形式存在的: ...

iOS图像处理(9)使用CoreImage滤镜

转载自:http://www.cnblogs.com/zanglitao/p/4038359.html CoreImage是IOS5中新增框架,通过这个框架我们可以轻松地对图片进行各种特...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)