寻求平滑处理字体图形的算法

时间:2021-11-19 17:35:46
当字号特别大时
用字做的图边缘部分不平滑
在photoshop中有处理的方法,使得文字平滑

这样的算法如何实现

谢谢。

20 个解决方案

#1


那你还不如将字体转为矢量图形呀!
在CorelDRAW里可将字体转为矢量!
在游戏里如何读取矢量图形的算法俺就不知啦!
还望高手指点!

#2


gdi+有,效果还行

#3


采用并获取TrueType字体的曲线轮廓数据(每一笔画由闭合的二次B样条曲线组成),然后绘出笔画轮廓并填充之。此法可任意变换字形,无级缩放。其步骤:
1. CreateFontIndirect 创建逻辑字体
2. SelectObject  选用逻辑字体
3. GetGlyphOutline 获取笔画轮廓
   由GetGlyphOutline,得
   DWORD cbBuffer; /* size of buffer for data */
   void FAR* lpBuffer;/* address of buffer for outline data */
                      /* 含B-2曲线的各特征点 */
4. 由cbBuffer和lpBuffer,构成一个或多个曲线多边形,并可任意变形处理
5. CreatePenIndirect
   CreateBrushIndirect
   SelectObject 选用笔
   SelectObject 选用刷
7. 用PolyPolygon 填绘各多边形(笔画)

#4


问题没有这么简单,即使用平滑的曲线绘画仍然不可避免的会有锯齿,这是人的视觉特征决定的,TrueTypy字体实际上已经采用了平滑的曲线进行绘制了,一般不需要你自己处理,自己处理我认为是多此一举。
photoShop之所以会感觉平滑,是因为它在字体边缘部分增加了过渡区,在前景色和背景色做了一个平滑的色彩过渡,如果你在输入文字的时候,填充上面不要选择正常,而是选择无,你就会发现PhotoShop做出来的仍然有锯齿。之所以感觉没有锯齿,是利用了人的视觉心理特征。你所要做的就是在绘制好的文字边缘增加过渡色彩,而不要生硬,这样就会感觉相当平滑。

#5


asett1(asett1):哪里有资料,给点提示

#6


1. BlueTrees(蜗牛)所说,“TrueTypy字体已经采用了平滑曲线进行绘制,一般不需自己处理”是对的。但是,如果要求对字形作任意变换(例如向左的斜体,向右上或右下的耸肩体,笔画内填充各种纹理等)且不依赖现成图形软件的话,则必须通过GetGlyphOutline 获取笔画轮廓,然后对其变换之。
2. 由于设备分辨率有限,在屏幕上绘各种几何曲线都会有“锯齿”形,锯齿大小为一个像元。TrueTypy字体能无级缩放,不论放大多少“锯齿”总是一像元大,而点阵字体的“锯齿”会随字形放大而增大。
3. 要使感觉没有锯齿,须用特殊手段,如反走样法。

#7


不知gdi+中有没有反走样功能?
如果无此功能,且须由应用程序实现,那末获取TrueType笔画轮廓数据(GetGlyphOutline )仍是必要的。

#8


不用反走样法效果不会太好

#9


I suggest you learn something about digital image processing. This is a basic image blur problem. The only difficulty is algorithm efficiency and final effect.

#10


很感谢大家的帮助
提了这么多意见
同样感谢版主大人把这个贴放到了首页。使得更多高手能够看到

可能我没表达太清楚
我所需要的是类似 photo shop里对字体平滑处理的算法
正如 BlueTrees(蜗牛) 讲的那样,是在字体周围加上一个过渡区
加过渡区,友好几种办法,有blur,还有什么模糊算法,例如Gauss模糊等
可是这些算法有差别的,字号大的时候能看出来,可以放大这个图,就看出
过渡区的不同了,
这些算法都远不如photoshop里的字体平滑算法。
我需要的就是这种平滑的算法。。。

虽然视觉效果相差不是很多,但是我们公司要这么追求品质,没办法。

谢谢大家的回复。

如果谁感觉分数不够的话,我可以最后重新开个新贴给大家补
我一次最多只能给200,我还有1000分剩余。

再次谢谢大家的回复。并期望大家关心。

#11


可按xqr(星球人) 所说的办法,只是画polygon的时候用自己写的画反锯齿polygon的函数。

#12


我就是在问这个反锯齿(加个过渡区)的函数的算法啊

#13


gdiplus支持反走样,用起来很方便。

#14


这个很复杂,我们公司花了10000元买来的,效果比微软的好,但是比inscriberCG还是差一点,不过用作普通的文字处理已很好了,原理都很简单
将曲线换成直线,画polygon时进行反走样,

#15


