OpenCV의 imread() 메서드를 사용하여 이미지를 읽으면 그 결과가 Mat 객체로 반환됩니다. 그런데 이 Mat 객체의 내용을 JavaFX 윈도우에 표시하려면 먼저 Mat 객체를 javafx.scene.image.WritableImage 클래스의 객체로 변환해야 합니다.
이 변환은 몇 가지 단계를 거쳐 수행할 수 있으며, 각 단계는 다음과 같습니다.
Mat을 WritableImage로 변환하는 단계
1. Mat을 MatOfByte로 인코딩하기
가장 먼저 행렬(Mat) 데이터를 바이트 행렬로 변환해야 합니다. 이 작업은 Imgcodecs 클래스의 imencode() 메서드를 사용하여 수행합니다.
이 메서드는 세 개의 매개변수를 받습니다. 이미지 형식을 지정하는 문자열, 원본 이미지를 나타내는 Mat 객체, 그리고 인코딩된 결과를 담을 MatOfByte 객체입니다.
2. MatOfByte 객체를 바이트 배열로 변환하기
toArray() 메서드를 사용하여 MatOfByte 객체를 일반 바이트 배열(byte array)로 변환합니다.
3. ByteArrayInputStream 생성하기
이전 단계에서 만든 바이트 배열을 생성자에 전달하여 ByteArrayInputStream 클래스의 인스턴스를 생성합니다.
4. BufferedImage 객체 만들기
앞서 생성한 InputStream 객체를 ImageIO 클래스의 read() 메서드에 전달하면 BufferedImage 객체가 반환됩니다.
5. toFXImage() 메서드 호출하기
마지막으로 SwingFXUtils 클래스의 toFXImage() 메서드를 호출하고, 이전 단계에서 얻은 BufferedImage 객체를 매개변수로 전달하면 최종적으로 WritableImage 객체를 얻을 수 있습니다.
예제 코드
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.imgcodecs.Imgcodecs;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.WritableImage;
public class Mat2WritableImage {
public static WritableImage Mat2WritableImage(Mat mat) throws IOException {
// 이미지 인코딩
MatOfByte matOfByte = new MatOfByte();
Imgcodecs.imencode(".jpg", mat, matOfByte);
// 인코딩된 Mat을 바이트 배열에 저장
byte[] byteArray = matOfByte.toArray();
// BufferedImage 준비
InputStream in = new ByteArrayInputStream(byteArray);
BufferedImage bufImage = ImageIO.read(in);
System.out.println("Image Loaded");
WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
return writableImage;
}
public static void main(String args[]) throws Exception {
// OpenCV 핵심 라이브러리 로드
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// 파일에서 이미지 읽기
String file = "C:/EXAMPLES/OpenCV/sample.jpg";
Mat image = Imgcodecs.imread(file);
WritableImage obj = Mat2WritableImage(image);
System.out.println(obj);
}
}실행 결과
Image Loaded javafx.scene.image.WritableImage@142269f2
위 예제처럼 imread()로 읽어온 Mat 객체를 변환 메서드에 전달하면, 콘솔에 "Image Loaded" 메시지와 함께 생성된 WritableImage 객체가 출력되는 것을 확인할 수 있습니다. 이렇게 변환된 WritableImage는 JavaFX의 ImageView 등에 바로 설정하여 화면에 표시할 수 있습니다.