我有一些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();
}
}
最佳答案
将像素点与像素进行比较,就像从公斤到牛顿,加速度可能会带来不同的转换。 AWT使您可以选择设备(屏幕,打印机),但是在您的情况下,您必须确定比例。
您当然可以使用Photoshop或Gimp并为Java创建标准图像。
经过阐述的问题:
嗯,我想我误会了。图像只涉及像素,从不涉及点,mm,DPI或其他。 (有时仅作为元信息单独添加到图像中。)
因此,如果您知道设备的DPI,要使用的英寸,则点/像素就清晰了。 points/dpi可能会更多。