当反复绘制在画布上的任何东西(显然具有低阿尔法值),不管它是的drawImage()或fill功能,从而导致颜色是我测试过的所有浏览器显著不准确的.以下是我通过特定混合操作得到的结果示例:

有关示例和一些代码,请查看我编写的jsFiddle:
最顶层的数据是测试的结果,您可以通过编辑iters和rgbaJS代码的顶部进行自定义.它采用您指定的任何颜色RGBA all in range [0, 255],并将其标记在完全干净,透明的画布iters上.同时,它保持运行计算标准Porter-Duff source-over-dest混合函数将为同一过程产生的内容(即浏览器应该运行和出现的内容).
底部数据集显示了一个边界情况,我发现[127, 0, 0, 2]在顶部混合[127, 0, 0, 63]会产生不准确的结果.有趣的是,混合[127, 0, 0, 2]在顶部[127, 0, 0, 62]和所有[127, 0, 0, x]颜色之间x <= 62会产生预期的结果.请注意,此边界情况仅在Windows上的Firefox和IE中有效.在我测试过的每个其他操作系统上的每个其他浏览器中,结果都差得多.
此外,如果您在Windows上的Firefox和Windows上的Chrome中运行测试,您会发现混合结果存在显着差异.不幸的是,我们并没有谈论一两个价值 - 更糟糕的是.
我知道HTML5画布规范指出,由于舍入错误,执行drawImage()或putImageData()然后getImageData()调用可能会显示稍微不同的结果.在这种情况下,基于我碰到迄今为止的一切,我们正在谈论的东西微乎其微喜欢红色通道被122代替121.
作为一些背景资料,我前一段时间问过这个问题,@ NathanOstgard做了一些优秀的研究,得出的结论是alpha预乘是罪魁祸首.虽然这肯定可以在这里起作用,但我认为真正的潜在问题有点大.
有没有人知道我怎么可能最终得到我看到的(非常不准确的)颜色值?此外,更重要的是,是否有人有任何想法如何规避问题并在所有浏览器中产生一致的结果? …
简要背景:我正在研究基于Web的绘图应用程序,我正在实现的工具之一是1像素厚的铅笔.该工具允许用户在画布上绘制1px别名行.
为了确定用户在画布上绘制的位置,将监视鼠标坐标.如果按住mouse1,光标所在的像素将会改变.基本上它就像Photoshop中的铅笔工具一样.
注意:Bresenham的算法不适用于这种情况.我的输入是实时提交的,所以我没有画一条从P0到P1的线,其中P0和P1之间的距离是很多像素.通常,P1是P0的邻居.
我遇到的问题是我生成的线条没有完全干净的1px重量.这是一个例子:

请注意,两条线都是手绘的,因此存在一些差异.有趣的是,Photoshop能够为我绘制的线条制作更清晰的1px表示.我的线看起来更脏的原因是因为:


在我的应用程序中使用该工具进行绘制时,红色像素被填充.在Photoshop中,红色像素未被填充.这是有道理的,因为为了从给定像素移动到例如其东南邻居,要么东或南邻居很可能会被遗弃.光标准确地越过角落进入东南邻居的可能性极小,避免了红色像素的绘制,但这通常不会发生.
所以,我留下的问题是Photoshop如何能够跳过我的线条中出现的红色像素.我唯一能想到的就是等到两个像素排队之后才能绘制其中任何一个,这样我就知道是否有一个"角落邻居"被传递过来.在这种情况下,我不会绘制两个像素中的第一个,因为它相当于我的图中的红色像素.如果用户绘制像素,将光标向南移动一个像素,然后向东移动一个像素,则存在不绘制预期像素的风险.应绘制两个像素,但算法会另外说明.
有任何想法吗?Photoshop如何处理这个问题?
简要背景:我正在开发一个基于Web的绘图应用程序,需要绘制1px厚的样条曲线,这些样条曲线通过它们的控制点.
我正在努力解决的问题是我需要在p1和p2之间绘制每个像素,就像我使用1px铅笔工具一样.因此,一次没有抗锯齿和一个像素.这需要在不使用任何线/曲线库代码的情况下手动完成,因为我的画笔系统依赖于具有像素坐标以将画笔笔尖应用于画布.
基本上,我需要将像Bresenham算法这样的一个像素步进与Catmull-Rom方程返回的坐标结合起来.我遇到了麻烦,因为Catmull-Rom点分布不均匀(所以我不能说曲线中应该有100个像素并运行方程100次).我尝试使用最大的X和Y的增量的的估计初始值和与布氏间隙充填,但由于四舍五入我仍然结束了一些"脏"的部分(即该线清楚地向上移动,并与对,但我仍然得到两个具有相同Y分量的像素,导致该行的"胖"部分).
我很肯定这已经解决了,因为几乎所有绘制样条的图形程序都必须支持我所追求的干净像素曲线.经过相当多的数学研究,我有点困惑,仍然没有解决方案.有什么建议?
编辑:这是我可能需要呈现的曲线的示例:

