在JavaFX中渲染YUV

时间:2017-04-07 23:15:11

标签: javafx yuv pixelformat

我需要在JavaFX中以最小延迟呈现yuyv422流。如果我将它转换为RGB,我可以使用带有PixelFormat实例的WritableImage的ImageView,它可以工作,但RGB转换会消耗大量CPU,特别是高分辨率。我看到了这个确切的功能请求

https://bugs.openjdk.java.net/browse/JDK-8091933

但似乎它不会在Java 9中实现。如果确实如此,我想知道它是否会引入延迟或者需要太多的CPU。还有另一种使用JavaFX的方法吗?

1 个答案:

答案 0 :(得分:0)

常规:
图像处理总是很昂贵的,这就是为什么将矢量化或硬件加速用于这些任务的原因。仅使用一个线程在Image中进行简单循环已经非常缓慢,尤其是在Java中。最重要的是,人们倾向于使用Color对象进行颜色修改,这非常慢。

纯Java:
如果您想将代码保留在纯Java中。您应该通过调用以下命令检查WriteableImage使用哪种内部格式:

myImage.getPixelWriter().getPixelFormat().getType() 

如果内部格式不是RGB,则将颜色转换调整为给定格式,以避免双重转换。 此外,请确保您的代码已尽可能优化:
-除了数组,不要使用任何对象
-尽量减少使用局部变量
您也可以尝试通过并行循环对转换过程进行多线程处理。

JNI:
远离Java带来了很多可能性。有几个独立于平台的库,可将YUV转换为RGB并反向转换:

OpenCV
易于使用,并且已经带有Java API:

byte[] myYuvImage = null; //your image here
byte[] myRgbImage = new byte[width * height * 3]; //the output image
Mat yuvMat = new Mat(height, width, CvType.CV_8UC2); //YUV422 should be 2 channel
Mat rgbMat = new Mat(height, width, CvType.CV_8UC3);
yuvMat.put(0,0, myYuvImage);
Imgproc.cvtColor(yuvMat, rgbMat, Imgproc.COLOR_YUV2RGB_Y422);
rgbMat.get(0, 0, myRgbImage);

Intel IPP
仅可通过JNI使用。您可以使用ippiRGBToYUV422_8u_C3C2R参见RGBToYUV422了解更多信息。

SwScale as part of FFmpeg
仅可通过JNI使用。请参见此answer并改编示例。

我的个人经验是IPP甚至可以在AMD机器上提供最佳性能。但是,它附带的许可证可能是免费的,但它禁止反编译,这可能与LGPL库不兼容。