У меня есть эта программа:Java Graphics.fillXxx() в сочетании с Graphics2D.scale()
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class TestLine {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestLine().start();
}
});
}
private static void start() {
JFrame frame = new JFrame();
frame.setContentPane(new CarthPanel());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static class CarthPanel extends JComponent {
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D gg = (Graphics2D) g;
int w = gg.getClipBounds().width;
int h = gg.getClipBounds().height;
System.out.println("(w,h)=(" + w + "," + h + ")");
gg.translate(w - 1, 0); // <<< when uncommenting both lines, mirroring applies
gg.scale(-1.0, 1.0); //
paintTest(gg, w, h);
}
private static void paintTest(Graphics2D g, int w, int h) {
// black background
g.setColor(Color.black);
g.fillRect(0, 0, w, h);
// colored corners
g.setColor(Color.RED);
g.drawLine(0, 0, 10, 0);
g.drawLine(0, 0, 0, 10);
g.setColor(Color.RED);
g.drawLine(0, 199, 10, 199);
g.drawLine(0, 199, 0, 189);
g.setColor(Color.CYAN);
g.drawLine(189, 0, 199, 0);
g.drawLine(199, 0, 199, 10);
g.setColor(Color.CYAN);
g.drawLine(189, 199, 199, 199);
g.drawLine(199, 199, 199, 189);
// yellow squares
g.setColor(Color.yellow);
g.drawRect(3, 3, 10, 10);
g.fillRect(186, 3, 11, 11);
g.fillRect(3, 186, 11, 11);
g.drawRect(186, 186, 10, 10);
String chars = "ABC";
g.setFont(Font.decode("Arial 72"));
Rectangle2D rect = g.getFontMetrics().getStringBounds(chars, g);
g.drawString(chars, (int) (200 - rect.getWidth())/2, (int) (200 - rect.getHeight()));
}
}
}
Если запустить эту программу один раз с двумя конкретными линиями комментируемых в и затем один раз с теми же линиями закомментирована (см код), то вы получите, чтобы увидеть это:
[
Если вы не заметили эту проблему, вот увеличенное рис:
Можно было бы ожидать, что изображение будет полностью зеркальным. Это справедливо для всех штрихов и полых форм (= drawXxx()). Однако все заполненные фигуры (= методы fillXxx()) выводятся ровно на один пиксель слева от того, где я их ожидаю; например заполненные желтые прямоугольники, и вы также можете заметить, что черный фон сдвинулся, как видно по белой линии на правой границе.
Является ли это ошибкой или это предназначено? Я подозреваю, что у него есть что-то делать с той разницей, как «ширина» и «высота» в настоящее время обрабатываются в drawXxx() и fillXxx() методы:
- DrawRect (х, у, ш, ч) приводит к полый прямоугольник с X-осями границ x и x + w, поэтому прямоугольник имеет ширину w + 1 пиксель.
- fillRect (x, y, w, h) приводит к заполненному прямоугольнику с границами x и x + w-1, поэтому прямоугольник имеет ширину w пикселей.
Что мне не хватает?
Что вы имеете в виду, «все drawXXX ошибочны»? Из моих тестов ясно, что заполненные фигуры сдвинуты, а не очерченные фигуры. Вы правы, что графический контекст BufferedImage работает! Так что это должно быть ошибкой в графическом контексте Java-компонента. – Timmos
Я думаю, что ваш пример почти прав, 'g.drawImage (img, 0, 0, null);' должен быть 'gg.drawImage (img, 0, 0, null);'. – Timmos
Я думаю, что ваш ответ не совсем правильный.Всякий раз, когда вы берете графический контекст из BufferedImage, а затем масштабируете/переводите его, методы fillXxx() также приводят к сдвигам пикселей. В вашем примере вы напрямую нарисовали все на BufferedImage (без каких-либо преобразований), а затем масштабировали/переводили всю вещь за один раз при рисовании изображения на графический объект Java Component. Это действительно работает, но ваше предположение о том, что это связано с самим графическим контекстом, неверно: ошибка возникает всякий раз, когда вы рисуете масштабированный/переведенный контекст. DrawXxx() сдвигается в пикселях. – Timmos