字体反走样宜采用“区域轮廓反走样”技术,这有二类处理方法:
1. “像素微移法”。若某个边缘像素有1/4以上面积落在理论轮廓线外,则控制电子束微偏(一般可微偏像素直径的1/4,1/2,3/4),以校正该像素位置。这种方法效果佳,但需硬件支持。
2. “改变像素亮度法”。逐个计算边缘像素落在理论轮廓线内的面积,若全部在内则按原亮度输出;否则,加大亮度输出,加大程度(分级)视像素内外面积比而定。这是常用之法。
看来,如果gdi+无反走样功能,那么不论采用何种反走样法获取曲线轮廓数据是必需的。
gdi+ 能支持反走样就更好,不知如何具体使用?

#16


If you have enough money, you can just buy one. If you don't want so, then you can never write such a good algorithm without a deep study on image processing. This is a basic blur problem, Gaussion blur is quite enough! Moreover, you needn't get the text outline at all.

I've written such one, but it's slower than GDI+. :-(

BTW: don't ask me for the source code, it's owned by my company.

#17


字越大,“锯齿”越明显吗?
不能一概而论,应区别不同情况来回答:
1. 如果输出点阵字,那么字越大“锯齿”也越大越明显。
2. 如果先输出较小的TrueType字,然后按图像放大法放大它(如Windows 画图软件中的放大功能),那么字越放大“锯齿”也越大越明显。
3. 如果直接按大尺寸输出TrueType字,那么不论字多大,“锯齿”大小是不变的(总是一个像元大)。而且,因为字越大笔画越粗,“锯齿”尺寸与笔画粗之比越小,所以在视觉上字越大“锯齿”却越不明显。

以上理解对吗?请指正。

#18


我也碰到类似问题。
不过我是处理多边形等图形。
比如使用windowsAPI画直线 (0,0)->(100,1),水平距离为1各像素,所以必然会在(50,0)(51,1)处产生锯齿。当然,使用GDI+可以避免这个情况,达到Photoshop通向效果,但是GDI+的效率太低了,根本不适合用在图形处理软件中(至少我在win2k下的测试结果如此).同时,我注意到ms 在officeXP中使用了画平滑线的技术(画个直线看看就知道了),而且我测试后发现比GDI+快很多,在officeXP目录中也没有gdiplus.dll,所以ms肯定使用了优化过的算法,真是卑鄙阿!!!
现在各位大虾和小弟都希望可以做出一个平滑算法,不如大家一起来努力如何?可以做一个封装好的类,方便自己,也方便大家。
至于算法,思路,还要靠大家帮忙拉!!!
如果有着方面的技术文档,例子,麻烦发到:harry202@163.com
如果有兴趣一起努力 ,加QQ:151586 发验证消息:"gdi"
完成后所有文档,代码会在csdn公布。

#19


patch:上面“水平距离为1各像素”改为"垂直距离为1各像素"

#20


sorry for late.

#1


那你还不如将字体转为矢量图形呀!
在CorelDRAW里可将字体转为矢量!
在游戏里如何读取矢量图形的算法俺就不知啦!
还望高手指点!

#2


gdi+有,效果还行

#3


采用并获取TrueType字体的曲线轮廓数据(每一笔画由闭合的二次B样条曲线组成),然后绘出笔画轮廓并填充之。此法可任意变换字形,无级缩放。其步骤:
1. CreateFontIndirect 创建逻辑字体
2. SelectObject  选用逻辑字体
3. GetGlyphOutline 获取笔画轮廓
   由GetGlyphOutline,得
   DWORD cbBuffer; /* size of buffer for data */
   void FAR* lpBuffer;/* address of buffer for outline data */
                      /* 含B-2曲线的各特征点 */
4. 由cbBuffer和lpBuffer,构成一个或多个曲线多边形,并可任意变形处理
5. CreatePenIndirect
   CreateBrushIndirect
   SelectObject 选用笔
   SelectObject 选用刷
7. 用PolyPolygon 填绘各多边形(笔画)

#4


问题没有这么简单,即使用平滑的曲线绘画仍然不可避免的会有锯齿,这是人的视觉特征决定的,TrueTypy字体实际上已经采用了平滑的曲线进行绘制了,一般不需要你自己处理,自己处理我认为是多此一举。
photoShop之所以会感觉平滑,是因为它在字体边缘部分增加了过渡区,在前景色和背景色做了一个平滑的色彩过渡,如果你在输入文字的时候,填充上面不要选择正常,而是选择无,你就会发现PhotoShop做出来的仍然有锯齿。之所以感觉没有锯齿,是利用了人的视觉心理特征。你所要做的就是在绘制好的文字边缘增加过渡色彩,而不要生硬,这样就会感觉相当平滑。

#5


asett1(asett1):哪里有资料,给点提示

#6


1. BlueTrees(蜗牛)所说,“TrueTypy字体已经采用了平滑曲线进行绘制,一般不需自己处理”是对的。但是,如果要求对字形作任意变换(例如向左的斜体,向右上或右下的耸肩体,笔画内填充各种纹理等)且不依赖现成图形软件的话,则必须通过GetGlyphOutline 获取笔画轮廓,然后对其变换之。
2. 由于设备分辨率有限,在屏幕上绘各种几何曲线都会有“锯齿”形,锯齿大小为一个像元。TrueTypy字体能无级缩放,不论放大多少“锯齿”总是一像元大,而点阵字体的“锯齿”会随字形放大而增大。
3. 要使感觉没有锯齿,须用特殊手段,如反走样法。

#7


不知gdi+中有没有反走样功能?
如果无此功能,且须由应用程序实现,那末获取TrueType笔画轮廓数据(GetGlyphOutline )仍是必要的。

#8


不用反走样法效果不会太好

#9


I suggest you learn something about digital image processing. This is a basic image blur problem. The only difficulty is algorithm efficiency and final effect.

#10


很感谢大家的帮助
提了这么多意见
同样感谢版主大人把这个贴放到了首页。使得更多高手能够看到

可能我没表达太清楚
我所需要的是类似 photo shop里对字体平滑处理的算法
正如 BlueTrees(蜗牛) 讲的那样,是在字体周围加上一个过渡区
加过渡区,友好几种办法,有blur,还有什么模糊算法,例如Gauss模糊等
可是这些算法有差别的,字号大的时候能看出来,可以放大这个图,就看出
过渡区的不同了,
这些算法都远不如photoshop里的字体平滑算法。
我需要的就是这种平滑的算法。。。

虽然视觉效果相差不是很多,但是我们公司要这么追求品质,没办法。

谢谢大家的回复。

如果谁感觉分数不够的话,我可以最后重新开个新贴给大家补
我一次最多只能给200,我还有1000分剩余。

再次谢谢大家的回复。并期望大家关心。

#11


可按xqr(星球人) 所说的办法,只是画polygon的时候用自己写的画反锯齿polygon的函数。

#12


我就是在问这个反锯齿(加个过渡区)的函数的算法啊

#13


gdiplus支持反走样,用起来很方便。

#14


这个很复杂,我们公司花了10000元买来的,效果比微软的好,但是比inscriberCG还是差一点,不过用作普通的文字处理已很好了,原理都很简单
将曲线换成直线,画polygon时进行反走样,

#15


字体反走样宜采用“区域轮廓反走样”技术,这有二类处理方法:
1. “像素微移法”。若某个边缘像素有1/4以上面积落在理论轮廓线外,则控制电子束微偏(一般可微偏像素直径的1/4,1/2,3/4),以校正该像素位置。这种方法效果佳,但需硬件支持。
2. “改变像素亮度法”。逐个计算边缘像素落在理论轮廓线内的面积,若全部在内则按原亮度输出;否则,加大亮度输出,加大程度(分级)视像素内外面积比而定。这是常用之法。
看来,如果gdi+无反走样功能,那么不论采用何种反走样法获取曲线轮廓数据是必需的。
gdi+ 能支持反走样就更好,不知如何具体使用?

#16


If you have enough money, you can just buy one. If you don't want so, then you can never write such a good algorithm without a deep study on image processing. This is a basic blur problem, Gaussion blur is quite enough! Moreover, you needn't get the text outline at all.

I've written such one, but it's slower than GDI+. :-(

BTW: don't ask me for the source code, it's owned by my company.

#17


字越大,“锯齿”越明显吗?
不能一概而论,应区别不同情况来回答:
1. 如果输出点阵字,那么字越大“锯齿”也越大越明显。
2. 如果先输出较小的TrueType字,然后按图像放大法放大它(如Windows 画图软件中的放大功能),那么字越放大“锯齿”也越大越明显。
3. 如果直接按大尺寸输出TrueType字,那么不论字多大,“锯齿”大小是不变的(总是一个像元大)。而且,因为字越大笔画越粗,“锯齿”尺寸与笔画粗之比越小,所以在视觉上字越大“锯齿”却越不明显。

以上理解对吗?请指正。

#18


我也碰到类似问题。
不过我是处理多边形等图形。
比如使用windowsAPI画直线 (0,0)->(100,1),水平距离为1各像素,所以必然会在(50,0)(51,1)处产生锯齿。当然,使用GDI+可以避免这个情况,达到Photoshop通向效果,但是GDI+的效率太低了,根本不适合用在图形处理软件中(至少我在win2k下的测试结果如此).同时,我注意到ms 在officeXP中使用了画平滑线的技术(画个直线看看就知道了),而且我测试后发现比GDI+快很多,在officeXP目录中也没有gdiplus.dll,所以ms肯定使用了优化过的算法,真是卑鄙阿!!!
现在各位大虾和小弟都希望可以做出一个平滑算法,不如大家一起来努力如何?可以做一个封装好的类,方便自己,也方便大家。
至于算法,思路,还要靠大家帮忙拉!!!
如果有着方面的技术文档,例子,麻烦发到:harry202@163.com
如果有兴趣一起努力 ,加QQ:151586 发验证消息:"gdi"
完成后所有文档,代码会在csdn公布。

#19


patch:上面“水平距离为1各像素”改为"垂直距离为1各像素"

#20


sorry for late.

#21