Snipaste / feedback

Feedback & wiki for Snipaste https://snipaste.com
3.06k stars 197 forks source link

Improve Anti-Jitter feature. | 改善画笔的防抖功能。 #371

Closed wdhwg001 closed 4 years ago

wdhwg001 commented 7 years ago

default snipaste_20170310_111305

像这样,当手绘尝试绘制一个弧形时,尽管手没有抖,但最终松开鼠标后生成的线条却抖的厉害。

我不知道目前Snipaste使用的防抖算法,不过或许可以尝试一下Cubic Hermite Spline或者其他Spline算法?

插值问题其实是较为复杂的,Cubic Hermite Spline可能是一个比较好的方案,但也有其他的,或许这里会有一些思路: https://www.zhihu.com/question/53708752/answer/136236819

wdhwg001 commented 7 years ago

以及又仔细看了一下,问题可能出现在采样上,最终生成的曲线继承了最初画笔的锯齿。

或许,采样精度需要进一步的提升?或者,这个问题仅出现在HiDPI即200% DPI下?

需要进一步的调查。


在松开鼠标前,画笔的锯齿跳变是以2像素为一个单位的,或许这是造成锯齿的原因。

liulex commented 7 years ago

这只是参数设置的问题。目前使用的参数是使得拟合结果尽可能接近于平滑之前的,确实不太理想,我会在下版本做调整。后续或许可以把这个参数交给用户设置。 谢谢你提供的资料。

wdhwg001 commented 7 years ago

更改QT_AUTO_SCREEN_SCALE_FACTOR使得

dots per inch = 2, device pixel ratio = 1

之后,线条变得平滑了一些,但是效果依旧不够理想,至于dpi=1, dpr=2的状况则更糟糕一些,且劣化的程度高于样本数/2,或许还可以引入一个降噪或是干脆在1/2分辨率下计算,然后bilinear插值到200% DPI?因为变形位置主要发生在锯齿区域。

liulex commented 7 years ago

Snipaste 使用的路径拟合算法是这个: http://paperjs.org/examples/path-simplification/ 之前设置的 tolerance1.5,你可以玩一下上面的 demo,看 tolerance 设为多少比较合适。 当然平滑效果和采样间隔有关,所以如果是慢慢地画,拟合处理的反而会不平滑些。

在乎这个的用户不多,所以就没必要改算法了,当然有现成可用的就另说了。 🌚

wdhwg001 commented 7 years ago

Cubic Hermite Spline的算法我在UE4里看到过,你或许可以在google上找到不少样例代码,其他的诸如Catmull–Rom的也应该能找到。 snipaste_20170310_182113 上图是: https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js#L1337 中的链接: https://www.particleincell.com/2012/bezier-splines/ 中的示例demo呈现的,可以看出这个算法其实…并不太对。 以及…基于预测和距离的采样或许会比基于时间的采样更可靠一些,但是这样工作量又大了,根据精力取舍吧。

liulex commented 7 years ago

你上面给的是 smooth 吧,我用到的是 simplify …… 拟合得更平滑的,比如把当前算法的 tolerance 设大,不可避免地会让线条变形更大,可能反而不是用户所希望的。

我用这个算法,就是因为它提供了 demo 并且效果让我满意,所以除非 有直接能用的并且效果明显更好的,没有必要做改变。

wdhwg001 commented 6 years ago

有更新吗?最近又一次被这个问题困扰了,或许可以:

liulex commented 6 years ago

https://docs.snipaste.com/zh-cn/advanced-configs?id=misc

[Misc]
path_simplify_tolerance=0
wdhwg001 commented 6 years ago

感谢。直接关闭平滑后效果好一些,但抗锯齿也随之消失了。

我注意到,在前文中的例子: http://paperjs.org/examples/path-simplification/ 中的平滑算法已经比较显著的优于Snipaste中使用的实现了,在path.simplify(1);时可以获得效果较好的平滑度。

以及,线条的抗锯齿和平滑是否应该分开设置?

liulex commented 6 years ago

@wdhwg001 输入不同哦,对于相同的鼠标移动速度,桌面应用能够获得的输入点更密集,你在 paperjs.org 缓慢地移动鼠标才能模拟 Snipaste 获得的输入,这种情况下网站计算的效果并不会更好。