How to change hue of UIIMAGE having transparent area?

北战南征 提交于 2019-12-14 03:57:22

问题


I am currently using following code for hue change:

  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();

This code is working fine, only issue is it also sets the colour of transparent portions. Can I avoid applying the hue to that transparent area of the UIImage?

Attached following two images for reference:

Thanks in advance?

Output


回答1:


Apply a mask from the image before adding the color.

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();



回答2:


I used Core Image to do what you're trying to achieve. Note: this is in Swift but you should get the gist.

    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)

One note: the inputAngle is done in radians according to this SO post.




回答3:


This code worked for me.

- (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;
}


来源:https://stackoverflow.com/questions/24962645/how-to-change-hue-of-uiimage-having-transparent-area

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!