zoukankan      html  css  js  c++  java
  • iOS中的图像处理(三)——混合运算

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

    我在JSWidget上发现了一些常用混合算法,对应着一些常用混合模式,通过这些blend modes,我们可以指定两张图像如何混合。

    不过在此之前,我们需要纯颜色图像和渐变图像来做辅助:

    1. + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size  
    2. {  
    3.     // http://stackoverflow.com/questions/1213790/how-to-get-a-color-image-in-iphone-sdk  
    4.       
    5.     //Create a context of the appropriate size  
    6.     UIGraphicsBeginImageContext(size);  
    7.     CGContextRef currentContext = UIGraphicsGetCurrentContext();  
    8.       
    9.     //Build a rect of appropriate size at origin 0,0  
    10.     CGRect fillRect = CGRectMake(0, 0, size.width, size.height);  
    11.       
    12.     //Set the fill color  
    13.     CGContextSetFillColorWithColor(currentContext, color.CGColor);  
    14.       
    15.     //Fill the color  
    16.     CGContextFillRect(currentContext, fillRect);  
    17.       
    18.     //Snap the picture and close the context  
    19.     UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();  
    20.     UIGraphicsEndImageContext();  
    21.       
    22.     return colorImage;  
    23. }  

    1. + (UIImage *)imageWithGradient:(UIImage *)image startColor:(UIColor *)startColor endColor:(UIColor *)endColor  
    2. {  
    3.     UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);  
    4.     CGContextRef context = UIGraphicsGetCurrentContext();  
    5.     CGContextTranslateCTM(context, 0, image.size.height);  
    6.     CGContextScaleCTM(context, 1.0, -1.0);  
    7.       
    8.     CGContextSetBlendMode(context, kCGBlendModeNormal);  
    9.     CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);  
    10.     CGContextDrawImage(context, rect, image.CGImage);  
    11.       
    12.     // Create gradient  
    13.     NSArray *colors = [NSArray arrayWithObjects:(id)endColor.CGColor, (id)startColor.CGColor, nil];  
    14.     CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();  
    15.     CGGradientRef gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, NULL);  
    16.       
    17.     // Apply gradient  
    18.     CGContextClipToMask(context, rect, image.CGImage);  
    19.     CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, image.size.height), 0);  
    20.     UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();  
    21.     UIGraphicsEndImageContext();  
    22.       
    23.     CGGradientRelease(gradient);  
    24.     CGColorSpaceRelease(space);  
    25.       
    26.     return gradientImage;  
    27. }  

    而且在第一篇文章中提到的透明度滤镜(作用域像素的alpha值上)是没效果的,可以通过Quartz 2D来实现:
    1. - (UIImage *)setAlpha:(CGFloat)alpha  
    2. {  
    3.     // http://stackoverflow.com/questions/5084845/how-to-set-the-opacity-alpha-of-a-uiimage   
    4.       
    5.     UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);  
    6.       
    7.     CGContextRef ctx = UIGraphicsGetCurrentContext();  
    8.     CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);  
    9.       
    10.     CGContextScaleCTM(ctx, 1, -1);  
    11.     CGContextTranslateCTM(ctx, 0, -area.size.height);  
    12.       
    13.     CGContextSetBlendMode(ctx, kCGBlendModeMultiply);  
    14.       
    15.     CGContextSetAlpha(ctx, alpha);  
    16.       
    17.     CGContextDrawImage(ctx, area, self.CGImage);  
    18.       
    19.     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();  
    20.       
    21.     UIGraphicsEndImageContext();  
    22.       
    23.     return newImage;  
    24. }  

    在此基础上,通过下面四行代码,可以分别得到四种不同效果:
    1. return [[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.5];;  

    1. return [UIImage imageWithGradient:originImage startColor:[UIColor whiteColor] endColor:[UIColor yellowColor]];  

    1. return [[originImage tintWithMaxRGBA:(RGBA){190, 190, 230} minRGBA:(RGBA){50, 35, 10}] overlayWithImage:[[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.3]];  

    1. return [originImage softlightWithImage:[[UIImage imageWithColor:[UIColor yellowColor] size:originImage.size] changeOpacityByFactor:0.8]];  

      

     

    其中,overlay算法如下:

    1. double calcOverlay(float b, float t)   
    2. {  
    3.     return (b > 128.0f) ? 255.0f - 2.0f * (255.0f - t) * (255.0f - b) / 255.0f: (b * t * 2.0f) / 255.0f;  
    4. }  
    5.   
    6. void filterOverlay(UInt8 *pixelBuf, UInt8 *pixedBlendBuf, UInt32 offset, void *context)  
    7. {  
    8.     int r = offset;  
    9.     int g = offset+1;  
    10.     int b = offset+2;  
    11.       
    12.     int red = pixelBuf[r];  
    13.     int green = pixelBuf[g];  
    14.     int blue = pixelBuf[b];  
    15.       
    16.     int blendRed = pixedBlendBuf[r];  
    17.     int blendGreen = pixedBlendBuf[g];  
    18.     int blendBlue = pixedBlendBuf[b];  
    19.       
    20.         pixelBuf[r] = SAFECOLOR(calcOverlay(red, blendRed));  
    21.     pixelBuf[g] = SAFECOLOR(calcOverlay(green, blendGreen));  
    22.     pixelBuf[b] = SAFECOLOR(calcOverlay(blue, blendBlue));  
    23. }  



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

  • 相关阅读:
    软工第1次阅读作业
    软工第0次作业
    第四次博客
    第三次博客
    第二次
    第一次博客
    提问回顾与个人总结
    软件工程结对作业
    软件工程第一次阅读作业
    软件工程第0次个人作业
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4946680.html
Copyright © 2011-2022 走看看