Search code examples
iosobjective-cuiimagehue

How to change hue of UIIMAGE having transparent area?


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:

enter image description here enter image description here

Thanks in advance?

Output enter image description here


Solution

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