【问题标题】:as3: draw a stroke to a transparent imageas3:在透明图像上画笔画
【发布时间】:2014-08-14 17:49:32
【问题描述】:

我正在尝试将 Photoshop 的魔棒工具复制到用户上传的位图上。

为了达到这个效果,我使用阈值来选择一些像素,然后操纵这些像素,甚至使用这种技术添加笔触

http://forums.tigsource.com/index.php?topic=27940.0

通过上述技术,我可以在位图对象中获得所需的笔触。

问题是位图被转换为适合特定区域,因此最终结果是模糊的或具有可变的笔画大小。此外,我想将魔术棒工具与多边形套索工具结合起来,我已经使用矢量图形的绘图 API 实现了该工具。

我认为我可以找到笔画像素,然后为每个像素分配一个点,最后以某种方式连接这些点。

这是我卡住的地方,因为这些点没有明显的顺序,所以我不能使用绘图 API 来“连接点”。

任何帮助或指出正确的方向都会非常有帮助, 提前谢谢

【问题讨论】:

  • 关于套索,如果您仔细观察 Photoshop,您会发现套索选择像素而不是曲线。矢量图形生成不与像素对齐的曲线。你可以像这样使用套索:抓取套索图形,使用readGraphicsData,然后在将路径应用到另一个精灵之前添加beginFill(),然后调用endFill(),你最终会得到一个填充了像素颜色的精灵应该。然后你把它画在一个蒙版BitmapData上,这会给你套索的像素集。
  • 感谢您的回答 Vesper,但 readGraphicsData 需要 FP 11.6,我无法将它与我拥有的 flash cs 5.5 一起使用。无论如何,我会进一步调查你的提议。谢谢!
  • 然后你可以用另一种方式记录点,比如放入一个与你作为套索绘制的内容一致的数组中,并根据这些记录构建图形路径。
  • 是的,这就是我的想法,但这不是很容易,或者我想不出连接点的正确方法。谢谢!

标签: actionscript-3 flash bitmap


【解决方案1】:

我不建议您使用您提到的方法来创建笔触。它只能为简单或小的形状给您带来满意的结果。 相反,您可以对每个像素的每个邻居进行采样,以定义它是否坚持使用迭代颜色。

这是用于标记透明图像轮廓的示例像素弯曲器代码(请注意,较新的 Flash 播放器不再支持此代码,即它现在由 Flash vm 执行)。颜色只是轮廓的颜色,阈值定义了像素将被视为不透明的 alpha 值。

evaluatePixel()
{
    float2 oc = outCoord();
    dst = sampleNearest(src,oc);

    float4 nN = sampleNearest(src,float2(oc.x, oc.y - 1.0));
    float4 nNE = sampleNearest(src,float2(oc.x + 1.0, oc.y - 1.0));
    float4 nE = sampleNearest(src,float2(oc.x + 1.0 , oc.y));
    float4 nSE = sampleNearest(src,float2(oc.x + 1.0, oc.y + 1.0));
    float4 nS = sampleNearest(src,float2(oc.x, oc.y + 1.0));
    float4 nSW = sampleNearest(src,float2(oc.x - 1.0, oc.y + 1.0));
    float4 nW = sampleNearest(src,float2(oc.x - 1.0, oc.y));
    float4 nNW = sampleNearest(src,float2(oc.x - 1.0, oc.y - 1.0));

    float4 av = nN + nNE + nE + nSE + nS + nSW + nW + nNW;
    av *= 0.125;
    if(dst.a <= threshold && av.a > 0.0 && av.a < 1.0) dst = color;
    else if( dst.a > 0.0) dst = body;
    else{
        dst = color;
        dst.a = 0.0;
    }
}

将此应用于该图像:

你明白了:

由于在某些时候出现了 alpha 渐变,您的轮廓会变得更粗。您可以通过应用另一个过滤器来修复它,该过滤器将仅通过与不透明(红色)区域直接相邻的像素。方法与上面的非常相似。 之后你会得到一个像素粗线:


现在你可以确定这个轮廓的矢量形状了。

  1. 开始向某个方向移动,直到找到第一个白色像素并将其标记为顶点。

  2. 测试相邻顶点是否连通(为白色)。

  3. 如果是,则移动到该像素并重复步骤 2 另外,如果下一个白色像素的方向不同,则将最后一个标记为顶点,将最后一个标记为顶点(保持顺序),否则将其设为空白。

重复此操作,直到回到第一个顶点或当前像素没有连接。

在某些情况下,当边缘被分割成更多行时,您可能无法选择正确的路径,如下所示:

您可能想回到像素有更多连接的位置并尝试其他路径。


另一种从位图中查找形状的方法:

  1. 向某个方向移动,当您碰到边缘标记顶点时,向您来自的方向移动一段预定义的距离。

  2. 开始围绕以最后一个顶点为中心的圆移动,向后移动的距离是圆的半径。当您击中边缘标记顶点并沿垂直于最后两个顶点形成的线的方向向后移动时。重复此步骤,直到最后一个顶点与第一个顶点足够接近。


第二种方法是根据给定的距离和顶点数获得近似形状,具体取决于形状边缘的长度,但您不需要以任何特定方式准备位图。另一方面,第一种方法可以为简单的尖锐形状(如矩形)提供很少的顶点,无论其大小如何,而对于复杂的形状则更多。

这是这两种方法的实时可视化。

http://audionysos.cba.pl/edges.html

http://audionysos.cba.pl/bmscaner.html

另外请理解,这些只是我的想法的实验性实现,可以显着改进,我不向您保证这些方法是解决您的问题的最佳方法,并且不知道它是如何在专业领域完成的像photoshop这样的软件,因为我什至没有费心去搜索这些信息。 但是,我希望它在某种程度上对您有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 2021-11-12
    • 2015-10-20
    • 2013-07-08
    • 2014-08-12
    相关资源
    最近更新 更多