标签: premultiplied-alpha

如何在图像卷积过程中使用预乘以解决alpha出血问题?

我试图将一个框模糊应用于透明图像,并且我在边缘周围得到一个"暗晕".

Jerry Huxtable 简要提到了这个问题,并且展示了问题的一个非常好的演示:

在此输入图像描述

但是,对于我的生活,我无法理解" 预乘alpha "是如何解决这个问题的.现在举一个非常简单的例子.我有一个3x3图像,包含一个红色和一个绿色像素:

在此输入图像描述

实际上剩下的像素是透明的:

在此输入图像描述

现在我们将对图像应用3x3 Box Blur.为简单起见,我们只计算中心像素的新值.盒子模糊的工作方式是,由于我们有一个9个位置的正方形(3x3,称为内核),我们占用内核中每个像素的1/9,并将其加起来:

在此输入图像描述

所以

finalRed =   1/9 * red1 + 1/9 * red2 + 1/9 * red3+ ... + 1/9 * red9
finalGreen = 1/9*green1 + 1/9*green2 + 1/9*green3+ ... + 1/9*green9
finalBlue =  1/9* blue1 + 1/9* blue2 + 1/9* blue3+ ... + 1/9* blue9
finalAlpha = 1/9*alpha1 + 1/9*alpha2 + 1/9*alpha3+ ... + 1/9*alpha9
Run Code Online (Sandbox Code Playgroud)

在这个非常简单的例子中,计算变得非常简单:

finalRed =   1/9 * 255
finalGreen = 1/9 * 255
finalBlue =  0
finalAlpha …
Run Code Online (Sandbox Code Playgroud)

alphablending image-processing convolution premultiplied-alpha

13
推荐指数
1
解决办法
2856
查看次数

将PNG转换为预乘alpha的方法

寻找某种简单的Windows工具或流程,让我将一个或多个标准PNG转换为预乘alpha.

命令行工具是理想的; 我可以轻松访问PIL(Python Imaging Library)和Imagemagick,但如果它让生活更轻松,它将安装另一个工具.

谢谢!

png imagemagick python-imaging-library premultiplied-alpha

8
推荐指数
3
解决办法
5539
查看次数

opengl中图像的部分透明部分周围的暗晕

我经常用OpenGL找到,当我试图在纹理上绘制一些东西然后再到另一个表面上时,使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),我总是最终得到一个彩色光环(通常是一个深色的带),在我的源的半透明部分边缘附近的图像.这显然是由于制作本质上是由该混合风格引起的预乘alpha的问题引起的.对于3D场景,我通常使用画家算法,并且为了渲染2D内容,我喜欢先绘制最后面的对象,然后在它们之上覆盖其他对象.值得注意的是,在进行这样的2D绘制时,我通常不能像3d中那样依赖像az缓冲区这样的功能,这就是为什么渲染像guis这样的东西比3D场景图更多的问题.

我认为值得注意的是,当目标缓冲区恰好已完全不透明时,上述混合风格实际上是完美的,但如果目标是透明的,那么在这种情况下实际需要的是glBlendFunc(GL_SRC,GL_ZERO)......因为任何全白像素例如,在源中部分透明,应该保持完全饱和的颜色,而不是与实际上不存在的背景"混合",因为使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)实际上会渲染部分透明和全白像素前景和背景之间的混合,这是我想要的,但不是alpha信息丢失的程度,也不是实际改变颜色的程度.

因此,在我看来,那种可能完美的混合函数实际上会混合在原本由其自身价值引起的glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)和由此引起的内容之间.glBlendFunc(GL_SRC,GL_ZERO)DST_ALPHA

因此,理想情况下:

Cr = Cs * (1 - Ad) + (Cs * As + Cd * (1 - As)) * Ad
Ar = As * (1 - Ad) + Ad * Ad
Run Code Online (Sandbox Code Playgroud)

这样,如果目的地已经是不透明的,则正常的阿尔法乘法适当地混合,而如果目的地是透明的或部分透明的,它将使用更多的源图像的真实颜色而不是使用所述颜色的阿尔法预乘形式.

然而,似乎没有明显的方法来描述这种混合机制到OpenGL.似乎这些问题在我的情况下几乎不应该是独一无二的,而且对我来说似乎并不常见,即使在可编程管道中也没有任何方法可以实现这一点.

到目前为止,我发现的唯一解决方法是每当我绘制一个纹理时反转绘图顺序,我将在其他地方绘制并使用glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA).

在我将在以后正常渲染的纹理上绘制某些东西的情况下绘制顺序的特殊情况是一种妥协,但这对我来说没有吸引力,因为它缺乏可重用性,除非执行绘图的代码总是让人知道什么类型的目的地,以便它可以扭转自己通常的绘图顺序,我可以毫不必要地使它复杂化.

最后,尽管反转整个场景的绘制顺序并不一定完全不可能,但它要求在绘制第一个对象之前确定将在每个图形帧中显示的完整对象列表.我对此有一个核心问题是虽然在渲染3D场景时这可能是可持续的,但在绘制像2d gui这样的东西时,绘制的各种各样的东西以及绘制它们的方式都是如此之大以至于没有将它们概括为单个对象列表的方法,该列表总是可以在以后以相反的顺序遍历.在我看来,它需要这样一个根本不同的观点,如何按照我习以为常的"倒退"顺序构建2D场景,我现在根本无法理解可维护的解决方案.

