iOS中的影像處理(三)——混合運算

來源:互聯網
上載者:User

標籤:

有時候,單獨對一張映像進行處理是很難或者根本達不到我們想要的效果的。一個好的濾鏡效果的誕生,往往要經過很多複雜步驟、細緻微調、圖片應用效果觀察以及很多圖層疊加。

我在JSWidget上發現了一些常用混合演算法,對應著一些常用混合模式,通過這些blend modes,我們可以指定兩張映像如何混合。

不過在此之前,我們需要純顏色映像和漸層映像來做輔助:

[cpp] view plaincopy
  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. }  

[cpp] view plaincopy
  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來實現: [cpp] view plaincopy
  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. }  

在此基礎上,通過下面四行代碼,可以分別得到四種不同效果: [cpp] view plaincopy
  1. return [[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.5];;  

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

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

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

  

 

其中,overlay演算法如下:

[cpp] view plaincopy
  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. }  



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

iOS中的影像處理(三)——混合運算

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.