2

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

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

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

4

1 回答 1

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);

英特尔 IPP
仅可通过 JNI 获得。您可以使用ippiRGBToYUV422_8u_C3C2Rsee RGBToYUV422获取更多信息。

SwScale 作为 FFmpeg 的一部分
仅可通过 JNI 获得。请参阅此答案并调整示例。

我个人的经验是,即使在 AMD 机器上,IPP 也能提供迄今为止最好的性能。然而,它附带的许可证可能是免费的,但它禁止反编译,这可能与 LGPL 库不兼容。

于 2018-08-22T13:32:21.757 回答