Java Image Cut Off

时间:2012-01-04 02:25:42

标签: java image graphics rotation

与上次相同的问题,但我会提供更多细节。 我目前正在使用以下方式旋转图像:

 int rotateNum //in main class

 double rotationRequired = Math.toRadians(rotateNum);

    double locationX = img.getWidth(this) / 2;
    double locationY = img.getHeight(this) / 2;
    AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);


    g2d.drawImage(op.filter((BufferedImage)img, null), imgX, imgY, null);

然后我实际上是使用以下方式旋转图像:

double deltaX = (double)(imgY - otherImg.imgY);
double deltaY = (double)(imgX - otherImg.imgX);
rotateNum = (int)(180 * Math.atan2(deltaY, deltaX) / Math.PI);

我的图片大小不一。较小的图像不会被切断(意味着被白色空间切断),但较大的图像不会被切断(左侧或右侧)。调整图像大小不起作用,我使用了剪切图像周围的白色矩形  GIMP。

示例图片: 之前(忽略左边的灰色区域)

在: 看到侧面的截止点

3 个答案:

答案 0 :(得分:2)

我认为重要的不是图像的大小,而是它的偏心:更像方形的图像比较胖或更薄的图像没有问题。

我认为你的问题是你的旋转中心不应该是[宽度/ 2,高度/ 2] - 它并不那么简单。相反,考虑到位于大正方形左上部的图像,正方形边的长度将是图像的宽度或高度,以较大者为准。这是旋转图像时旋转的内容。

例如,请在此处查看我的回复:https://stackoverflow.com/a/8720123/522444

答案 1 :(得分:1)

这是java不幸的事情。解决这个问题的一种方法是使形状成为正方形,这样在旋转时不会发生削波。

大卫的“Java中的杀手游戏编程”一书中提到了这个问题,books_google_killer+game+programming+clipping+rotating如果您想要进行任何Java游戏编程,那么这本书是伟大的书籍(即使它是一个有点老了。

编辑::可以通过图像编辑软件或通过java本身将图像转换为正方形。也许滚动你自己的旋转方法,可以检查这种碰撞..

答案 2 :(得分:1)

旋转图像也可能会影响图像的大小。这是我很久以前在旧的Sun论坛上发现的一些代码(我忘了原版海报)。它重新计算以给定旋转角度显示图像所需的尺寸:

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import javax.imageio.*;
import javax.swing.*;

public class RotateImage {
    public static void main(String[] args) throws IOException {
        URL url = new URL("https://blogs.oracle.com/jag/resource/JagHeadshot-small.jpg");
        BufferedImage original = ImageIO.read(url);
        GraphicsConfiguration gc = getDefaultConfiguration();
        BufferedImage rotated1 = tilt(original, -Math.PI/2, gc);
        BufferedImage rotated2 = tilt(original, +Math.PI/4, gc);
        BufferedImage rotated3 = tilt(original, Math.PI, gc);
        display(original, rotated1, rotated2, rotated3);
    }

    public static BufferedImage tilt(BufferedImage image, double angle, GraphicsConfiguration gc) {
        double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
        int w = image.getWidth(), h = image.getHeight();
        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
        int transparency = image.getColorModel().getTransparency();
        System.out.println(transparency);
//        BufferedImage result = gc.createCompatibleImage(neww, newh, transparency);
        BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
        Graphics2D g = result.createGraphics();
        g.translate((neww-w)/2, (newh-h)/2);
        g.rotate(angle, w/2, h/2);
        g.drawRenderedImage(image, null);
        return result;
    }

    public static GraphicsConfiguration getDefaultConfiguration() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        return gd.getDefaultConfiguration();
    }

    public static void display(BufferedImage im1, BufferedImage im2, BufferedImage im3, BufferedImage im4) {
        JPanel cp = new JPanel(new GridLayout(2,2));
        addImage(cp, im1, "original");
        addImage(cp, im2, "rotate -PI/2");
        addImage(cp, im3, "rotate +PI/4");
        addImage(cp, im4, "rotate PI");

        JFrame f = new JFrame("RotateImage");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(cp);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    static void addImage(Container cp, BufferedImage im, String title) {
        JLabel lbl = new JLabel(new ImageIcon(im));
        lbl.setBorder(BorderFactory.createTitledBorder(title));
        cp.add(lbl);
    }
}