Java,根据自己的功能快速图像变形

Java, fast image warping according to own function

我将根据 Java 中的用户定义函数对图像进行变形。一般来说,图像比较大(JPEG,30-50 MB)。

最初,加载图像:

BufferedImage img = ImageIO.read("image.jpg");

设[X,Y]为重采样后的图像像素坐标,其中[x,y]表示其像素坐标。

坐标函数(简单例子)写法如下:

X = y * cos(x);
Y = x;

我的想法是使用逐像素变换:

//Get size of the raster
int width = img.getWidth(), height = img.getHeight();
int proj_width =  (int)(width * Math.cos(height*Math.pi/180)),proj_height = height;

 //Create output image
 BufferedImage img2 = new BufferedImage(proj_width+1, proj_height+1, img.getType());

 //Reproject raster
 for (int i = 0; i < img.getWidth(); i++) {
      for (int j = 0; j < img.getHeight(); j++) {

            //Color of the pixel
            int col = img.getRGB(i, j);

            //Its new coordinates
            int X = (int)(i * Math.cos(j*Math.pi/180));
            int Y = j;

            //Set X,Y,col to the new raster
            img2.setRGB(X,Y,col);                 
       } 
  }

有没有不用额外库实现这个操作更快的方法?

例如在 Warp class...

中使用 warpRect() 方法

感谢您的帮助。

使用 get/setRGB() 基本上是在 Java2D API 中复制像素的最简单但也可能是最慢的方法。这是因为每个像素的值必须从其原始表示形式转换为 sRGB 颜色 space 中的打包 32 位 ARGB 格式(对于 setRGB() 方法再次返回)..

由于您并不真正关心本机像素数据在您的情况下是什么样子,因此使用 (Writable)Raster 及其 get/setDataElements() 方法可能会更快(快多少取决于 BufferedImage类型):

// Reproject raster
Object pixel = null;

Raster from = img.getRaster();
WritableRaster to = img2.getRaster(); // Assuming img2.getType() == img.getType() always

for (int y = 0; y < img.getHeight(); y++) {
    for (int x = 0; x < img.getWidth(); x++) {
        // Color of the pixel
        pixel = from.getDataElements(x, y, pixel);

        // Its new coordinates
        int X = (int) (x * Math.cos(y * Math.pi/180));
        int Y = y;

        // Set X,Y,pixel to the new raster
        to.setDataElements(X, Y, pixel);                 
   } 

}

请注意,我还更改了嵌套循环以在内部循环中迭代宽度。由于普通 CPU 中的数据局部性和缓存,这可能会提供更好的性能。