那么......有另一种方法吗?我错过了什么吗?或者我是否必须学习一种完全不同的方式来构建2D图像?我不可能是唯一有这个问题的人,但我还没有找到任何好的和干净的解决方案.

编辑:

如果确实存在OpenGL的任何常用扩展,通过NVIDIA或其他方式,允许混合模式可以执行此操作:

Cr = Cs * (1 - Ad) + (Cs * As + Cd * (1 - As)) * Ad …
Run Code Online (Sandbox Code Playgroud)

opengl alphablending premultiplied-alpha

8
推荐指数
1
解决办法
677
查看次数

如何判断FFmpeg解码的视频帧中的颜色是否预先乘以alpha?

当我使用FFmpeg(avcodec_decode_video2(),sws_scale())和一些视频(例如,ProRes4444)解码视频帧时,我得到预先乘以alpha的颜色,并且使用其他视频(例如,QuickTime PNG),我得到的颜色不是预先倍增的通过alpha.

如何判断颜色是否预先倍增?或者,我如何告诉FFmpeg始终提供预乘或未预乘("直alpha")颜色?

graphics video ffmpeg compositing premultiplied-alpha

6
推荐指数
1
解决办法
327
查看次数

如何在手动“叠加”混合操作中处理 alpha?

我正在玩一些手动(按像素移动)图像处理,我正在重新创建标准的“叠加”混合。我在这里查看“Photoshop 数学”宏:

http://www.nathanm.com/photoshop-blending-math/另请参阅此处了解更易读的 Overlay 版本)

两个源图像都采用相当标准的 RGBA(每个 8 位)格式,目标也是如此。当两个图像完全不透明(alpha 为 1.0)时,结果按预期正确混合:

但是,如果我的“混合”层(顶部图像)具有透明度,那么我对如何将该 alpha正确分解到混合方程中感到有些困惑。我希望它能够工作,使得混合层中的透明像素对结果没有影响,混合层中的不透明像素正常进行叠加混合,而半透明混合层像素对结果有一些缩放效果。

有人可以向我解释混合方程或这样做背后的概念吗?

奖励积分,如果你能帮助我做到这一点使得产生的图像已经正确地预乘alpha(只进场对于不是不透明的两个层中的像素,我想。)

谢谢!

// factor in blendLayerA, (1-blendLayerA) somehow?
resultR = ChannelBlend_Overlay(baseLayerR, blendLayerR); 
resultG = ChannelBlend_Overlay(baseLayerG, blendLayerG);
resultB = ChannelBlend_Overlay(baseLayerB, blendLayerB);
resultA = 1.0; // also, what should this be??
Run Code Online (Sandbox Code Playgroud)

graphics blend image-processing rgba premultiplied-alpha

5
推荐指数
2
解决办法
2132
查看次数

在iOS中加载4通道纹理数据

我想从iOS中的文件加载4通道纹理数据,因此我将纹理视为(连续)地图

[0,1]x[0,1] -> [0,1]x[0,1]x[0,1]x[0,1]
Run Code Online (Sandbox Code Playgroud)

如果我使用fileformat .png,XCode/iOS 会将文件视为图像,因此将每个组件rgba(预乘alpha)相乘,从而破坏我的数据.我该怎么解决这个问题?例子可能是

  • 使用两个纹理与组件rgb(3通道)
  • postdivide alpha
  • 使用其他文件格式

其中,我认为最好的解决方案是使用其他文件格式.GL压缩文件格式(PVRTC?)不是Apple平台独立的,似乎是低分辨率(4位)(参考).

编辑:如果我自己的答案是真的,那么就无法在iOS中获得png的4通道数据.由于OpenGL是关于创建图像而不是呈现图像,因此应该可以以某种方式加载4通道数据.png是图像的文件格式(和压缩取决于所有4个通道但是一个通道的压缩与其他通道无关),因此有人可能会说我应该使用另一种文件格式.那么我应该使用哪种其他压缩文件格式,哪些易于在iOS中阅读/集成?

更新:"组合"提到了一种加载4通道非预乘纹理的方法,所以我不得不给他正确的答案.但是,该解决方案有一些我不喜欢的限制.我的下一个问题是"从iOS中的png文件访问原始4通道数据":)

我认为这是一个糟糕的库设计,无法读取4通道png数据.我不喜欢系统试图比我自己聪明.

textures ios opengl-es-2.0 premultiplied-alpha

5
推荐指数
1
解决办法
1781
查看次数

TYPE_INT_ARGB_PRE 的影响

我在ConvolveOp方面遇到了一些问题,可以通过将我正在使用的BufferedImage的 imageType 设置为TYPE_INT_ARGB_PRE来解决(请参阅此处相关的 SO 答案)。

不幸的是,我不完全理解选择这种不同的 imageType 的所有含义,而且我似乎也找不到好的参考,所以让我在这里尝试一下:

将 BufferedImage 的 imageType 从 TYPE_INT_ARGB 更改为 TYPE_INT_ARGB_PRE 会影响哪些绘图操作?它只是BufferedImageOps吗?或者如果将图像绘制到不同的 Graphics 对象上,它是否会影响图像的Graphics对象上的任何绘制命令或图像的渲染方式?

java bufferedimage premultiplied-alpha

1
推荐指数
1
解决办法
1456
查看次数