閱讀929 返回首頁    go 微軟 go windows


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

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

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

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

+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size
{
    // https://stackoverflow.com/questions/1213790/how-to-get-a-color-image-in-iphone-sdk
    
    //Create a context of the appropriate size
    UIGraphicsBeginImageContext(size);
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    
    //Build a rect of appropriate size at origin 0,0
    CGRect fillRect = CGRectMake(0, 0, size.width, size.height);
    
    //Set the fill color
    CGContextSetFillColorWithColor(currentContext, color.CGColor);
    
    //Fill the color
    CGContextFillRect(currentContext, fillRect);
    
    //Snap the picture and close the context
    UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return colorImage;
}

+ (UIImage *)imageWithGradient:(UIImage *)image startColor:(UIColor *)startColor endColor:(UIColor *)endColor
{
    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, image.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    
    CGContextSetBlendMode(context, kCGBlendModeNormal);
    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
    CGContextDrawImage(context, rect, image.CGImage);
    
    // Create gradient
    NSArray *colors = [NSArray arrayWithObjects:(id)endColor.CGColor, (id)startColor.CGColor, nil];
    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, NULL);
    
    // Apply gradient
    CGContextClipToMask(context, rect, image.CGImage);
    CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, image.size.height), 0);
    UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    CGGradientRelease(gradient);
    CGColorSpaceRelease(space);
    
    return gradientImage;
}

而且在第一篇文章中提到的透明度濾鏡(作用域像素的alpha值上)是沒效果的,可以通過Quartz 2D來實現:

- (UIImage *)setAlpha:(CGFloat)alpha
{
    // https://stackoverflow.com/questions/5084845/how-to-set-the-opacity-alpha-of-a-uiimage 
    
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);
    
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -area.size.height);
    
    CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
    
    CGContextSetAlpha(ctx, alpha);
    
    CGContextDrawImage(ctx, area, self.CGImage);
    
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return newImage;
}

在此基礎上,通過下麵四行代碼,可以分別得到四種不同效果:

return [[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.5];;

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

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

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

  

 

其中,overlay算法如下:

double calcOverlay(float b, float t) 
{
	return (b > 128.0f) ? 255.0f - 2.0f * (255.0f - t) * (255.0f - b) / 255.0f: (b * t * 2.0f) / 255.0f;
}

void filterOverlay(UInt8 *pixelBuf, UInt8 *pixedBlendBuf, 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];
	
	int blendRed = pixedBlendBuf[r];
	int blendGreen = pixedBlendBuf[g];
	int blendBlue = pixedBlendBuf[b];
	
        pixelBuf[r] = SAFECOLOR(calcOverlay(red, blendRed));
	pixelBuf[g] = SAFECOLOR(calcOverlay(green, blendGreen));
	pixelBuf[b] = SAFECOLOR(calcOverlay(blue, blendBlue));
}



最後更新:2017-04-02 16:48:10

  上一篇:go 淘寶開源數據庫OceanBase編譯、安裝和配置手冊
  下一篇:go adb操作命令