【问题标题】:Higlight Artifacts When Using Hard Light Blend Mode使用强光混合模式时突出显示伪影
【发布时间】:2011-09-24 13:44:55
【问题描述】:

我正在我的 iPhone 应用程序中混合两个图像,使用顶部图像的 HardLight 混合模式。它看起来像这样:

UIGraphicsBeginImageContext(size);
[sourceImage drawInRect:rectangle blendMode:kCGBlendModeNormal alpha:1.0];
[effectOverlay drawInRect:rectangle blendMode:kCGBlendModeHardLight alpha:0.75];
mainImage.image =  UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

它工作正常。然而,图像中的高光溢出出现了奇怪的颜色伪影。请注意这张照片右下角的紫色工件:

http://dl.dropbox.com/u/626891/artifact.jpg http://dl.dropbox.com/u/626891/artifact.jpg

这仅在使用强光时发生;其他混合模式都很好。有谁知道该怎么办?

【问题讨论】:

  • 没人知道发生了什么?
  • 我在这里遇到了完全相同的问题。强光混合会产生奇怪的伪影。一个简单的两层混合强光在 Photoshop 中看起来很好。但是,我在 iOS 中得到了奇怪的伪影,具体取决于我混合的颜色。
  • 同样的问题!使用 alpha 不等于 1.0 的 kCGBlendModeHardLight 时。与 GIMP 2.8 相比,结果不同!

标签: objective-c ios cocoa-touch image-processing core-graphics


【解决方案1】:

我能够确认这很可能是色彩空间问题。我使用一个名为 Opacity 的应用程序来直观地创建形状、混合效果、阴影等,并将结果导出到 Core Graphics 代码。我碰巧使用了强光混合模式,但在不透明度中一切似乎都很好。然而,当我在 iOS 上导出并运行代码时,我得到了相同的工件。

这并不完全是一个解决方案,但在我的情况下,我只是用纯色进行遮罩和填充,并与上面的图像混合(硬光)。 我注意到这些伪影只发生在亮度为 100% 的填充颜色中。将亮度设置为 99% 解决了我的特定问题。但是,对于混合图像和其他内容,我认为您将不得不使用色彩空间。

不过我可能是错的。我当然不是色彩专家。

【讨论】:

    【解决方案2】:

    我在使用 kCGBlendModeColor 时得到了类似的伪像。我认为这不是色彩空间问题。在计算像素值时,iOS 似乎没有钳制在 255。绝对是操作系统中的错误。很遗憾,因为这就像图像处理 101。

    【讨论】:

    • 这绝对是问题所在。非常非常简单的错误。
    【解决方案3】:

    找到解决方案/解决方法...

    只需浏览您的图像并将任何 255,255,255 的像素更改为 254,254,254,您就不会看到伪影。

    刚刚为我工作。

    明确地说,在我的例子中,我有一个上下文,其中包含要着色的图像和一个 CGImage,其中包含我想要使用带有 kCGBlendModeColor 的 CGDrawImage 着色的颜色。我只是从上下文中制作一个临时图像,遍历每个像素以寻找 255、255、255 并将这些像素更改为 254、254、254。然后我将该图像放回上下文中并使用 kCGBlendModeColor 绘制色调图像,然后一切都好。

    希望对您有所帮助。

    【讨论】:

      【解决方案4】:

      这个问题很烦人。有人向 Apple 提交了错误报告吗?

      尽管如此,这是另一种解决方法,它似乎比我在此处看到的临时方法(对我不起作用)更适合更可靠地解决问题。知道混合模式 HardLight 与 Overlay 相同,只是切换了两个参数,这很有用。问题是 iOS 的 Overlay 实现不是有问题的。因此,您需要在您的绘图中移动(并且可能使用UIGraphicsGetImageFromCurrentImageContext 等进行中间快照),以便您以切换的顺序绘制您的两个图像。这样您就可以使用 Overlay 而不是 HardLight。

      因此,对于您的示例,将代码更改为:

          UIGraphicsBeginImageContext(size);
          [effectOverlay drawInRect:rectangle blendMode:kCGBlendModeNormal alpha:0.75];
          [sourceImage drawInRect:rectangle blendMode:kCGBlendModeOverlay alpha:1.0];
          mainImage.image =  UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
      

      希望这会有所帮助。

      【讨论】:

      • 完美解决方案!显然,这比遍历每个像素寻找 255、255、255 并将这些像素更改为 254、254、254(link)要好得多。
      • 这真的只发生在 (255,255,255),例如纯白色吗?我很确定我看到的是纯黄色 (255,255,0) 和纯绿色 (0,255,0) 的垃圾伪影。无论如何,我将我的代码切换为使用 kCGBlendModeOverlay 而不是 kCGBlendModeHardLight,它不仅现在可以正常工作,而且工作速度也更快,因为我可以在我的照明图像上应用着色,而不是在所需的顶部应用照明图像着色,在我的例子中是少了一个巨大的位图操作操作。
      【解决方案5】:

      我在使用 kCGBlendModeNormal 时遇到了同样的问题。我有一种方法是用特定的 alpha 和特定的混合模式覆盖两个图像:

      - (UIImage *)overlayImage:(UIImage *)image withBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha 
      {
      CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
      UIGraphicsBeginImageContext(self.size);
      CGContextSetInterpolationQuality(UIGraphicsGetCurrentContext(), kCGInterpolationHigh);
      [self drawInRect:rect blendMode:kCGBlendModeNormal alpha:0.99];
      [image drawInRect:rect blendMode:blendMode alpha:alpha * 0.99];
      UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      
      return result; 
      }
      

      对 alpha 使用 0.99 的最大值可确保我不会有任何像素为 255、255、255。我希望这会有所帮助

      【讨论】:

        猜你喜欢
        • 2020-04-28
        • 2014-12-28
        • 1970-01-01
        • 2016-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-05
        相关资源
        最近更新 更多