Java 将 OpenCV Mat 对象转换为 BufferedImage

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27086120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 03:47:06  来源:igfitidea点击:

Convert OpenCV Mat object to BufferedImage

javaimageopencvbufferedimage

提问by John Ng

I am trying to create a helper function using OpenCV Java API that would process an input image and return the output byte array. The input image is a jpg file saved in the computer. The input and output image are displayed in the Java UI using Swing.

我正在尝试使用 OpenCV Java API 创建一个辅助函数,该函数将处理输入图像并返回输出字节数组。输入图像是保存在计算机中的jpg文件。输入和输出图像使用 Swing 显示在 Java UI 中。

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// Load image from file
Mat rgba = Highgui.imread(filePath);

Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0);

// Convert back to byte[] and return
byte[] return_buff = new byte[(int) (rgba.total() * rgba.channels())];
rgba.get(0, 0, return_buff);
return return_buff;

When the return_buffis returned and converted to BufferedImage I get NULL back. When I comment out the Imgproc.cvtColorfunction, the return_buffis properly converted to a BufferedImage that I can display. It seems like the Imgproc.cvtColoris returning a Mat object that I couldn't display in Java.

return_buff返回并转换为 BufferedImage 时,我返回 NULL。当我注释掉该Imgproc.cvtColor函数时,它return_buff会正确转换为我可以显示的 BufferedImage。似乎Imgproc.cvtColor正在返回一个我无法在 Java 中显示的 Mat 对象。

Here's my code to convert from byte[] to BufferedImage:

这是我从 byte[] 转换为 BufferedImage 的代码:

InputStream in = new ByteArrayInputStream(inputByteArray);
BufferedImage outputImage = ImageIO.read(in);

In above code, outputImage is NULL

在上面的代码中, outputImage 为 NULL

Does anybody have any suggestions or ideas?

有人有任何建议或想法吗?

采纳答案by haraldK

ImageIO.read(...)(and the javax.imageiopackage in general) is for reading/writing images from/to file formats. What you have is an array containing "raw" pixels. It's impossible for ImageIOto determine file format from this byte array. Because of this, it will return null.

ImageIO.read(...)(以及javax.imageio一般的包)用于从/向文件格式读取/写入图像。您拥有的是一个包含“原始”像素的数组。ImageIO从这个字节数组中确定文件格式是不可能的。因此,它将返回null

Instead, you should create a BufferedImagefrom the bytes directly. I don't know OpenCV that well, but I'm assuming that the result of Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0)will be an image in grayscale (8 bits/sample, 1 sample/pixel). This is the same format as BufferedImage.TYPE_BYTE_GRAY. If this assumption is correct, you should be able to do:

相反,您应该BufferedImage直接从字节创建一个。我不太了解 OpenCV,但我假设结果Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0)将是灰度图像(8 位/样本,1 个样本/像素)。这与BufferedImage.TYPE_BYTE_GRAY. 如果这个假设是正确的,你应该能够做到:

// Read image to Mat as before
Mat rgba = ...;
Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0);

// Create an empty image in matching format
BufferedImage gray = new BufferedImage(rgba.width(), rgba.height(), BufferedImage.TYPE_BYTE_GRAY);

// Get the BufferedImage's backing array and copy the pixels directly into it
byte[] data = ((DataBufferByte) gray.getRaster().getDataBuffer()).getData();
rgba.get(0, 0, data);

Doing it this way, saves you one large byte array allocation and one byte array copy as a bonus. :-)

这样做可以为您节省一个大字节数组分配和一个字节数组副本作为奖励。:-)

回答by Log Raj Bhatt

I used this kind of code to convert Mat object to Buffered Image.

我使用这种代码将 Mat 对象转换为缓冲图像。

static BufferedImage Mat2BufferedImage(Mat matrix)throws Exception {        
    MatOfByte mob=new MatOfByte();
    Imgcodecs.imencode(".jpg", matrix, mob);
    byte ba[]=mob.toArray();

    BufferedImage bi=ImageIO.read(new ByteArrayInputStream(ba));
    return bi;
}