这是this question的后续行动。
我正在开发一个低级别的C应用程序,我必须在其中绘制文本。我决定存储我想用作数组的字体(黑色和白色,每个char 128x256,也许),然后我用一些算法将它缩小到我需要的尺寸(作为灰度,所以我可以有一些原油字体平滑)。
注意:这是一个玩具项目,请忽略诸如在运行时进行计算之类的事情。
问题是,哪种算法?
我抬头2xSaI
,但它相当复杂。我想要一些我可以阅读描述并自己编写代码的东西(我是一名初学者,并且已经用C / C ++编写了不到一年的时间)。
建议,有人吗?
谢谢你的时间!
编辑:请注意,输入为B& W,输出应平滑灰度
答案 0 :(得分:4)
找出源图像中与目标像素对应的矩形。例如,如果源图像为50x100且目标为20x40,则目标中的左上角像素对应于源图像中从(0,0)到(2.2,2.2)的矩形。现在,对这些像素进行面积平均值:
这个很简单,因为您开始在图像边缘均匀排列源和目标像素。通常,您将在滑动矩形的所有4个边/ 4个角上进行部分覆盖。
不要使用区域平均以外的算法来减小尺寸。它们中的大多数都是普通的错误的(它们导致可怕的混叠,至少有一个小于1/2的因素)而且那些不是完全错误的那些实现起来有点麻烦,可能不会给你更好的结果。
答案 1 :(得分:3)
考虑您的图像是N * M BW位图。为简单起见,当允许值为char Letter[N][M]
和0
时,我们会将其视为1
。现在考虑要将其缩减到unsigned char letter[n][m]
。这意味着来自letter
的每个灰度像素将被计算为大位图中的白色像素数:
char Letter[N][M];
unsigned char letter[n][m];
int rect_sz_X = N / n; // the size of rectangle that will map to a single pixel
int rect_sz_Y = M / m; // in the downscaled image
int i, j, x, y;
for (i = 0; i < n; i++) for (j = 0; j < m; j++){
int sum = 0;
for (x = 0; x < rect_sz_X; x++) for (y = 0; y < rect_sz_Y; y++)
sum += Letter[i*rect_sz_X + x][j*rect_sz_Y + y];
letter[n][m] = ( sum * 255) / (rect_sz_X * rect_sz_Y);
};
请注意,创建像素的矩形可能会重叠(如果大小不可分割)。原始位图越大越好。
答案 2 :(得分:2)
缩放位图字体与缩放任何其他位图的问题相同。您所追求的一般算法类是插值。有很多方法可以做到这一点 - 通常,结果在视觉上越精确,算法就越复杂。您可以从查看(按复杂程度递增的顺序)开始:
答案 3 :(得分:1)
这很简单。如果你所拥有的只是一个位图字体而不是轮廓字体,那么你在选择抗锯齿像素颜色方面的选择非常有限。例如,如果位图字体点大小恰好是所需显示点大小的四倍,那么您只能获得16个不同的选择。 4x4映射矩形中“点亮”像素的数量。
必须处理分数映射是一项编程练习,但不能提高质量。
答案 4 :(得分:0)
如果将降尺度约束为2的倍数(50%,25%,12.5%等)是可以接受的,那么一个非常简单且相当不错的算法就是创建每个缩小的像素作为所有的缩小投票。源像素。例如,在50%时,四个像素的正方形形成一个缩小的像素:如果它们中的一个或一个打开,则输出关闭;如果打开三个或四个,则输出打开。艺术案例(两个像素开启),要么总是选择开启,要么关闭,或者看其他周围的像素进行抢夺。