Java-从图像获取像素数组

我正在寻找从中获取像素数据(以表格形式int[][])的最快方法BufferedImage。我的目标是能够解决像素(x, y)从使用图像int[x][y]。我发现的所有方法均不执行此操作(大多数方法都返回int[]s)。

回答:

我只是在玩同一个主题,这是访问像素的最快方法。我目前知道执行此操作的两种方法:

使用getRGB()@tskuzzy的答案中所述的BufferedImage 方法。

通过直接使用以下方式访问像素数组:

byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();

如果你要处理大图像并且性能是一个问题,则第一种方法绝对不是可行的方法。该getRGB()方法将alpha,红色,绿色和蓝色的值合并为一个int,然后返回结果,在大多数情况下,你将进行相反操作以将这些值取回。

第二种方法将直接为每个像素返回红色,绿色和蓝色值,如果有alpha通道,它将添加alpha值。使用此方法在计算指标方面比较困难,但是比第一种方法要快得多。

在我的应用程序中,通过从第一种方法切换到第二种方法,我能够将像素处理时间减少90%以上!

这是我为比较两种方法而设置的比较:

import java.awt.image.BufferedImage;

import java.awt.image.DataBufferByte;

import java.io.IOException;

import javax.imageio.ImageIO;

public class PerformanceTest {

public static void main(String[] args) throws IOException {

BufferedImage hugeImage = ImageIO.read(PerformanceTest.class.getResource("12000X12000.jpg"));

System.out.println("Testing convertTo2DUsingGetRGB:");

for (int i = 0; i < 10; i++) {

long startTime = System.nanoTime();

int[][] result = convertTo2DUsingGetRGB(hugeImage);

long endTime = System.nanoTime();

System.out.println(String.format("%-2d: %s", (i + 1), toString(endTime - startTime)));

}

System.out.println("");

System.out.println("Testing convertTo2DWithoutUsingGetRGB:");

for (int i = 0; i < 10; i++) {

long startTime = System.nanoTime();

int[][] result = convertTo2DWithoutUsingGetRGB(hugeImage);

long endTime = System.nanoTime();

System.out.println(String.format("%-2d: %s", (i + 1), toString(endTime - startTime)));

}

}

private static int[][] convertTo2DUsingGetRGB(BufferedImage image) {

int width = image.getWidth();

int height = image.getHeight();

int[][] result = new int[height][width];

for (int row = 0; row < height; row++) {

for (int col = 0; col < width; col++) {

result[row][col] = image.getRGB(col, row);

}

}

return result;

}

private static int[][] convertTo2DWithoutUsingGetRGB(BufferedImage image) {

final byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();

final int width = image.getWidth();

final int height = image.getHeight();

final boolean hasAlphaChannel = image.getAlphaRaster() != null;

int[][] result = new int[height][width];

if (hasAlphaChannel) {

final int pixelLength = 4;

for (int pixel = 0, row = 0, col = 0; pixel + 3 < pixels.length; pixel += pixelLength) {

int argb = 0;

argb += (((int) pixels[pixel] & 0xff) << 24); // alpha

argb += ((int) pixels[pixel + 1] & 0xff); // blue

argb += (((int) pixels[pixel + 2] & 0xff) << 8); // green

argb += (((int) pixels[pixel + 3] & 0xff) << 16); // red

result[row][col] = argb;

col++;

if (col == width) {

col = 0;

row++;

}

}

} else {

final int pixelLength = 3;

for (int pixel = 0, row = 0, col = 0; pixel + 2 < pixels.length; pixel += pixelLength) {

int argb = 0;

argb += -16777216; // 255 alpha

argb += ((int) pixels[pixel] & 0xff); // blue

argb += (((int) pixels[pixel + 1] & 0xff) << 8); // green

argb += (((int) pixels[pixel + 2] & 0xff) << 16); // red

result[row][col] = argb;

col++;

if (col == width) {

col = 0;

row++;

}

}

}

return result;

}

private static String toString(long nanoSecs) {

int minutes = (int) (nanoSecs / 60000000000.0);

int seconds = (int) (nanoSecs / 1000000000.0) - (minutes * 60);

int millisecs = (int) ( ((nanoSecs / 1000000000.0) - (seconds + minutes * 60)) * 1000);

if (minutes == 0 && seconds == 0)

return millisecs + "ms";

else if (minutes == 0 && millisecs == 0)

return seconds + "s";

else if (seconds == 0 && millisecs == 0)

return minutes + "min";

else if (minutes == 0)

return seconds + "s " + millisecs + "ms";

else if (seconds == 0)

return minutes + "min " + millisecs + "ms";

else if (millisecs == 0)

return minutes + "min " + seconds + "s";

return minutes + "min " + seconds + "s " + millisecs + "ms";

}

}

你能猜出输出吗?;)

Testing convertTo2DUsingGetRGB:

1 : 16s 911ms

2 : 16s 730ms

3 : 16s 512ms

4 : 16s 476ms

5 : 16s 503ms

6 : 16s 683ms

7 : 16s 477ms

8 : 16s 373ms

9 : 16s 367ms

10: 16s 446ms

Testing convertTo2DWithoutUsingGetRGB:

1 : 1s 487ms

2 : 1s 940ms

3 : 1s 785ms

4 : 1s 848ms

5 : 1s 624ms

6 : 2s 13ms

7 : 1s 968ms

8 : 1s 864ms

9 : 1s 673ms

10: 2s 86ms

BUILD SUCCESSFUL (total time: 3 minutes 10 seconds)

以上是 Java-从图像获取像素数组 的全部内容, 来源链接: utcz.com/qa/417445.html

回到顶部