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

标签 java image graphics pixel warp

我将根据 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 类中使用 warpRect() 方法...

感谢您的帮助。

最佳答案

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

由于您并不真正关心您的情况下的 native 像素数据是什么样子,因此可能使用 (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 中的缓存,这可能会提供更好的性能。

关于Java,根据自己的功能快速图像变形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44914295/

相关文章:

iphone - 如何将iPhone点击手势识别限制在圆形图像内?

java - Javabean 和 EJB 的区别

java - 使用 RabbitMQ(Java 客户端),有没有办法确定在使用期间网络连接是否关闭?

C# - 图像作为可点击的按钮

image - Qt 图形 View ,显示图像! , 小部件

windows - GDI GradientFill 不适用于屏幕外位图

graphics - 使用 SDL2 和 Lisp 的多个图形窗口?

java - 嵌套的正则表达式和替换

java - 不同数据源的@Transaction注解

java - 我想加载没有额外白色像素的图像。我该怎么做呢?