【发布时间】:2021-09-10 01:23:17
【问题描述】:
动机
我正在尝试使用imageproc 在Image 上呈现动态长度的String。
问题
我需要一种方法或函数来计算文本在使用特定Font 和Scale 渲染时的宽度,以使文本在图像上居中。
附加说明
rusttype是imageproc使用的字体库。
【问题讨论】:
标签: image image-processing rust fonts
我正在尝试使用imageproc 在Image 上呈现动态长度的String。
我需要一种方法或函数来计算文本在使用特定Font 和Scale 渲染时的宽度,以使文本在图像上居中。
rusttype是imageproc使用的字体库。
【问题讨论】:
标签: image image-processing rust fonts
rusttype 存储库包含一个示例 (examples/image.rs),它测量一行文本的边界并将其呈现为图像。 除了居中部分之外,基本上你正在搜索的内容。
// rusttype = "0.9.2"
use rusttype::{point, Font, Scale};
let v_metrics = font.v_metrics(scale);
let glyphs: Vec<_> = font.layout(text, scale, point(0.0, 0.0)).collect();
let glyphs_height = (v_metrics.ascent - v_metrics.descent).ceil() as u32;
let glyphs_width = {
let min_x = glyphs
.first()
.map(|g| g.pixel_bounding_box().unwrap().min.x)
.unwrap();
let max_x = glyphs
.last()
.map(|g| g.pixel_bounding_box().unwrap().max.x)
.unwrap();
(max_x - min_x) as u32
};
我不喜欢总是需要收集到Vec,同时还需要使用非整数大小。所以在过去,我在示例中创建了自己的版本本质上。
一个重要的注意事项是,当您只需要大小时,传递给布局的位置真的并不重要。但是,如果您确实需要渲染字形,则位置很重要,否则结果将包含锯齿伪影。
// rusttype = "0.9.2"
use rusttype::{point, Font, Scale};
fn measure_line(font: &Font, text: &str, scale: Scale) -> (f32, f32) {
let width = font
.layout(text, scale, point(0.0, 0.0))
.map(|g| g.position().x + g.unpositioned().h_metrics().advance_width)
.last()
.unwrap_or(0.0);
let v_metrics = font.v_metrics(scale);
let height = v_metrics.ascent - v_metrics.descent + v_metrics.line_gap;
(width, height)
}
如果文本有多行,那么您需要手动在字符串上使用.lines(),然后将行高和行间距相加。
【讨论】:
.last() 移动到一个队列即可提高大型字符串的性能。