问题
I'm blending two images in my iPhone app, using the HardLight blend mode of the top image. It looks something like this:
UIGraphicsBeginImageContext(size);
[sourceImage drawInRect:rectangle blendMode:kCGBlendModeNormal alpha:1.0];
[effectOverlay drawInRect:rectangle blendMode:kCGBlendModeHardLight alpha:0.75];
mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
It works fine. However, the blown-out highlights in the image appear with a weird color artifact. Note the purple artifact in the bottom-right corner of this photo:
http://dl.dropbox.com/u/626891/artifact.jpg http://dl.dropbox.com/u/626891/artifact.jpg
This only occurs using Hard Light; other blend modes are fine. Anyone know what to do about this?
回答1:
This issue is quite annoying. Did somebody file a bug report to Apple?
Nevertheless, here is another workaround which seems better suited to solve the problem more reliably than the adhoc approaches I see here (which did not work for me). It is useful to know that the blend mode HardLight is the same as Overlay, only with the two arguments switched. And the things is that the iOS implementation of Overlay is not buggy. So you need to move around your drawing (and maybe take an intermediate snap shot with UIGraphicsGetImageFromCurrentImageContext
or the like) such that you draw your two images in a switched order. This way you can use Overlay instead of HardLight.
So, for your example change the code to:
UIGraphicsBeginImageContext(size);
[effectOverlay drawInRect:rectangle blendMode:kCGBlendModeNormal alpha:0.75];
[sourceImage drawInRect:rectangle blendMode:kCGBlendModeOverlay alpha:1.0];
mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Hope this helps.
回答2:
I'm getting similar artifacts with kCGBlendModeColor. I don't think it's a colorspace issue. It looks like iOS is not clamping at 255 when computing the pixel value. Definitely a bug in the OS. Sad, because that's like Image Processing 101.
回答3:
I was able to confirm that this is likely a color space issue. I use an app called Opacity to visually create shapes, blending effects, shadows, etc., and export the results to Core Graphics code. I happened to be using the Hard Light blend mode, but everything seemed just fine in Opacity. When I exported and ran the code on iOS, however, I was getting the same artifacts.
This isn't a solution exactly, but in my case, I was simply masking and filling with a solid color, blending with an image above it (Hard Light). I noticed that these artifacts only occurred with fill colors whose brightness was 100%. Setting the brightness down to 99% solved my particular issue. For blending images and stuff, however, I think you're going to have to play around with color spaces.
I could be wrong though. I'm certainly no color expert.
回答4:
Found a solution/workaround...
Just go through your image and change any pixel that's 255,255,255 to 254,254,254 and you won't see the artifacts.
Just worked for me.
To be clear, in my case, I have a context that has the image to be tinted and a CGImage that contains the color that I want to tint with using a CGDrawImage with kCGBlendModeColor. I simply make a temporary image from the context, go through each pixel looking for 255, 255, 255 and change those pixels to 254, 254, 254. Then I put that image back in a context and draw the tint image with kCGBlendModeColor, and it's all good.
Hope that helps.
回答5:
I had the same problem with kCGBlendModeNormal. I had a method that was overlaying two images with a certain alpha and a certain blend mode:
- (UIImage *)overlayImage:(UIImage *)image withBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha
{
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
UIGraphicsBeginImageContext(self.size);
CGContextSetInterpolationQuality(UIGraphicsGetCurrentContext(), kCGInterpolationHigh);
[self drawInRect:rect blendMode:kCGBlendModeNormal alpha:0.99];
[image drawInRect:rect blendMode:blendMode alpha:alpha * 0.99];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
Using a .99 max value for alpha ensures that I will not have any pixel with 255, 255, 255. I hope this helps
来源:https://stackoverflow.com/questions/6511272/higlight-artifacts-when-using-hard-light-blend-mode