我是JAVA OpenCV的新用户,我今天正在学习如何将Mat
对象转换为BufferedImage
的官方教程。
从演示代码中,我可以理解输入图像源是一个矩阵形式,然后sourcePixels
似乎是图像的字节表示数组,所以我们需要从original
矩阵获取值到sourcePixels
。这里sourcePixels
具有整个图像字节长度的长度(大小:w * h *通道),因此它将立即获取整个图像字节值。
然后就是这个对我来说不直观。 System.arraycopy()
似乎将值从sourcePixels
复制到targetPixels
,但是什么行动回来的是image
。我可以从代码中猜测targetPixels
与image
有关系,但我不知道我们如何将值从sourcePixels
复制到targetPixels
,但它实际上影响了image
的值?
这是演示代码。谢谢!
private static BufferedImage matToBufferedImage(Mat original)
{
BufferedImage image = null;
int width = original.width(), height = original.height(), channels = original.channels();
byte[] sourcePixels = new byte[width * height * channels];
original.get(0, 0, sourcePixels);
if (original.channels() > 1)
{
image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
}
else
{
image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
}
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(sourcePixels, 0, targetPixels, 0, sourcePixels.length);
return image;
}
每个BufferedImage
都支持一个字节数组,就像OpenCV中的Mat
类一样,对((DataBufferByte) image.getRaster().getDataBuffer()).getData();
的调用返回这个底层字节数组并将其分配给targetPixels
,换句话说,targetPixels
指向BufferedImage
image
目前正在环绕的这个底层字节数组,所以当你调用System.arraycopy
时,你实际上是从源字节数组复制到BufferedImage
的字节数组,这就是返回image
的原因,因为在那时,image
封装的底层字节数组包含来自original
的像素数据,这就像这个小例子,在b
指向a之后,对b
的修改也将反映在a
,就像tagetPixels
,因为它指向字节数组image
封装,从sourcePixels
复制到targetPixels
也将改变image
int[] a = new int[1];
int[] b = a;
// Because b references the same array that a does
// Modifying b will actually change the array a is pointing to
b[0] = 1;
System.out.println(a[0] == 1);