Преобразование объекта OpenCV Mat в BufferedImage
Я пытаюсь создать вспомогательную функцию с помощью Java API OpenCV, которая будет обрабатывать входное изображение и возвращать выходной массив байтов. Входное изображение представляет собой файл jpg, сохраненный в компьютере. Входное и выходное изображение отображаются в интерфейсе Java с помощью Swing.
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;
Когда return_buff
возвращается и преобразуется в BufferedImage я получаю NULL обратно. Когда я комментирую функцию Imgproc.cvtColor
, return_buff
должным образом преобразуется в Буферизованное изображение, которое я могу отобразить. Похоже, что Imgproc.cvtColor
является возврат объекта Mat, который я не смог отобразить в Java.
Вот мой код для преобразования из byte[] в BufferedImage:
InputStream in = new ByteArrayInputStream(inputByteArray);
BufferedImage outputImage = ImageIO.read(in);
В приведенном выше коде outputImage равен NULL
У кого-нибудь есть какие-нибудь предложения или идеи?2 ответа:
ImageIO.read(...)
(и Пакетjavax.imageio
в целом) предназначен для чтения / записи изображений из / в форматы файлов. То, что у вас есть, - это массив, содержащий "сырые" пиксели. Невозможно дляImageIO
определить формат файла из этого массива байтов. Из-за этого он вернетсяnull
.Вместо этого вы должны создать
BufferedImage
непосредственно из байтов. Я не очень хорошо знаю OpenCV, но я предполагаю, что результатомImgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGB2GRAY, 0)
будет изображение в оттенках серого (8 бит/образец, 1 образец/пиксель). Это тот же формат, что иBufferedImage.TYPE_BYTE_GRAY
. Если это предположение верно, вы должны быть в состоянии сделать:// Read image as before Mat rgba = Highgui.imread(filePath); 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);
Делая это таким образом, вы экономите одно выделение большого массива байтов и одну копию массива байтов в качестве бонуса. :- )
Я использовал этот код, чтобы преобразовать объект коврик для Буферизованные изображения.
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; }