as3:在透明图像上绘制笔划

时间:2014-06-24 12:48:51

标签: actionscript-3 flash bitmap

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

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

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

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

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

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

这是我被卡住的地方,因为这些点没有明显的顺序,因此我无法使用绘图API来连接点#34;。

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

1 个答案:

答案 0 :(得分:0)

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

这是用于标记透明图像轮廓的示例像素弯曲程序代码(请注意,在较新的闪存播放器中不再支持此功能,即现在由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;
    }
}

将此应用于该图像:

enter image description here

你明白了:

enter image description here

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

enter image description here


现在您可以确定此轮廓的矢量形状。

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

  2. 测试邻居顶点以查找它是否已连接(白色)。

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

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

    在某些情况下,当您将边缘拆分为更多行时,您可能无法选择正确的路径:

    enter image description here

    你可能想要回到像素有更多连接的位置并尝试另一条路径。


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

    1. 向某个方向移动,当你碰到边缘标记顶点时,向前移动一个预定距离的方向。

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


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

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

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

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

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