在Java中扭曲或扭曲图像对象

在Java中扭曲或扭曲图像对象,java,distortion,skew,Java,Distortion,Skew,在Java中是否可能扭曲图像对象?我“拉”出图像的一面,使它看起来更接近我。(如3D) 有什么建议吗?有。有很多种方法,但我会从这个开始。它提供了大量先进的成像功能 但要进行你所说的那种转换,你可能只需要一个。对于上一个链接。您也可以使用JavaFX执行此操作 下面的示例使用和在上进行一点旋转 它改变了这个图像 进入这个 import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.e

在Java中是否可能扭曲图像对象?我“拉”出图像的一面,使它看起来更接近我。(如3D)


有什么建议吗?

有。有很多种方法,但我会从这个开始。它提供了大量先进的成像功能


但要进行你所说的那种转换,你可能只需要一个。对于上一个链接。

您也可以使用JavaFX执行此操作

下面的示例使用和在上进行一点旋转

它改变了这个图像

进入这个

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.SnapshotParameters;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.CountDownLatch;

/**
* Distorts images using transformations.
* <p>
* Created by Matthias Braun on 2018-09-05.
*/
public class Distortion {

    public static void main(String... args) throws IOException {
        URL imgUrl = new URL("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a");
        BufferedImage img = ImageIO.read(imgUrl);
        BufferedImage distorted = distortImg(img);

        File newImgFile = new File(System.getenv("HOME") + "/distorted.png");
        System.out.println("Saving to: " + newImgFile);
        ImageIO.write(distorted, "png", newImgFile);

        // Since we started a JavaFX thread in distortImg we have to shut it down. Otherwise the JVM won't exit
        Platform.exit();
    }

    /**
    * Applies perspective transformations to a copy of this {@code image} and rotates it.
    * <p>
    * Since this method starts a JavaFX thread, it's important to call {@link Platform#exit()} at the end of
    * your application. Otherwise the thread will prevent the JVM from shutting down.
    *
    * @param image the image we want to distort
    * @return the distorted image
    */
    private static BufferedImage distortImg(BufferedImage image) {
        // Necessary to initialize the JavaFX platform and to avoid "IllegalStateException: Toolkit not initialized"
        new JFXPanel();

        // This array allows us to get the distorted image out of the runLater closure below
        final BufferedImage[] imageContainer = new BufferedImage[1];

        // We use this latch to await the end of the JavaFX thread. Otherwise this method would finish before
        // the thread creates the distorted image
        final CountDownLatch latch = new CountDownLatch(1);

        // To avoid "IllegalStateException: Not on FX application thread" we start a JavaFX thread
        Platform.runLater(() -> {
            int width = image.getWidth();
            int height = image.getHeight();
            Canvas canvas = new Canvas(width, height);
            GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
            ImageView imageView = new ImageView(SwingFXUtils.toFXImage(image, null));

            PerspectiveTransform trans = new PerspectiveTransform();
            trans.setUlx(0);
            trans.setUly(height / 4);
            trans.setUrx(width);
            trans.setUry(0);
            trans.setLrx(width);
            trans.setLry(height);
            trans.setLlx(0);
            trans.setLly(height - height / 2);

            imageView.setEffect(trans);

            imageView.setRotate(2);

            SnapshotParameters params = new SnapshotParameters();
            params.setFill(Color.TRANSPARENT);

            Image newImage = imageView.snapshot(params, null);
            graphicsContext.drawImage(newImage, 0, 0);

            imageContainer[0] = SwingFXUtils.fromFXImage(newImage, image);
            // Work is done, we decrement the latch which we used for awaiting the end of this thread
            latch.countDown();
        });
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return imageContainer[0];
    }
}

导入javafx.application.Platform;
导入javafx.embed.swing.JFXPanel;
导入javafx.embed.swing.SwingFXUtils;
导入javafx.scene.Snapshot参数;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
导入javafx.scene.effect.PerspectiveTransform;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.paint.Color;
导入javax.imageio.imageio;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.net.URL;
导入java.util.concurrent.CountDownLatch;
/**
*使用变换扭曲图像。
*
*由Matthias Braun于2018-09-05创建。
*/
公共阶级扭曲{
公共静态void main(字符串…参数)引发IOException{
URL imgUrl=新URL(“https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a");
BuffereImage img=ImageIO.read(imgUrl);
BuffereImage畸变=畸变mg(img);
File newImgFile=new文件(System.getenv(“HOME”)+“/distributed.png”);
System.out.println(“保存到:“+newImgFile”);
ImageIO.write(扭曲的“png”,新的imgFile);
//因为我们在Java中启动了一个JavaFX线程,所以我们必须关闭它,否则JVM将无法退出
Platform.exit();
}
/**
*将透视变换应用于此{@code image}的副本并旋转它。
*
*由于此方法启动JavaFX线程,因此在结束时调用{@link Platform#exit()}非常重要
*否则线程将阻止JVM关闭。
*
*@param image我们想要扭曲的图像
*@返回扭曲的图像
*/
专用静态BuffereImage(BuffereImage图像){
//初始化JavaFX平台和避免“IllegalStateException:Toolkit未初始化”所必需的
新JFXPanel();
//这个数组允许我们从下面的runLater闭包中获得扭曲的图像
最终BuffereImage[]imageContainer=新的BuffereImage[1];
//我们使用这个锁存器来等待JavaFX线程的结束,否则这个方法将在
//线程创建扭曲的图像
最终倒计时闩锁=新倒计时闩锁(1);
//为了避免“IllegalStateException:不在FX应用程序线程上”,我们启动了一个JavaFX线程
Platform.runLater(()->{
int width=image.getWidth();
int height=image.getHeight();
画布=新画布(宽度、高度);
GraphicsContext GraphicsContext=canvas.getGraphicsContext2D();
ImageView ImageView=newImageView(SwingFXUtils.toFXImage(image,null));
PerspectiveTransform=新的PerspectiveTransform();
反式setUlx(0);
横截面积(高度/4);
横截面积(宽度);
横贯塞图里(0);
横向设置lrx(宽度);
变速箱设置(高度);
trans.setLlx(0);
横截面(高度-高度/2);
设置效果(trans);
设置旋转(2);
SnapshotParameters params=新的SnapshotParameters();
参数设置填充(颜色透明);
Image newImage=imageView.snapshot(参数,null);
graphicsContext.drawImage(newImage,0,0);
imageContainer[0]=SwingFXUtils.fromFXImage(newImage,image);
//工作完成后,我们减少用于等待线程结束的闩锁
倒计时();
});
试一试{
satch.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
返回图像容器[0];
}
}

关于JAI的好建议,但我不认为像建议的那样,仅凭仿射变换就足够了。我也不确定这是否是正确的变换。这就是为什么我添加了图像搜索结果,作为佐证。也许吧?垃圾神,透视变换是我所需要的。我需要透视和直线。谢谢。可能是第二份