java 提取轮廓_java – 以编程方式获取字体轮廓

这篇博客介绍了如何在Java中使用TextLayout和FontRenderContext将文本转换为形状,从而获取字体轮廓。通过PathIterator遍历形状路径,转换Bézier曲线,提取轮廓点。虽然示例基于Java,但提供了可能适用于Android开发的思路。
摘要由CSDN通过智能技术生成

由于我从未为Android设备开发过,我会给你这样做的方法,但是在Java中.

这是一些很好的库,但我不知道你是否可以使用它(C/C++)所以我会解释你如何自己做.

您应该首先使用TextLayout(您可以绘制的样式字符数据的不可变图形表示)在FontRenderContext中将您的单词转换为形状.

根据John J Smith的回答:https://stackoverflow.com/a/6864113/837765,应该可以在Android上使用类似于TextLayout的东西.但是,没有FontRenderContext的等效性.正如我所说,我从来没有为Android设备开发,但可能(我希望如此)一种解决方法来转换形状中的字符.

在Java中这样的东西应该工作(转换Shape中的文本):

public Shape getShape(String text, Font font, Point from) {

FontRenderContext context = new FontRenderContext(null, false, false);

GeneralPath shape = new GeneralPath();

TextLayout layout = new TextLayout(text, font, context);

Shape outline = layout.getOutline(null);

shape.append(outline, true);

return shape;

}

然后,你应该找到形状边界.这里不是很难,因为你的形状可以直接给你带有shape.getPathIterator(null)的路径迭代器

在每次迭代中,您可以获得当前段,its type和坐标:

> SEG_QUADTO:二次参数曲线;

> SEG_CUBICTO:三次参数曲线;

> SEG_LINETO:指定一条线的终点;

> SEG_MOVETO:指定新子路径的起始位置的点.

此时,您应该阅读Bézier曲线here和here.

你会了解到:

Any quadratic spline can be expressed as a cubic (where the cubic term

is zero). The end points of the cubic will be the same as the

quadratic’s.

CP0 = QP0 CP3 = QP2

The two control points for the cubic are:

CP1 = QP0 + 2/3 *(QP1-QP0) CP2 = CP1 + 1/3 *(QP2-QP0)

因此,从TrueType转换为PostScript是微不足道的.

在Java中这样的东西应该工作:

public List getPoints(Shape shape) {

List out = new ArrayList();

PathIterator iterator = shape.getPathIterator(null);

double[] coordinates = new double[6];

double x = 0, y = 0;

while (!iterator.isDone()) {

double x1 = coordinates[0];

double y1 = coordinates[1];

double x2 = coordinates[2];

double y2 = coordinates[3];

double x3 = coordinates[4];

double y3 = coordinates[5];

switch (iterator.currentSegment(coordinates)) {

case PathIterator.SEG_QUADTO:

x3 = x2;

y3 = y2;

x2 = x1 + 1 / 3f * (x2 - x1);

y2 = y1 + 1 / 3f * (y2 - y1);

x1 = x + 2 / 3f * (x1 - x);

y1 = y + 2 / 3f * (y1 - y);

out.add(new Point(x3, y3));

x = x3;

y = y3;

break;

case PathIterator.SEG_CUBICTO:

out.add(new Point(x3, y3));

x = x3;

y = y3;

break;

case PathIterator.SEG_LINETO:

out.add(new Point(x1, y1));

x = x1;

y = y1;

break;

case PathIterator.SEG_MOVETO:

out.add(new Point(x1, y1));

x = x1;

y = y1;

break;

}

iterator.next();

}

return out;

}

初始形状文本(在轮廓转换后):

形状上的点:

只有要点:

以及所有要点的输出:

(0.0,0.0)

(9.326171875,200.0)

(9.326171875,127.734375)

(0.0,0.0)

(50.7080078125,130.126953125)

(62.158203125,138.232421875)

(69.82421875,162.158203125)

(60.302734375,190.087890625)

(50.78125,200.0)

//...

我知道你不能在Android中使用Graphics2D(我在UI中使用它),但你应该能够将我的解决方案用于Android项目(我希望如此).

之后,您可以(在Bézier曲线的帮助下)重新创建曲线.

此外,还有其他一些好的工具.看看这一个:

它是在Javascript中,但也许它可以帮助你更多.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值