java - java中使用java.awt.Graphics2D的变形图像

标签 java image swing graphics java-2d

我有这样的图像:

Original image

我需要将其变形为这样的图像:

Deformed image

我尝试了很多代码,但没有解决。这是我最后一次尝试,但最终图像看起来不太好

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

class MyPanel2 extends JPanel {

    private final static double DEG_TO_RAD = Math.PI / 360;

    private BufferedImage imageA;
    private BufferedImage imageB;

    static String IMG_URL1 = "img/upg.png";

    public MyPanel2() {

        try {
            imageA = ImageIO.read(new File(IMG_URL1));
        } catch (IOException e) {
            System.err.println("Couldn't find input file. ");
            System.exit(1);
        }

        double rotationRequired = Math.toRadians(90);
        double locationX = imageA.getWidth() / 2;
        double locationY = imageA.getHeight() / 2;
        AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
        AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);

        BufferedImage pom_2 = imageA;
        imageA = new BufferedImage(imageA.getWidth(), imageA.getHeight(), BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2 = imageA.createGraphics();
        g2.setStroke(new BasicStroke(5));
        g2.setColor(Color.BLACK);

        g2.drawImage(op.filter(pom_2, null),10,10, null);

        BufferedImage pom = new BufferedImage(imageA.getWidth()*2, imageA.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g3 = pom.createGraphics();
        g3.setColor(Color.white);
        g3.drawImage(imageA, imageA.getWidth()/5, 0, null);
        imageA = pom;

        imageB = new BufferedImage(imageA.getWidth(), imageA.getWidth(), BufferedImage.TYPE_INT_ARGB);
        // pruchod obrazkem pixel po pixelu
        for (int i = imageB.getWidth(); i > 0; i--) {
            for (int j = imageB.getHeight(); j > 0; j--) {
                int r = (int) (Math.sqrt(i * i + j *j));
                int fi = (int) (Math.atan2(j, i) / DEG_TO_RAD);

                if (r < pom.getWidth() && fi < pom.getHeight()) {
                    imageB.setRGB(i, j, pom.getRGB(r, fi));
                }
            }
        }

        this.setPreferredSize(new Dimension(800, 600));

        imageA = pom_2;
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D)g;

        g2.drawImage(imageA,0,0, null);


        double rotationRequired = Math.toRadians(-135);
        double locationX = imageB.getWidth() / 2;
        double locationY = imageB.getHeight() / 2;
        AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
        AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);

        g2.drawImage(op.filter(imageB, null), 0, -imageB.getHeight()/2, null);
    }
}

使用此代码,最终图像如下所示: final image

最佳答案

我发布了我的解决方案。也许它不优雅,但它有效:

My result

class MyPanel2 extends JPanel {

    private BufferedImage imageA;
    private BufferedImage imageB;
    private double k = 3.0;

    String IMG_URL1 = "img/upg.png";

    public MyPanel2() {

        try {
            imageA = ImageIO.read(new File(IMG_URL1));
        } catch (IOException e) {
            System.err.println("Couldn't find input file. ");
            System.exit(1);
        }

        double radius = k*imageA.getHeight();
        int xC = (int)radius, yC = (int)radius; 
        imageB = new BufferedImage(xC*2,yC, BufferedImage.TYPE_INT_ARGB);

        double r, i, j;
        for(int y = 0; y < imageB.getHeight(); y++) {
            for (int x = 0; x < imageB.getWidth(); x++) {
                r = Math.sqrt((xC-x)*(xC-x)+(yC-y)*(yC-y));
                i = (radius-r);
                j = (-k*imageA.getWidth()/2*(xC-x))/r + imageA.getWidth()/2;
                if (i>=0 && i < imageA.getHeight() && j>=0 && j < imageA.getWidth()) {
                    imageB.setRGB(x, y, imageA.getRGB((int)j, (int)i));
                }
            }
        }
        this.setPreferredSize(new Dimension(800, 600));
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.drawImage(imageA, 0, 0, null);
        g2.drawImage(imageB, -imageA.getWidth(), 0, null);
    }
}

关于java - java中使用java.awt.Graphics2D的变形图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15746337/

相关文章:

java - 如何将oracle jdbc驱动程序依赖添加到JIRA插件?

java - 将日历日期转换为字符串?

java - 是否可以让 BitmapFactory.decodeFile() 尊重 EXIF?

java - Swing JDialog 的内容 Pane 在执行幻灯片时未更新

java - 如何在 JLabel 中的文本前添加空格?

java - 如何在 JTable 中选择一行?

java - 错误: method contains in class String cannot be applied to given types

python - 我想要叠加两张图像,其中一张是透明的

ios - iPhone 7 Plus 背景图片大小

java - setCellRenderer() 不起作用