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. }  



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

  • 相关阅读:
    Sum Root to Leaf Numbers
    Sum Root to Leaf Numbers
    Sort Colors
    Partition List
    Binary Tree Inorder Traversal
    Binary Tree Postorder Traversal
    Remove Duplicates from Sorted List II
    Remove Duplicates from Sorted List
    Search a 2D Matrix
    leetcode221
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4946680.html
Copyright © 2011-2022 走看看