我目前正在使用以下代码进行色调更改:
CGSize imageSize = [imageView.image size];
CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height);
// Create a context containing the image.
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
[imageView.image drawAtPoint:CGPointMake(0, 0)];
// Draw the hue on top of the image.
CGContextSetBlendMode(context, kCGBlendModeHue);
[color set];
UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent];
[imagePath fill];
// Retrieve the new image.
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
imageView.image= result;
UIGraphicsEndImageContext();
这段代码工作正常,唯一的问题是它还设置了透明部分的颜色。我可以避免将色调应用到UIImage的透明区域吗?
附上以下两张图片供参考:
提前致谢?
输出
答案 0 :(得分:4)
在添加颜色之前从图像中应用蒙版。
CGSize imageSize = [imageView.image size];
CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height);
// Create a context containing the image.
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
[imageView.image drawAtPoint:CGPointMake(0, 0)];
// Setup a clip region using the image
CGContextSaveGState(context);
CGContextClipToMask(context, imageExtent, imageView.image.CGImage);
[color set];
CGContextFillRect(context, imageExtent);
// Draw the hue on top of the image.
CGContextSetBlendMode(context, kCGBlendModeHue);
[color set];
UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent];
[imagePath fill];
CGContextRestoreGState(context); // remove clip region
// Retrieve the new image.
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
imageView.image= result;
UIGraphicsEndImageContext();
答案 1 :(得分:2)
我使用Core Image来做你想要实现的目标。注意:这是在Swift中,但你应该得到要点。
var hueFilter = CIFilter(name: "CIHueAdjust", withInputParameters: ["inputAngle" : M_2_PI])
let imageRef = UIImage(named: "Maggie").CGImage
let coreImage = CIImage(CGImage: imageRef)
hueFilter.setValue(coreImage, forKey: kCIInputImageKey)
maggieView.image = UIImage(CIImage: hueFilter.outputImage)
一个注意事项:inputAngle根据this SO post以弧度完成。
答案 2 :(得分:1)
这段代码对我有用。
- (UIImage*)imageWithImage:(UIImageView*)source colorValue:(CGFloat)hue {
CGSize imageSize = [source.image size];
CGRect imageExtent = CGRectMake(0,0,imageSize.width,imageSize.height);
// Create a context containing the image.
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
[source.image drawAtPoint:CGPointMake(0, 0)];
// Setup a clip region using the image
CGContextSaveGState(context);
CGContextClipToMask(context, source.bounds, source.image.CGImage);
self.imageColor = [UIColor colorWithHue:hue saturation:1.0 brightness:1 alpha:1.0];
[self.imageColor set];
CGContextFillRect(context, source.bounds);
// Draw the hue on top of the image.
CGContextSetBlendMode(context, kCGBlendModeHue);
[self.imageColor set];
UIBezierPath *imagePath = [UIBezierPath bezierPathWithRect:imageExtent];
[imagePath fill];
CGContextRestoreGState(context); // remove clip region
// Retrieve the new image.
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}