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

时间:2023-12-11 18:44:20

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

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

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

  1. + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size
  2. {
  3. // http://*.com/questions/1213790/how-to-get-a-color-image-in-iphone-sdk
  4. //Create a context of the appropriate size
  5. UIGraphicsBeginImageContext(size);
  6. CGContextRef currentContext = UIGraphicsGetCurrentContext();
  7. //Build a rect of appropriate size at origin 0,0
  8. CGRect fillRect = CGRectMake(0, 0, size.width, size.height);
  9. //Set the fill color
  10. CGContextSetFillColorWithColor(currentContext, color.CGColor);
  11. //Fill the color
  12. CGContextFillRect(currentContext, fillRect);
  13. //Snap the picture and close the context
  14. UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
  15. UIGraphicsEndImageContext();
  16. return colorImage;
  17. }
  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. CGContextSetBlendMode(context, kCGBlendModeNormal);
  8. CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
  9. CGContextDrawImage(context, rect, image.CGImage);
  10. // Create gradient
  11. NSArray *colors = [NSArray arrayWithObjects:(id)endColor.CGColor, (id)startColor.CGColor, nil];
  12. CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
  13. CGGradientRef gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, NULL);
  14. // Apply gradient
  15. CGContextClipToMask(context, rect, image.CGImage);
  16. CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, image.size.height), 0);
  17. UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();
  18. UIGraphicsEndImageContext();
  19. CGGradientRelease(gradient);
  20. CGColorSpaceRelease(space);
  21. return gradientImage;
  22. }

而且在第一篇文章中提到的透明度滤镜(作用域像素的alpha值上)是没效果的,可以通过Quartz 2D来实现:

  1. - (UIImage *)setAlpha:(CGFloat)alpha
  2. {
  3. // http://*.com/questions/5084845/how-to-set-the-opacity-alpha-of-a-uiimage
  4. UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
  5. CGContextRef ctx = UIGraphicsGetCurrentContext();
  6. CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);
  7. CGContextScaleCTM(ctx, 1, -1);
  8. CGContextTranslateCTM(ctx, 0, -area.size.height);
  9. CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
  10. CGContextSetAlpha(ctx, alpha);
  11. CGContextDrawImage(ctx, area, self.CGImage);
  12. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  13. UIGraphicsEndImageContext();
  14. return newImage;
  15. }

在此基础上,通过下面四行代码,可以分别得到四种不同效果:

  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]];

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

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

其中,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. void filterOverlay(UInt8 *pixelBuf, UInt8 *pixedBlendBuf, UInt32 offset, void *context)
  6. {
  7. int r = offset;
  8. int g = offset+1;
  9. int b = offset+2;
  10. int red = pixelBuf[r];
  11. int green = pixelBuf[g];
  12. int blue = pixelBuf[b];
  13. int blendRed = pixedBlendBuf[r];
  14. int blendGreen = pixedBlendBuf[g];
  15. int blendBlue = pixedBlendBuf[b];
  16. pixelBuf[r] = SAFECOLOR(calcOverlay(red, blendRed));
  17. pixelBuf[g] = SAFECOLOR(calcOverlay(green, blendGreen));
  18. pixelBuf[b] = SAFECOLOR(calcOverlay(blue, blendBlue));
  19. }

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