Как добиться четких результатов рисования при повороте B ufferedImage?

Одна попытка заключалась в использовании TexturePaint и g.fillRect () ], чтобы раскрасить изображение. Однако это требует, чтобы вы создавали новые объекты TexturePaint и Rectangle2D каждый раз, когда рисуете изображение, что не идеально - и в любом случае не помогает.

Когда я использую g.drawImage (BufferedImage, ... ) , повернутые изображения кажутся размытыми / мягкими.

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

Код для использования TexturePaint выглядит примерно так.

Grahics2D g2d = (Graphics2D)g; 
g2d.setPaint(new TexturePaint(bufferedImage, new Rectangle2D.Float(0,0,50,50)));
g2d.fillRect(0,0,50,50);

Я использую AffineTransform , чтобы повернуть руку с карточками в веер. Как лучше всего быстро рисовать красивые изображения?

Вот скриншот:
Example of blurred rotations
Девятка четкая, но остальные карты определенно не такие резкие.

Возможно, что картинка Проблема заключается в том, что я создаю каждое изображение карты и сохраняю его в массиве.
Вот как я это делаю сейчас:

// i from 0 to 52, card codes.
...
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
BufferedImage img = gc.createCompatibleImage(86, 126, Transparency.TRANSLUCENT);

    Graphics2D g = img.createGraphics();
    setRenderingHints(g);
    g.drawImage(shadow, 0, 0, 86, 126, null);
    g.drawImage(white, 3, 3, 80, 120, null);
    g.drawImage(suit, 3, 3, 80, 120, null);
    g.drawImage(value, 3, 3, 80, 120, null);
    g.dispose();

    cardImages[i] = img;
}

private void setRenderingHints(Graphics2D g){
    g.setRenderingHint(KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g.setRenderingHint(KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
}

Как мне подойти к этому по-другому? Спасибо.

Edit:
Example of hand without RenderingHints
Without RenderingHints

Установка подсказок AA не имеет значения. Кроме того, установка RenderingHints при создании изображений также не имеет значения. Только когда они вращаются с помощью AffineTransform и раскрашиваются с помощью g.drawImage (...) , они кажутся размытыми.
На изображении выше показана разница между интерполяцией по умолчанию (ближайший сосед) и билинейной интерполяцией.

Вот как я их сейчас раскрашиваю (намного быстрее, чем TexturePaint):

// GamePanel.java
private void paintCard(Graphics2D g, int code, int x, int y){
    g.drawImage(imageLoader.getCard(code), x, y, 86, 126, null);
  }

// ImageLoader.java
public BufferedImage getCard(int code){
    return cardImages[code];
  }

Все мои карты 80x120 и тень. png имеет размер 86x126, чтобы вокруг карты оставалась полупрозрачная тень размером 3 пикселя. Я знаю, что это нереальная тень, но она выглядит нормально.

Итак, возникает вопрос ... Как можно добиться четких результатов рисования при повороте BufferedImage?

Ссылка на предыдущий вопрос, также касающийся рука с веерными карточками:
Как вы можете обнаружить событие щелчка мыши на объекте Image в Java?

Bounty-Edit: Итак, после долгого обсуждения я сделал несколько тестовых карточек .svg, чтобы увидеть, как SVG Salamander будет их рендерить. К сожалению, производительность ужасная. Моя реализация достаточно чистая, поскольку с помощью BufferedImage с двойной буферизацией рисование было невероятно быстрым. Это означает, что я прошел полный круг и вернулся к своей исходной проблеме.

Я дам 50 наград тому, кто может дать мне решение для получения резких вращений BufferedImage. Предлагалось сделать изображения больше, чем они должны быть, и уменьшить их перед рисованием, а также использовать бикубическую интерполяцию. Если это единственно возможные решения, то я действительно не знаю, куда идти дальше, и мне, возможно, придется иметь дело с размытыми поворотами - потому что оба они приводят к снижению производительности.

Я могу закончить свою игру, если я может найти способ сделать это хорошо. Спасибо всем. :)

25
задан 21 revs, 2 users 97% 23 May 2017 в 12:18
поделиться