PDF 图像软掩模伪影

标签 pdf artifacts

我正在使用 C++ 开发 PDF 生成器。

在处理过程中,我遇到了图像软掩模的一个大问题。

enter image description here

我将图像放在 PDF 页面的右侧,如上所示。粉红熊是位图图像并具有 Alpha channel 。但是,它还没有 PDF 蒙版。

在我成功地以正确的方式放置图像之后。我需要找到一种方法来删除图像的黑色背景。 (又名 Alpha 处理)

我发现有几个选项可以将其存档,如下所示。

  • 单色蒙版。
  • 模板掩模。
  • 软 mask 。

我的应用程序有渐变图像。因此,软面膜法对我来说是最好的。因此,我按照如下方式实现了它。

enter image description here

图像的黑色背景消失了。看来一切都很好。

但是,当我放大结果时,我意识到存在一些伪影。

enter image description here

左侧是带有 Alpha 的正确图像,右侧是 PDF 结果。

熊的轮廓周围有黑色噪音。(单击图像可显示大图)当我放置矩形图像时,我可以在边缘发现黑色线条。

RGB channel 和A channel 似乎不完全匹配。(好像A channel 大了1~2 px)

我的实现如下。

  1. 我制作了一个 XObject (SMask)
8 0 obj
<<
/Type /XObject
/Subtype /Image
/Width 693
/Height 972
/BitsPerComponent 8
/Filter /FlateDecode
/ColorSpace /DeviceGray
/Length 137856
>>
stream
  • 将 XObject 链接到原始图像。
  • 7 0 obj
    <<
    /Type /XObject
    /Subtype /Image
    /Width 693
    /Height 972
    /BitsPerComponent 8
    /Filter /FlateDecode
    /ColorSpace /DeviceRGB
    /SMask 8 0 R
    /Length 261436
    >>
    stream
    

    这就是我所做的一切。我还需要做更多的事情吗?

    我花了一周时间来修复它。但是,即使我在谷歌上搜索,我仍然没有任何想法。

    我附上结果文件。

    https://www.dropbox.com/s/09ggj28bhzi8f6e/Output.pdf?dl=0

    请有人给我一些建议。


    **** 更新 ****

    我制作了更简单的版本进行测试。

    enter image description here

    我制作了一个位图。我在图像左侧画了一个白色矩形,如上所示。右侧是空的。

    enter image description here

    将位图放入 PDF 并通过其 alpha 值应用软掩模后, 白色矩形的边缘有一条黑线。 (左侧绘制白色矩形。右侧是透明的。)

    位图的 Alpha channel 与上图完全相同。我已经在 Photoshop 上检查过了。 Alpha channel 中没有任何灰色,并且每个像素与RGB channel 完全匹配。

    enter image description here

    我附上了 PDF 结果。

    Before soft masking

    After soft masking

    最佳答案

    这个问题看起来很老,但仍然以防万一有人偶然发现它,我有一个类似的问题,透明图像边缘周围出现细灰线,并发现问题是由于“图像平滑”通过 PDF 查看器。为了进行确认,您可以在 Adob​​e Acrobat Reader 中打开文档并从首选项中关闭图像平滑功能,线条将会消失 - 但由于它依赖于查看器,因此不能依赖此解决方案。

    在多次检查 pdf 规范以确保 Alpha 被正确分割并进行大量在线搜索后,我认为问题在于透明像素实际上是“透明黑色” 或 rgba(0,0,0,0),因此观看者自然会尝试混合边缘上的颜色,从而创建一条灰线。我使用的是从浏览器生成的图像,浏览器将 alpha=0 的任何像素视为“透明黑色”。这些 GitHub 问题中给出了更多详细信息:#issue1 #issue2但提到的解决方案,将像素转换为“透明白色”rgba(255,255,255,0),如果背景和图像更改为黑色,则会导致相同的问题。

    我对图像平滑/抗锯齿算法了解不多,但我将每个完全透明像素的 RGB 颜色更改为周围像素的平均值,并且伪像消失了!(保持 alpha 为 0) 运行几次平均函数会得到更平滑的结果,并且由于它们是透明像素,只要没有正在生产硬边。

    这只是一次测试运行,可能有更好、更快的图像平滑选项。 imgData 是您的 RGB 像素流,alphaChannel 是软掩模

    let iterations = 10;
      
      while (iterations > 0) {
        let p = 0,
            a = 0;
        
        for (a = 0; a < pixelCount; a++) {
          if (alphaChannel[a] !== 0) {
            p += colorCount;
            continue;
          }
          const colorSum = {r: 0, g: 0, b: 0};
    
          let count = 0;
          for (i = -2; i < 3; i++) {
            for (let j = -2; j < 3; j++) {
              const index = (a + i + j * this.width) * colorCount;
              if (index < 0 || index >= this.width * this.height * colorCount) {
                continue
              }
              colorSum.r += imgData[index];
              colorSum.g += imgData[index + 1];
              colorSum.b += imgData[index + 2];
              count++;
            }
          }
          imgData[p++] = colorSum.r / count;
          imgData[p++] = colorSum.g / count;
          imgData[p++] = colorSum.b / count;
    
        }
        iterations--;
      }
    

    关于PDF 图像软掩模伪影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62558338/

    相关文章:

    hudson - Jenkins 可以将工件存储在作业目录之外吗?

    artifacts - 您生产哪些重要的设计作品?

    configuration - 将 TeamCity 工件复制到目标路径的根目录的正确通配符语法是什么?

    pdf - 使用 PostScript 创建 PDF 超链接

    iphone - int retVal = UIApplicationMain(argc, argv, nil, nil);尝试在 webView 中加载 pdf 时 EXC_BAD_ACCESS

    Python 将请求 header 传递给 pdfkit

    java - Bamboo 制品部分遗失

    python - 造成这种复杂信号伪影的原因是什么?

    java - 从 Restful Web 服务下载 pdf

    java - 将 JSP 页面下载为 PDF