Gsllchb / Handright

A lightweight Python library for simulating Chinese handwriting
BSD 3-Clause "New" or "Revised" License
2.03k stars 248 forks source link

旋转stroke会导致像素丢失 #56

Open zixiiu opened 3 months ago

zixiiu commented 3 months ago

你的代码里,每一个stroke都会随机旋转和上下移动。

def _rotate(
        center: Tuple[float, float], x: float, y: float, theta: float
) -> Tuple[float, float]:
    if theta == 0:
        return x, y
    new_x = ((x - center[0]) * math.cos(theta)
             + (y - center[1]) * math.sin(theta)
             + center[0])
    new_y = ((y - center[1]) * math.cos(theta)
             - (x - center[0]) * math.sin(theta)
             + center[1])
    return new_x, new_y

得到新的像素坐标这里,使用了cos和sin去算新坐标的位置。如果theta不为0,这里必定得到的值不是整数。 然而在这里

def _draw_stroke(
        bitmap,
        stroke: Sequence[Tuple[int, int]],
        tpl: Template,
        center: Tuple[float, float],
        rand
) -> None:
    dx = gauss(rand, 0, tpl.get_perturb_x_sigma())
    dy = gauss(rand, 0, tpl.get_perturb_y_sigma())
    theta = gauss(rand, 0, tpl.get_perturb_theta_sigma())

    for x, y in stroke:
        # if 0 <= x < width and 0 <= y < height:
        #     draw.point((x, y), fill='black')
        new_x, new_y = _rotate(center, x, y, theta)
        new_x = round(new_x + dx)
        new_y = round(new_y + dy)
        width, height = tpl.get_size()
        if 0 <= new_x < width and 0 <= new_y < height:
            bitmap[new_x, new_y] = tpl.get_fill()

new_x 和 new_y 被 round到了整数。

所以如果有一定的旋转值,必定会丢失一些像素。如图所示。

image

kerener commented 2 months ago

楼主解决没,我也遇到这个问题。我查资料,旋转使用三次插值算法可解决空穴问题,不知道如何实现。

Gsllchb commented 2 months ago

只要画布足够大,就可以忽略锯齿的影响。加入抗锯齿反而会引入过渡色,导致颜色不纯,打印出来的效果反而不好。

---原始邮件--- 发件人: @.> 发送时间: 2024年8月22日(周四) 下午2:19 收件人: @.>; 抄送: @.***>; 主题: Re: [Gsllchb/Handright] 旋转stroke会导致像素丢失 (Issue #56)

楼主解决没,我也遇到这个问题。我查资料,旋转使用三次插值算法可解决空穴问题,不知道如何实现。

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.***>