使用java.awt.Graphics2D在java中变形图像
我有这样的形象: 我需要把它变形成这样的图像: 我试着用很多代码来实现它,但我没有解决它。这是我最后一次尝试,但最终的图像看起来不太好使用java.awt.Graphics2D在java中变形图像,java,image,swing,graphics,java-2d,Java,Image,Swing,Graphics,Java 2d,我有这样的形象: 我需要把它变形成这样的图像: 我试着用很多代码来实现它,但我没有解决它。这是我最后一次尝试,但最终的图像看起来不太好 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 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);
}
}
使用此代码查看最终图像,如下所示:
您走的路是对的,因为您得到了极坐标到直角坐标的转换。 您只需缩放/平移源图像和生成的图像,或者等效地变换相对坐标 直观地说,在生成的图像中,fi跨度太大,如PI/2,而在所需的图像中,角度跨度非常小,你看到曲率小得多吗
希望这能有所帮助。您走对了,因为您得到了极坐标到直角坐标的转换。 您只需缩放/平移源图像和生成的图像,或者等效地变换相对坐标 直观地说,在生成的图像中,fi跨度太大,如PI/2,而在所需的图像中,角度跨度非常小,你看到曲率小得多吗
希望这有帮助。我发布了我的解决方案。也许它并不优雅,但它很有效:
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);
}
}
我发布我的解决方案。也许它并不优雅,但它很有效:
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);
}
}
谢谢你的评论,我看到了这种差异,但我现在不知道如何做得更好。谢谢你的评论,我看到了这种差异,但我现在不知道如何做得更好。