简体   繁体   English

java.awt中的屏幕外图形分辨率

[英]off screen graphics resolution in java.awt

I have some java code that needs to programmatically render text onto an image. 我有一些Java代码,需要以编程方式将文本渲染到图像上。 So I use BufferedImage, and write text on the Graphics object. 因此,我使用BufferedImage,并在Graphics对象上写文本。

However, when configuring the font instance, one would specify the font size in points. 但是,在配置字体实例时,将以磅为单位指定字体大小。 When a piece of text is rendered onto an image, AWT will translate the points into pixels, based on the resolution of the Graphics object. 将一段文本渲染到图像上时,AWT将根据Graphics对象的分辨率将这些点转换为像素。 I don't want to get myself involved in computing the pixel/point ratio, since it's really the task for the AWT. 我不想让自己参与像素/点比率的计算,因为这实际上是AWT的任务。 The image that is being produced is for a high resolution device (higher than any desktop monitors). 生成的图像适用于高分辨率设备(高于任何台式机显示器)。

But, I don't seem to find a way to specify what the resolution of the Graphics is. 但是,我似乎没有找到指定图形分辨率的方法。 It inherits it from the local graphics environment, which is beyond my control. 它是从本地图形环境继承的,这是我无法控制的。 I don't really want this code to be dependent on anything local, and I'm not even sure it's "sane", to use local graphics environment for determining the resolution of off screen rasters, who knows what people would want them for. 我真的不希望此代码依赖于任何本地代码,而且甚至不确定使用本地图形环境确定屏幕外栅格的分辨率是否“明智”,后者知道人们想要它们的作用。

So, any way I can specify the resolution for an off screen image of any kind (preferably the one that can create Graphics object so I can use standard AWT rendering API)? 因此,可以通过任何方式为任何类型的屏幕外图像指定分辨率(最好是可以创建Graphics对象以便可以使用标准AWT渲染API的分辨率)?

(update) Here is a (rather long) sample problem that renders a piece of text on an image, with predefined font size in pixels (effectively, the target device DPI is 72). (更新)这是一个(相当长的)样本问题,该问题以预定的字体大小(以像素为单位)在图像上渲染一段文本(有效,目标设备的DPI为72)。 What bugs me, is that I have to use local screen DPI to make the calculation of the font size in points, though I'm not using the screen in any way, so it's not relevant, and plain fails on headless systems all together. 让我感到烦恼的是,尽管我没有以任何方式使用屏幕,但我必须使用本地屏幕DPI来计算字体大小(以磅为单位),因此这无关紧要,并且在无头系统上全部失败。 What I would loved in this case instead, is being able to create an off screen image (graphics, raster), with DPI of 72, which would make points, by value, be equal to pixels. 在这种情况下,我更喜欢的是能够创建DPI为72的屏幕外图像(图形,光栅),这将使点的值等于像素。

Sample way to run the code: 运行代码的示例方法:

$ java FontDisplay Monospace 150 "Cat in a bag" 1.png

This would render "Cat in a bag message", with font size of 150 pixels, on a 150 pixel tall image, and save the result in 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();

    }

}

Comparing points to pixels is like kg to Newton where the acceleration may give varying conversions. 像素 像素进行比较,就像从公斤牛顿 ,加速度可能会带来不同的转换。 AWT lets you elect a device (screen, printer), but in your case you definitely have to determine your ratio. AWT使您可以选择设备(屏幕,打印机),但是在您的情况下,您必须确定比例。

You may of course use Photoshop or Gimp and create a normative image for java. 您当然可以使用Photoshop或Gimp并为Java创建标准图像。


After elaborated question: 经过阐述的问题:

Ah, I think I see the misunderstanding. 嗯,我想我误会了。 An image does only concern pixels, never points, mm, DPI, or whatever. 图像只涉及像素,从不涉及点,mm,DPI或其他。 (Sometimes only as metainfo added separately to the image.) (有时仅作为元信息单独添加到图像中。)

So if you know the DPI of your device, the inches you want to use, then the dots/pixels are clear. 因此,如果您知道设备的DPI,要使用的英寸,则点/像素就清晰了。 points/dpi may shed more light. 点/ dpi可能会照亮更多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM