разрешение экрана вне экрана в java.awt - PullRequest
2 голосов
/ 16 марта 2012

У меня есть некоторый Java-код, который должен программно отображать текст на изображении. Поэтому я использую BufferedImage и пишу текст на объекте Graphics.

Однако при настройке экземпляра шрифта размер шрифта указывается в пунктах. Когда фрагмент текста отображается на изображении, AWT преобразует точки в пиксели в зависимости от разрешения объекта Graphics. Я не хочу вовлекаться в вычисление отношения пиксель / точка, так как это действительно задача для AWT. Изображение, которое создается для устройства с высоким разрешением (выше, чем у любых настольных мониторов).

Но, похоже, я не могу найти способ указать разрешение графики. Он наследует его от локальной графической среды, которая находится вне моего контроля. Я не хочу, чтобы этот код зависел от чего-то локального, и я даже не уверен, что это «нормально» - использовать локальную графическую среду для определения разрешения внеэкранных растров, которые знают, для чего они нужны людям.

Итак, каким-либо образом я могу указать разрешение для изображения вне экрана любого типа (предпочтительно того, которое может создавать графический объект, чтобы я мог использовать стандартный API рендеринга AWT)?

(обновление) Вот примерная (довольно длинная) проблема, которая визуализирует фрагмент текста на изображении с предопределенным размером шрифта в пикселей (фактически, 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();

    }

}

1 Ответ

1 голос
/ 16 марта 2012

Сравнение точек с пикселей похоже на кг с Ньютон , где ускорение может давать различные преобразования. AWT позволяет вам выбрать устройство (экран, принтер), но в вашем случае вам обязательно нужно определить свой коэффициент.

Конечно, вы можете использовать Photoshop или Gimp и создать нормативное изображение для Java.


После уточненного вопроса:

Ах, я думаю, что вижу недоразумение. Изображение касается только пикселей, а не точек, мм, точек на дюйм или чего-либо еще. (иногда только как метаинфо, добавляемое отдельно к изображению.)

Так что если вы знаете DPI вашего устройства, дюймы, которые вы хотите использовать, то точки / пиксели будут четкими. точек / точек на дюйм может пролить больше света.

...