我使用OpenCV-Library访问安装在系统上的相机。我从每个抓取的帧中获取尺寸,颜色信息和BGR-Samples,并根据整个事件初始化的帧速率让GStreamer AppSrc将图像拖入视频处理流水线。最初的管道是这样的:
的OpenCV,摄像机 - > AppSrc - > VideoRate - > ffmpegcolorspace - > AppSink
它去很快,但比较复杂,现在这是怎么看起来像。
的AppSink呼吁GStreamer的“新缓冲区”信号的功能(其它一些没有涉及到我的问题,其中重要)。这些回调实现调用提供图像颜色和维度的Java对象函数以及其示例缓冲区。所以这是关于我在做什么的简要信息。
现在我的问题:
看来我解决了我的问题。我现在使用另一种方式来创建我的图像,现在它的工作。
//constructor, callback whatever
imageSource = new MemoryImageSource(data.width,data.height,rawdata,0,data.width);
...
//Paint method of a JFrame or what ever ...
...
image img = createImage(imageSource);
setBounds(100,100,img.getWidth(null),img.getHeight(null));
createBufferStrategy(2);
BufferStrategy strategy = getBufferStrategy();
Graphics gr = strategy.getDrawGraphics();
gr.drawImage(img, 0, 0, null);
gr.dispose();
strategy.show();
我使用这些几行,其工作为我现在::
int[] nBits = {8, 8, 8};
ComponentSampleModel sampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, channels, width * channels, new int[] {2, 1, 0});
ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel colorModel = new ComponentColorModel(colorSpace, nBits, false, false,Transparency.OPAQUE,DataBuffer.TYPE_BYTE);
DataBufferByte db = new DataBufferByte(new byte[][] {buffer}, buffer.length);
WritableRaster raster = Raster.createWritableRaster(sampleModel, db, new Point(0, 0));
BufferedImage image = new BufferedImage(colorModel, raster, false, null);
缓冲器在本文表示原始字节样本阵列I得到throught
代替使用存储器中的图像源,像这样的我的方法从本地调用。
我也遇到了其他几个问题,利用摆动像冻结UI或崩溃抛出这些错误消息:
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
java: ../../src/xcb_io.c:178: dequeue_pending_request: assertion »!xcb_xlib_unknown_req_in_deq« failed.
这是因为我用了UIManager.setLookAndFeel()
方法来设置窗口外观到系统默认值。我没有将此与问题联系起来,因为如果您使用默认系统“Look And Feels”,我不知道Swing使用本机UI框架。删除这可以解决问题。我的研究将我带到论坛post(德文),它描述了Linux(Ubuntu)机器上仅发生在Java上(不是本机部分)的情况,而同一应用程序在未经修改的情况下在Windows机器上运行。所以删除它解决了我的问题。我认为我的“形象没有出现问题”与此有某种关系,但我不知道,因为我现在工作,所以我不在乎。
对UI的任何更新都应发生在事件派发线程上,通常通过调用SwingUtilities.invokeLater(Runnable)来实现。这意味着您的图像数据必须存在于生产线程和事件分派线程可用的范围内。 – technomage
我在最后一次测试中做到了这一点......没有成功...... – kneo
除非您每次*测试都做到这一点,否则您一定没有成功。 – technomage