如何改变具有透明区域的UIIMAGE的色调?

时间:2014-07-25 18:53:16

标签: ios objective-c uiimage hue

我目前正在使用以下代码进行色调更改:

  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的透明区域吗?

附上以下两张图片供参考:

enter image description here enter image description here

提前致谢?

输出 enter image description here

3 个答案:

答案 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;
}