【问题标题】:How to change hue of UIIMAGE having transparent area?如何改变具有透明区域的 UIIMAGE 的色调?
【发布时间】:2014-07-25 18:53:16
【问题描述】:

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

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

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

提前致谢?

输出

【问题讨论】:

    标签: ios objective-c uiimage hue


    【解决方案1】:

    在添加颜色之前应用图像中的蒙版。

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

    【讨论】:

    • @maddy 感谢您的帮助,实际上我想让它成为通用代码,而不是任何特定图像。例如你有衬衫、帽子等透明图像,我只想改变不透明部分的色调。我附上了两张图片。
    • 这就是我的回答应该做的。
    • 嘿@rmaddy,谢谢它的工作,但我正在尝试解决这个问题 180 旋转蒙版图像,使用 CGContextRotateCTM 但它没有改变色调。你能帮忙吗?
    • 旋转将围绕在角落的原点发生,而不是中心。因此,除了旋转之外,您还需要翻译。
    • 我认为它只能通过 CIFilter 实现,但这不会根据所选颜色而改变。它仅根据浮动中的 deltaHueRadians 变化。但我想通过选定的颜色来改变它。有什么建议可以解决吗?
    【解决方案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)
    

    注意:根据this SO post,inputAngle 以弧度表示。

    【讨论】:

      【解决方案3】:

      这段代码对我有用。

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

      【讨论】:

      • @dangerZone 谢谢,我做到了。
      猜你喜欢
      • 2012-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      相关资源
      最近更新 更多