哪个可能有预期的结果(请注意这是一个估计):

使用Catmull-Rom样条方程,我们需要四个点来创建一个分段.P0和P3用作来自P1-> P2段的进出方向的切线.使用Catmull-Rom样条曲线时,蓝色部分随着t从0移动到1而被插值.可以复制P0和P3以确保渲染绿色部分,因此这对我来说不是问题.
为了简便起见,我需要呈现P1和P2之间的曲线上的像素,因为我在P0和P3的形式切线.我不一定需要使用Catmull-Rom样条曲线,但它们似乎是这项工作的正确工具,因为控制点必须通过.插值点的非均匀分布是我抛弃循环的原因.
EDIT2:这是我说的结果曲线很脏时的一个例子:

红色箭头指出了一些不应该有像素的位置.发生这种情况是因为计算出的坐标的X和Y分量不会以相同的速率变化.因此,当每个组件都被舍入时(因此我有一个精确的像素位置),可能是X或Y没有被碰到的情况,因为计算的坐标是,例如,(42.4999,50.98).将圆形换成地板或天花板并不能解决问题,因为它只会改变发生的位置.
编辑:我不一定需要解决这个问题 - 而是我想了解它为什么会发生.我不明白为什么我应该得到以下奇怪的结果......
虽然这个问题是针对我在HTML5画布应用程序中遇到的问题,但我认为问题不那么具体.
我有一个HTML5画布应用程序,允许您在屏幕上标记图像.这些图像是32位PNG,所以我正在使用透明度.如果我在同一位置多次(大约100)标记高度透明的图像,我最终会得到一个绝对可怕的结果:

我用作图章的图像的颜色和我正在加盖RGB(167, 22, 22)的背景是RGB(255, 255, 255).这是源图像,如果有人感兴趣:

如您所知,图像的alpha级别极低.可能左右2/255 to 5/255左右.我期望发生的是,如果你反复将图像标记重复应用到画布上,你将获得颜色像素RGBA(167, 22, 22, 255).不幸的是,我得到了一个混合的颜色袋,包括一些非常奇怪的灰色区域,其值为RGB(155, 155, 155).
我只是加载Excel并插入了源代码alpha混合的等式(维基百科参考),我似乎在RGB(167, 22, 22)经过足够的迭代后收敛.我可能遗漏了一些关于alpha混合操作的基本知识以及HTML5 canvas如何实现源代码合成...任何人都可以帮助理顺我吗?
谢谢!
注意:这个问题与我的问题类似,但我不太明白为什么我得到了我在这里发布的结果.
我需要设置一个GLSL片段着色器来更改当前正在处理的片段之外的片段的颜色.由于这似乎不太可取,我将提供一个非常简短的背景.
该项目利用渲染过程,将给定模型绘制到具有与纹理贴图中的UV坐标对应的独特颜色的FBO中.然后对这些颜色进行采样并转换为图像坐标,以便可以根据相机可见的内容更新模型的纹理贴图.实质上:
Render model to FBO
For each FBO pixel
1. sample secondary texture based on FBO pixel position
2. convert color at current pixel to image coordinate for the model's texture map
3. update model's texture with sampled secondary texture at calculated coordinate
End loop
Run Code Online (Sandbox Code Playgroud)
问题是当前的实现非常受CPU限制,因此我正在读取FBO中的像素,然后对它们进行操作.理想情况下,由于我已经在片段着色器中使用了片段的颜色,因此我想简单介绍该过程的最后几个步骤并将所有内容保留在GPU上.
我遇到的具体问题是,我不太清楚如何(或者甚至可能)让片段着色器设置它未处理的片段的颜色.如果我不能通过使用一个特大的FBO来工作,只是偏移我要设置颜色的片段,我可以做一些直接写入纹理的东西吗?
非常感谢任何帮助/建议.谢谢!