LINUX.ORG.RU

Graphics2D.drawString рендерит разные результаты на разных машинах

 , , , ,


0

2

Graphics2D.drawString без антиалиасинга даёт «попиксельно» разные результаты на разных машинах. С антиалиасингом так вообще разница огромная. Пример как рендерю текст:

import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;

public class Test {
    public static void main(String... args) throws FontFormatException, IOException {
        int x = 0;
        int y = 9;
        int width = 80;
        int height = 10;
        float fontSizeInPixels = 9f;
        String text = "PseudoText";

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);

        URL fontUrl = new URL(
                "https://github.com/indvd00m/graphics2d-drawstring-test/blob/master/src/test/resources/fonts/DejaVuSansMono/DejaVuSansMono.ttf?raw=true");
        Font font = Font.createFont(Font.TRUETYPE_FONT, fontUrl.openStream());
        font = font.deriveFont(fontSizeInPixels);

        Color fontColor = Color.BLACK;
        Color backgroundColor = Color.WHITE;

        graphics.setFont(font);
        graphics.setColor(backgroundColor);
        graphics.fillRect(0, 0, width, height);
        graphics.setColor(fontColor);
        graphics.drawString(text, x, y);

        ImageIO.write(image, "png", new File("/tmp/test.png"));
    }
}

Сделал проект для тестов:

https://github.com/indvd00m/graphics2d-drawstring-test

Вот пример сборки на TravisCI:

https://travis-ci.org/indvd00m/graphics2d-drawstring-test/builds/178672466

Из 7 конфигураций ОС/версия_явы на 2-х тест пройден, остальные провалились. Собственно и вопрос, можно ли это пофиксить и везде получать попиксельно одинаковый результат.

★★★★★

Последнее исправление: orm-i-auga (всего исправлений: 2)

Проверил ещё на одной машине, там и без A-A результат разный. Видимо дело действительно в фонте. У меня на этом валилось часть тестов, отключил их пока.

orm-i-auga ★★★★★
() автор топика

Стал разбираться. Шрифт теперь использую не логический а физический, он подключен к проекту, читается и используется напрямую из ресурсов и, соответственно, на всех платформах один и тот же. Однако результат всё равно разный. С А-А результат отличается сильно. Без — символы совпадают попиксельно, но расстояние между ними может отличаться на 1-2 пикселя.

orm-i-auga ★★★★★
() автор топика
Последнее исправление: orm-i-auga (всего исправлений: 1)

Отрендеренный текст я попиксельно перевожу в символы, чтобы вывести ASCII-артом.

Пример, как без А-А рендерится у меня:

                          █                                 
 ███                      █      █████                      
 █  █                     █        █               █        
 █  █ ████   ██  █  █   ███  ██    █    ██  █  █  ████      
 ███  █     █  █ █  █  █  █ █  █   █   █  █  ██    █        
 █     ███  ████ █  █  █  █ █  █   █   ████  ██    █        
 █       █  █    █  █  █  █ █  █   █   █     ██    █        
 █    ████   ███ ████   ███  ██    █    ███ █  █   ███      
И вот как то же самое рендерится в TravisCI:
                         █                                  
 ███                     █     █████                        
 █  █                    █       █              █           
 █  █ ████  ██  █  █   ███  ██   █    ██  █  █ ████         
 ███  █    █  █ █  █  █  █ █  █  █   █  █  ██   █           
 █     ███ ████ █  █  █  █ █  █  █   ████  ██   █           
 █       █ █    █  █  █  █ █  █  █   █     ██   █           
 █    ████  ███ ████   ███  ██   █    ███ █  █  ███         
Видно, что результат на 3 пикселя короче, чем у меня.

Антиалиасинг символьно имитирую 4-мя символами: ░▒▓█. С А-А у меня:

                          █                                 
 ███▒                     █      █████                      
 █ ░█                     █        █               █        
 █ ░█ ▒███  ░██▒ █  █  ▒█▓█ ▒██▒   █   ░██▒ ▓▒▒▓  ████      
 ███▒ █▒░   █▒░█ █  █  █▒▒█ █▒▒█   █   █▒░█ ░██░   █        
 █    ▒▓█▓  ████ █ ░█  █░░█ █░░█   █   ████  ██    █        
 █      ░█  █░░  █░▒█  █▒▒█ █▒▒█   █   █░░  ░██░   █░       
 █    ███▒  ░███ ▒█▓█  ▒█▓█ ▒██▒   █   ░███ ▓▒▒▓   ▓██      
В TravisCI:
░▓▓▒░                   ░▓     ▒▓▓▓▓░          ░░           
░█░▒█                   ▒▓     ░░█▒░░          ░▓           
░▓  █ ▓▓▓░ ▓▓▓░░▓ ░▓ ░▓▓▓▓ ▓▓█░  ▓░  ▓▓▓░░▓ ▒▓░▓█▓▒         
░█▒▓▓ █   ░▓ ░▓░▓ ░▓ ▒▓ ▒▓░▓ ░▓  ▓░ ░▓ ░▓ ▒▒▓░ ░▓           
░█▒▒░ ▒█▓░▒█▓▓▓░▓ ░▓ ▒▒ ▒▓▒▒ ░▓  ▓░ ▒█▓▓▓  █▒  ░▓           
░▓      ▒▓▒▓   ░▓ ▒▓ ▒▒ ▒▓▒▓ ░▓  ▓░ ▒▓    ▓▒█░ ░▓           
░▓   ░▓▓▓░ ▓▓▓▓ █▓▓▓ ░▓▓▓▓ ▓▓█░  ▓░  ▓▓▓▓▒▓ ░▓  ▓▓▒         
       ░░   ░░   ░     ░    ░░        ░░                    

orm-i-auga ★★★★★
() автор топика

Может от системных настроек отрисовки шрифтов зависит? Поставь везде одинаковые.

anonymous
()
Ответ на: комментарий от devorg

Такое чувство что на первом примере autohint выключен, а на втором включен.

Решил проверить и вручную удалил хинты из файла шрифта, результаты всё равно разные на разных машинах.

orm-i-auga ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Может от системных настроек отрисовки шрифтов зависит? Поставь везде одинаковые.

Я вот понятия не имею на каком уровне рендерятся шрифты, в яве это происходит или уходит в системное апи. Менять везде настройки не очень вариант, т.к. хотел решение чисто на яве.

orm-i-auga ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Да, читал там. Сейчас вообще выключил А-А чтобы хотя бы так добиться идентичности. Обновил стартовый пост.

orm-i-auga ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.