BufferedImage
ユーザー定義の間隔 (私のテストでは 100 ミリ秒) で s を作成し、それらの画像を使用してムービー ファイルを作成することにより、Java プログラムでビデオ キャプチャを実装しています。JFrame
から記録しようとしている には、 に含まれるダッシュボードのようなインターフェイスが含まれていますJLayeredPane
。にJFrame
も 2 つCanvas3D
の があります。私はこれら 3 つのことをそれぞれ独自のに、render
または独自の に伝えており、後でそれらを結合します。ダッシュボードは、すべてのフレームのみをレンダリングするように設定されています。paint
LinkedBlockingDeque<BufferedImage>
dashboardFrameRepaintFrequency
Thread captureThread = new Thread(new Runnable() {
public void run() {
final Object LOCK = new Object();
final Thread captureDashboard = new Thread(new Runnable() {
public void run() {
while (m_isCapturingMovie) {
synchronized (LOCK) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.err.println("Calling getDashboardImage");
m_unsavedDash.add(getDashboardImage(m_dashboard.getWidth(), m_dashboard.getHeight(), BufferedImage.TYPE_INT_ARGB));
System.err.println("captureDashboard returned from calling m_unsavedDash.add...");
}
}
}
}
});
captureDashboard.start();
while (m_isCapturingMovie) {
startTime = System.currentTimeMillis();
captureCanvases();
if (++frameCount > dashboardFrameRepaintFrequency) {
frameCount = 0;
synchronized (LOCK) {
LOCK.notify();
}
}
endTime = System.currentTimeMillis();
millisToSleep = captureDelayInMillis - (endTime - startTime);
if (millisToSleep > 0) {
try {
Thread.sleep(millisToSleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized (captureDashboard) {
captureDashboard.notify();
}
}
});
15 ~ 20notify()
秒後に、プログラムがロックアップすることがわかりました。キャンバスの記録が停止し、キーボード入力への応答が停止します。まだ、フォーカスのあるウィンドウとボタン (ウィンドウを閉じるための X ボタンなど) を変更できます。 window) は、マウスのロールオーバーやクリックによって視覚状態を変更しますが、コマンドを実行しません。
コンソール出力から、15 ~ 20 回の反復の後、captureDashboard スレッドがgetDashboardImage
メソッドから返されないようです。
private BufferedImage getDashboardImage(int width, int height, int type) {
BufferedImage dashImg = new BufferedImage(m_dashboard.getWidth(), m_dashboard.getHeight(), type);
Graphics2D g = dashImg.createGraphics();
m_dashboard.paintAll(g);
g.dispose();
return getScaledImage(width, height, dashImg);
}
private BufferedImage getScaledImage(int width, int height, BufferedImage original) {
BufferedImage scaled = new BufferedImage(width, height, original.getType());
AffineTransform at = new AffineTransform();
at.scale((double) scaled.getWidth() / original.getWidth(), (double) scaled.getHeight() / original.getHeight());
AffineTransformOp scaleOp;
if (at.getScaleX() + at.getScaleY() > 2.0) {
scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC); // Better quality for enlargement
} else {
scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); // Better quality for ensmallment
}
scaled = scaleOp.filter(original, scaled);
original.flush();
return scaled;
}
何か案は?私はこれで数日間働いていて、困惑しています。