Java: вращение буферизованного изображения вокруг его центра перекошено - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь повернуть буферизованное изображение в Java (значок плоскости на карте) вокруг его центра, используя справку отсюда: Вращение экземпляров BufferedImage

Когда я использую этот код:

AffineTransform at = new AffineTransform();

at.rotate(Math.toRadians(planeHeading),origImage.getWidth() / 2, origImage.getHeight() / 2);

AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

origImage = op.filter(origImage, null);

g.drawImage(origImage, x-origImage.getWidth() / 2, y-origImage.getHeight() / 2, null);

при повороте на 180-270 градусов, изображение располагается выше и немного левее его центра:

enter image description here

Если я использую этот код:

AffineTransform at = new AffineTransform();

at.translate(x, y);

at.rotate(Math.toRadians(planeHeading));

at.translate(-origImage.getWidth()/2, -origImage.getHeight()/2);

g.drawImage(origImage, at, null);

изображение поворачивается правильно, однако само изображение становится очень пикселированным по краям.

enter image description here

Может кто-нибудь помочь найти виновника?

Это весь метод:

@Override
public void paintWaypoint(Graphics2D g, JXMapViewer viewer, MapPlane w)
{
    g = (Graphics2D)g.create();

    try
    {
        origImage = ImageIO.read(getClass().getResource("/images/map/mapPLANE.png"));

        Point2D point = viewer.getTileFactory().geoToPixel(w.getPosition(), viewer.getZoom());

        // Center coordinates
        int x = (int)point.getX();
        int y = (int)point.getY();

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // Get heading of the plane and rotate the image
        String planeHeadingStr = w.getHeading();

        try
        {
            double planeHeading = Double.parseDouble(planeHeadingStr);

            AffineTransform at = new AffineTransform();

            //Do the actual rotation
            at.rotate(Math.toRadians(planeHeading),origImage.getWidth() / 2, origImage.getHeight() / 2);
            AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
            origImage = op.filter(origImage, null);

            // Draw the image
            g.drawImage(origImage, x-origImage.getWidth() / 2, y-origImage.getHeight() / 2, null);

        }
        catch(NumberFormatException e)
        {

        }


        g.dispose();

    }
    catch (Exception ex)
    {
        log.warn("couldn't read mapPLANE.png", ex);
    }

}

Спасибо большое!

1 Ответ

0 голосов
/ 12 июня 2018

Чтобы добиться той же билинейной интерполяции, которую вы получили для вашего AffineTransformOp во втором случае, когда вы рисуете напрямую, используя AffineTransform, вы должны установить другой RenderingHint:

g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
                   RenderingHints.VALUE_INTERPOLATION_BILINEAR);

В противном случае, в вашемв этом случае по умолчанию используется интерполяция NEAREST_NEIGHBOUR.

...