Один из попыток - использовать 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
для поворота руки карт в вентилятор.
Каким будет лучший подход к быстрому рисованию хороших изображений?
Вот скриншот:
9 - хрустящий, но остальные карты определенно не такие острые.
Возможно, проблема заключается в том, что я создаю каждое изображение карты и сохраняю ее в массиве.
Как я это делаю сейчас:
// 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:
Без 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, чтобы оставить полупрозрачную тень размером 3px вокруг карты. Это не реальная тень, которую я знаю, но все выглядит нормально.
И вот вопрос... Как вы можете получить резкие результаты краски при вращении BufferedImage?
Ссылка на предыдущий вопрос также относительно руки раздутой карты:
Как вы можете обнаружить событие мыши в объекте Image в Java?
Баунти-Edit: Хорошо, поэтому после долгих обсуждений я сделал несколько тестовых карт .svg, чтобы посмотреть, как SVG Salamander будет заниматься их рендерингом. К сожалению, производительность ужасная. Моя реализация достаточно чистая, так как с буферизацией BufferedImage с двойной буферизацией картина была невероятно быстрой. Это означает, что я пришел в полный круг, и я вернулся к своей первоначальной проблеме.
Я дам 50 бонусов тому, кто может дать мне решение, чтобы получить резкие вращения BufferedImage. Предложения заключались в том, чтобы сделать изображения более крупными, чем они должны быть и уменьшены до рисования, и использовать бикубическую интерполяцию. Если это единственные возможные решения, то я действительно не знаю, куда идти отсюда, и мне просто нужно иметь дело с размытыми вращениями - потому что оба из них налагают неудачи производительности.
Я могу закончить игру, если найду способ сделать это хорошо. Спасибо всем.:)