【问题标题】:Mix two .png images with alpha border with CSS使用 CSS 混合两个带有 alpha 边框的 .png 图像
【发布时间】:2018-02-24 15:59:24
【问题描述】:

有没有一种方法可以混合两个 PNG 图像以在它们都有带 alpha 的边框时完美匹配?

这是我遇到的问题的一个示例:

img {
  position: absolute;
  left: 0px;
  top: 0px;
}

.container {
  height: 512px;
  width: 512px;
}
<div class="container">
  <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
  <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" alt="Cube">
</div>

或CodePen的链接

情况是我有两个保存为 PNG 的 3D 渲染,并且都具有透明度为 50% 的 alpha 边框,如果您在 Photoshop 和/或 After Effects 中将它们合并,则可以完美匹配。

但是当在 HTML/CSS 中创建相同的情况时,我们在元素之间有一条白线。 在阅读了一些关于 mix-blending-mode 和 background-blending-mode 并用它们进行一些测试之后,它似乎没有帮助。我们认为这两个图像(它们的 Alpha 通道)都与背景预乘,这就是为什么它们之间会出现半透明线(边界所在的位置)。

有没有办法通过 CSS 甚至 JavaScript/jQuery 来实现这一点?

编辑:所以我们不会在图像移动和 css 技巧上讨论更多的 cmets。删除 1px 或隐藏它不是一个选项,因为大图片的外观不会相同。

【问题讨论】:

  • “如果你在 Photoshop 中合并它们会完美匹配” 嗯不i.stack.imgur.com/X9D3Q.png
  • @Kaiido 如果您在 AF 中使用 Alpha Add Mode,他们会这样做。我不确定 prntscr 是否将 png 保存为索引,如果它在 Photoshop 中保存,则必须将图像转换为 sRGB,因为 Photoshop 不能很好地处理索引图像

标签: javascript html css alpha compositing


【解决方案1】:

这不是与背景预乘的问题——而是沿着边界,您在同一位置有来自两个图像的部分透明像素,这让背景渗出。 50% 透明度加上 50% 透明度不等于 100% 不透明。

我认为您需要自己调整图像蒙版,而不是摆弄阴影或像素调整来修补问题。 (我不相信会有 CSS 或 JS 解决方案,因为没有编程方式来确定预期结果是什么。)

如果您只是堆叠两张图像,这很容易——不要在“底部”图像上放置任何 Alpha 通道,只在“顶部”图像上放置一个,然后就完成了。

如果您需要堆叠两个以上(或者如果您需要在背景图像上使用蒙版以使页面背景显示出来),您将有几个选择:

  1. 只要图像之间的边界会导致这种渗色,请在堆栈中的“底部”图像上使用 1 位 Alpha 通道。因此,如果您将“球体”图像堆叠在“立方体”图像上方,则立方体沿球体和立方体之间的边界将没有部分透明度,沿边界的所有像素将是 100% 不透明的。球体的部分透明度会使边界变得平滑,因此您不会看到像素化边缘。
  2. 使底部图像上的蒙版比当前大一像素。这是完成 (1) 的懒惰方式。
  3. 预乘图像本身的颜色 - 不是与背景,而是与否则会重叠的其他图像。沿边界的颜色变暗以弥补否则会渗出的白色。 (很明显,这有点超出我的专业领域,所以我不能确切地建议如何计算精确的颜色......)

【讨论】:

  • 感谢丹尼尔的回答,是的,您的选择是解决问题的一种方法,但我们试图避免更改图像,因为我们会遇到不同元素和不同颜色图像数量的情况,这意味着 3D 中的每个对象都需要手动调整。这就是为什么我使用 CSS3、HTML5 或 JavaScript/jQuery 寻找解决方案的原因,这样我们就不必手动更改每张图片
  • 是的,完全理解——我希望我有一个更简单的解决方案给你,但我认为事后没有任何方法可以做到这一点。如果是我,我会先尝试“使蒙版变大”的方法,因为它的工作量最少,然后看看结果是否可以接受。
  • @Pece,如果你对 js 解决方案没问题,为什么不直接用 webGL 生成这些形状呢?
  • @Kaiido 因为这些是示例形状,3D 模型可以而且将会比这更复杂
  • webgl 可以处理复杂的模型,不用担心。
【解决方案2】:

存在细微的像素差异。将你的立方体向上和向左移动 1px,你就可以开始了。

img {
  position: absolute;
  left: 0px;
  top: 0px;
}
#cube{
  top:-1px;
  left:-1px;
}
.container {
  height: 512px;
  width: 512px;
}
<div class="container">
        <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
        <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" id="cube" alt="Cube">
    </div>

【讨论】:

  • 感谢您的重播,但失去那些 1px 并不是解决方案。
  • 那你说的是哪条白线?
  • 正如我所说,这是图像的一部分,它们有 1px 的边框,alpha 为 50%,如果你将它们关联在一起,你应该得到该边框的正确颜色。我们不会试图放弃那个像素,因为大图看起来会有所不同
【解决方案3】:

试一试有助于完整解决方案

我只添加了一些 css .container img:last-child{ left: -1px; top:-1px; position:absolute }

img {
            position: absolute;
            left: 0px;
            top: 0px;
        }
        
 .container img:last-child{ left: -1px; top:-1px; position:absolute }
 
        .container {
            height: 512px;
            width: 512px;
        }
<div class="container">
        <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
        <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" alt="Cube">
    </div>

【讨论】:

  • 感谢您的回复,但我不会尝试移动图像以便它们混合,这只是一个快速修复,但不是解决方案。想象一下,如果图片中有更多元素,您将不得不对它们中的每一个进行调整,最后您将无法获得与以前相同的图像
【解决方案4】:

不幸的是,如果不实际移动元素或修改实际图像,就无法消除该间隙。但是,您可以通过对每个图像应用阴影来隐藏它来伪造它。有点像化妆去除瑕疵。不过,这确实会在图像边缘添加轻微的模糊,因此它不是一个完美的解决方案。

img {
    position: absolute;
    left: 0px;
    top: 0px;
    filter: drop-shadow(0 0 1px #000);
}

.container {
    height: 512px;
    width: 512px;
}
<div class="container">
    <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
    <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" alt="Cube">
</div>

【讨论】:

    猜你喜欢
    • 2015-02-03
    • 1970-01-01
    • 2012-09-23
    • 2018-09-19
    • 2018-08-10
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    相关资源
    最近更新 更多