Подтвердить что ты не робот

Как я могу наследовать настройку анти-алиаса системы для рисования текста для изображений вне экрана, например, качели?

Когда я запускаю свои графические приложения swing под Java 6, они автоматически используют настроенные параметры под-пикселя для всех псевдонимов. Результат значительно улучшился по сравнению со стандартными вариантами AA.

Но когда я рисую изображение, я не могу найти способ инициализировать графический контекст для использования конфигурации системы AA. Попытка поиграть с Java различными подсказками AA является потерянной причиной, потому что никакой субпиксельный метод не будет работать для всех пользователей.

Есть ли способ наследовать настройки системы AA для заданного графического контекста вместо того, чтобы выбирать один и явно устанавливать подсказку? В настоящий момент я должен использовать GASP AA, чтобы избежать ужасных результатов, которые дает стандартный AA с небольшими шрифтами. Я пробовал ничего не устанавливать для текста AA, и вообще не устанавливал никаких намеков AA.


Обновление 2010-01-05

Я думаю, что я приписал это; подсказки субпикселя AA, по-видимому, соблюдаются только при прямолинейном рисовании графического контекста AWT; когда я рисую на изображение с двойным буфером, он просто делает стандартный АА; но когда я обходит изображение с двойным буфером, выполняется субпиксель А.

В противном случае ответ "The_Fire" будет работать в JVM, у которых есть Swing (но не J2ME JVM); Обратите внимание, что ответ "The_Fire" не работает с использованием компонента AWT (с использованием нового Label() вместо нового JLabel()), по-видимому, потому что FontRenderContext не может быть извлечен до тех пор, пока компонент не будет реализован на дисплее.


Мой текущий код, чтобы получить графический контекст для моего целевого изображения, теперь выглядит следующим образом:

try {
    if((dbImage=dctRoot.createImage(wid,hgt,1))!=null) {            // if createImage returns null or throws an exception the component is not yet displayable
        dbGraphics=(Graphics2D)dbImage.getGraphics();
        if(dctRoot.properties.getBoolean("Antialias",true)) {
            try {
                // set AA on overall
                dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING     ,RenderingHints.VALUE_ANTIALIAS_ON);
                // set text AA to platform/impl default
                dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
                // try to override platform/impl AA with font-specified AA (Java 6+)
                try { dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.class.getField("VALUE_TEXT_ANTIALIAS_GASP").get(null)); } catch(Throwable thr) {;} // yes, ignore exception
                }
            catch(Throwable thr) {
                dctRoot.log.println("Antialiasing not supported on this JVM ("+thr+").");
                dctRoot.setProperty("Antialias","False");           // turn off AA for subsequent painting
                }
            }
        }
    }
catch(Throwable thr) {
    dbImage=null;
    dbGraphics=null;
    }

В коде для создания изображения используется базовый компонент AWT, который формирует фон, на котором я выполняю всю мою картину - компонент является панелью, потому что мне нужно иметь возможность делать setFocusCycleRoot, чтобы он хорошо работал с другим AWT компоненты. Создайте код изображения:

public DctImage createImage(int wid, int hgt, float accpty) {
    GraphicsConfiguration               cfg=awtComponent.getGraphicsConfiguration();
    Image                               img=null;

    if(transparentImages) {
        //y { img=new BufferedImage(wid,hgt,BufferedImage.TYPE_INT_ARGB); }     // NB: J2ME CDC/PP 1.1 does not have the BufferedImage constructors (one day I may discover a way to create a BufferedImage via another API!!)
        try { img=cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT); }// NB: J2ME CDC/PP 1.1 does not have this API, but prefer to use GraphicsConfiguration over new BufferImage(...)
        catch(NoClassDefFoundError   thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        catch(NoSuchMethodError      thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        catch(NoSuchFieldError       thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        }
    else {
        img=cfg.createCompatibleImage(wid,hgt);
        }

    if(accpty>0 && SET_ACCELERATION_PRIORITY!=null) {
        try { SET_ACCELERATION_PRIORITY.invoke(img,new Object[]{new Float(accpty)}); } catch(Throwable thr) {;}
        }

    return (img==null ? null : new DctImage(img));
    }
4b9b3361

Ответ 1

Я обнаружил, что здесь есть несколько факторов.

Во-первых, изображение должно быть создано из основного компонента AWT и должно быть создано без прозрачности:

cfg.createCompatibleImage(wid,hgt);

вместо

cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT);

Во-вторых, по какой-то необъяснимой причине первичная настройка АА, KEY_ANTIALIASING, должна быть отключена, чтобы использовать субпиксель АА LCD.

Наконец, и самое главное, подсказки рендеринга шрифтов для рабочего стола легко извлекаются с помощью:

java.awt.Toolkit.getDesktopProperty("awt.font.desktophints")

Обновление 2010-01-05

Повторная проверка в Java 6.26, похоже, проблема с необходимостью установки общего AA для рендеринга текста AA, наконец, была решена (путь к Oracle... после того, как Sun был всего лишь несколько лет десятилетие слишком поздно).

Ответ 2

Используя Swing, я могу получить подсказку сглаживания правильного текста следующим образом:

JLabel label = new JLabel();
FontMetrics fm  = label.getFontMetrics( label.getFont() );
Object aaHintValue = fm.getFontRenderContext().getAntiAliasingHint();

В моей системе это возвращает RenderingHits.VALUE_TEXT_ANTIALIAS_LCD_HRGB.

Ответ 3

java.awt.Toolkit.getDesktopProperty( "awt.font.desktophints" ), по-видимому, имеет значение null для linux, по крайней мере, без каких-либо специальных параметров командной строки vm, по-видимому, потому, что он не может понять, что такое по умолчанию платформы. добавление, например, "-Dawt.useSystemAAFontSettings = lcd", похоже, вылечивает его и включает субпиксельную визуализацию, если вы задаете подсказки на вашем экземпляре Graphics2D.

Ответ 4

Подождите, вы используете этот код в JVM для Windows? Я думал, что ClearType - это технология Microsoft, которую Swing наследует через собственный код (т.е. Недоступен на Linux или других платформах, отличных от Microsoft).

Я однажды написал сервлет, который сгенерировал JPG с анти-псевдонимами, которые запускались на Debian, и это был код, который я использовал

Font font = new Font("Komix", Font.PLAIN, 8);
Graphics2D g2;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
FontRenderContext  frc = g2.getFontRenderContext();
g2.setFont(font);
g2.setPaint(Color.black);
g2.drawString(sMessage, xOffset, yOffset);

Оффлайн Я не могу вспомнить, использует ли какой-либо из этого кода Swing (я импортировал javax.swing и сервлет длиной около 300 строк, поэтому, возможно, я думал, что это нужно для чего-то другого), быстрая проверка на Google похоже, что это прямо в пространстве AWT. Надеюсь, что это поможет.