线条质量非常低,边缘锯齿或模糊

时间:2017-06-20 14:18:56

标签: actionscript-3 flash graphics graphics2d

我正在使用绘图应用程序,与其他绘图应用程序相比,线条质量似乎非常低且呈锯齿状。

或者可能是其他应用正在做一些与我不同的事情。

到目前为止我所做的是使用graphics属性绘制线条。我还收集鼠标移动事件上的鼠标位置,以便稍后分配给路径。总结一下:

MouseDownHandler:

mouseDownPoint.x = event.stageX;
mouseDownPoint.y = event.stageY;
drawCommands.push(GraphicsPathCommand.MOVE_TO);
simplePath = "M " + mouseDownPoint.x + " " + mouseDownPoint.y;

MouseMoveHandler:

line.graphics.lineStyle(lineWeight, lineColor, lineAlpha, pixelHinting);
line.graphics.moveTo(previousPoint.x, previousPoint.y);
scaledPoint = new Point(localPoint.x/scaleX, localPoint.y/scaleY);
line.graphics.lineTo(scaledPoint.x, scaledPoint.y);
previousPoint.x = scaledPoint.x;
previousPoint.y = scaledPoint.y;
simplePath += " L " + scaledPoint.x + " " + scaledPoint.y;

MouseUpHandler:

myPath.data = simplePath;

当我绘制时,我更新了一行(它是一个UIComponent,但也可以是一个Shape或Sprite - 任何具有graphics属性的东西)。同时我跟踪simplePath字符串中的鼠标位置。

当鼠标启动时,我清除线条图形并显示路径图形元素。路径对此并不重要,但我注意到它看起来比绘制的线稍微干净一些。这可能是因为它有像素提示(它不太清洁)。有时会有文物。并且我包括它以防我出于某种原因需要使用路径。

以下是截图:

without pixel hinting with pixel hinting

像素暗示的版本看起来更加清晰,但它仍然远低于其他应用程序中线条画的质量,在某些情况下,它看起来更加锯齿状。有什么我想念的吗?

注意:我包含了graphics2d和canvas2d,因为我认为这可能与特定语言或平台无关,但可能与绘制图形有关。

2 个答案:

答案 0 :(得分:3)

绿线由 Graphics.cubicCurveTo(...)方法生成。最初,您有一个用户提供的点A1,A2,A3 ... An的列表。为了使用三次曲线,你还需要为每个Ak分别绘制2个控制点CFk(向前)和CBk(向后),所以你从A1开始绘制那条大曲线,从Ak-1到Ak的每个曲线片段都需要参数 .cubicCurveTo(CFk-1,CBk,Ak);

对于每个Ak(A1和An除外),您可以按如下方式计算CFk和CBk:

(vector)AForward = (vector)(Ak+1 - Ak-1)
(vector)AForward.length = (vector)(Ak+1 - Ak).length / 3

CFk = Ak + (point)AForward

(vector)ABackward = (vector)(Ak-1 - Ak+1)
(vector)ABackward.length = (vector)(Ak-1 - Ak).length / 3

CBk = Ak + (point)ABackward

然后,A1和An被遗漏了,但我相信你可以自己解决它们。

对于矢量数学,您可以从我的一些有用的东西中使用 ru.delimiter.math.Vector2D 类(适用于笛卡尔坐标和极坐标):https://bitbucket.org/thydmitry/ru.delimiter/src/9083fb46ce1c/classes/ru/delimiter/math/

PS 也许你不需要走极端,用红线就可以了,这是一个简单的 .curveTo(Ak,(Ak + Ak + 1) )/ 2);

UPD :一种简单的算法,可以将曲线刻成由一系列点提供的之字形。

function middle(A:Point, B:Point):Point
{
    return new Point((A.x + B.x) / 2, (A.y + B.y) / 2);
}

function drawTo(target:Point):void
{
    graphics.lineTo(target.x, target.y);
}

function bendTo(control:Point, target:Point):void
{
    graphics.curveTo(control.x, control.y, target.x, target.y);
}

// This should contain at least 2 points before you start drawing.
var PP:Vector.<Point>;

// Go to the start position.
graphics.lineStyle(0, 0xFF0000);
graphics.moveTo(PP[0].x, PP[0].y);

// Draw a straight line to the center of the first zigzag segment.
drawTo(middle(PP[0], PP[1]));

// For each 3 consequent points A,B and C, connect
// the middle of AB and the middle of BC with a curve.
for (var i:int = 2; i < PP.length; i++)
{
    bendTo(PP[i - 1], middle(PP[i - 1], PP[i]));
}

// Connect the center of the last zigzag segment with the end point.
drawTo(PP[PP.length - 1]);

答案 1 :(得分:0)

有多种原因:

  • 舞台质量。在Flash Player中,您可以将stage quality设置为LOW,MEDIUM,HIGH,BEST,8x8,8x8Linear,16x16和16x16Linear。这会影响是否在线/路径上应用抗锯齿以及应用了多少次。提高质量有助于8​​x8和更高质量的Flash Player中存在错误(非嵌入字体的字体大小减少25%,图形工件,渐变填充颜色数减少)。
  • 像素对齐。如果您的1px线最终位于半像素上,则它会在两条线上反锯齿。通常抗锯齿可以提高质量,但在偏移单像素线的情况下会降低质量。设置像素对齐有帮助。
  • 使用curveTo和cubicCurveTo而不是@Organis建议的线点。不知道该怎么做。

当我有机会时,会尝试在每种情况下发布差异图像。