我有一些需要以编程方式将文本渲染到图像上的java代码。所以我使用BufferedImage,并在Graphics对象上写文本。
但是,在配置字体实例时,可以指定字体大小。当一段文本渲染到图像上时,AWT会根据Graphics对象的分辨率将这些点转换为像素。我不想让自己参与计算像素/点比率,因为它确实是AWT的任务。正在生成的图像用于高分辨率设备(高于任何桌面监视器)。
但是,我似乎没有找到一种方法来指定图形的分辨率。它从本地图形环境继承它,这是我无法控制的。我真的不希望这些代码依赖于本地的任何东西,我甚至不确定它是“理智的”,使用本地图形环境来确定屏幕外栅格的分辨率,谁知道人们会想要它们。
所以,我可以用任何方式为任何类型的屏幕外图像指定分辨率(最好是可以创建Graphics对象的图像,以便我可以使用标准的AWT渲染API)?
(更新) 这是一个(相当长的)示例问题,它在图像上呈现一段文本,预定义的字体大小为像素(实际上,目标设备DPI为72)。让我感到困惑的是,我必须使用本地屏幕DPI来计算字体大小,尽管我没有以任何方式使用屏幕,所以它不相关,并且无头系统上的普通故障。相反,在这种情况下我喜欢的是能够创建一个DPI为72的屏幕外图像(图形,光栅),这将使点数值等于像素。
运行代码的示例方式:
$ java FontDisplay Monospace 150 "Cat in a bag" 1.png
这将在150像素高的图像上呈现“猫袋信息”,字体大小为150像素,并将结果保存为1.png。
import java.awt.*;
import java.awt.image.*;
import java.awt.font.*;
import javax.imageio.*;
import javax.imageio.stream.*;
import java.io.*;
import java.util.*;
public class FontDisplay {
public static void main(String a[]) throws Exception {
// args: <font_name> <pixel_height> <text> <image_file>
// image file must have supported extension.
int height = Integer.parseInt(a[1]);
String text = a[2];
BufferedImage bi = new BufferedImage(1, 1,
BufferedImage.TYPE_INT_ARGB);
int dpi = Toolkit.getDefaultToolkit().getScreenResolution();
System.out.println("dpi : "+dpi);
float points = (float)height * 72.0F / (float)dpi;
System.out.println("points : "+points);
Map m = new HashMap();
m.put(TextAttribute.FAMILY, a[0]);
m.put(TextAttribute.SIZE, points);
Font f = Font.getFont(m);
if (f == null) {
throw new Exception("Font "+a[0]+" not found on your system");
}
Graphics2D g = bi.createGraphics();
FontMetrics fm = g.getFontMetrics(f);
int w = fm.charsWidth(text.toCharArray(), 0, text.length());
bi = new BufferedImage(w, height, BufferedImage.TYPE_INT_ARGB);
g = bi.createGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, w, height);
g.setColor(Color.WHITE);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g.setFont(f);
g.drawString(text, 0, fm.getMaxAscent());
String fName = a[3];
String ext = fName.substring(fName.lastIndexOf('.')+1).toLowerCase();
File file = new File(fName);
ImageWriter iw = ImageIO.getImageWritersBySuffix(ext).next();
ImageOutputStream ios = ImageIO.createImageOutputStream(file);
iw.setOutput(ios);
iw.write(bi);
ios.flush();
ios.close();
}
}
答案 0 :(得分:1)
将点与像素进行比较,就像 kg 到牛顿,其中加速可能会产生不同的转换。 AWT允许您选择一个设备(屏幕,打印机),但在您的情况下,您必须确定您的比率。
您当然可以使用Photoshop或Gimp并为java创建规范图像。
经过精心设计的问题:
啊,我想我看到了这个误会。图像仅涉及像素,不涉及点,mm,DPI等。 (有时仅作为元信息单独添加到图像中。)因此,如果你知道你的设备的DPI,你想要使用的英寸,那么点/像素是清晰的。 points/dpi可能会有更多的亮光。