From 09e54ec3b36e4b3cabb22121123c369f505ba97a Mon Sep 17 00:00:00 2001 From: nyatla Date: Fri, 31 Dec 2010 06:32:08 +0000 Subject: [PATCH] git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@773 7cac0a50-4618-4814-88d0-24b83990f816 --- .../nyartoolkit/qt/utils/QtCameraCapture.java | 243 +++++++++++++++++++++ .../nyartoolkit/qt/utils/QtCaptureListener.java | 35 +++ .../nyartoolkit/qt/utils/QtNyARRaster_RGB.java | 98 +++++++++ 3 files changed, 376 insertions(+) create mode 100644 utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCameraCapture.java create mode 100644 utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCaptureListener.java create mode 100644 utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtNyARRaster_RGB.java diff --git a/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCameraCapture.java b/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCameraCapture.java new file mode 100644 index 0000000..5a46699 --- /dev/null +++ b/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCameraCapture.java @@ -0,0 +1,243 @@ +/* + * PROJECT: NyARToolkit Quicktime utilities. + * -------------------------------------------------------------------------------- + * Copyright (C)2008 arc@dmz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this framework; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information please contact. + * + * + * + */ + +package jp.nyatla.nyartoolkit.qt.utils; + +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +import javax.swing.Timer; + +import quicktime.QTException; +import quicktime.QTSession; +import quicktime.io.QTFile; +import quicktime.qd.PixMap; +import quicktime.qd.QDConstants; +import quicktime.qd.QDGraphics; +import quicktime.qd.QDRect; +import quicktime.std.StdQTConstants; +import quicktime.std.movies.Movie; +import quicktime.std.movies.media.DataRef; +import quicktime.std.sg.SGVideoChannel; +import quicktime.std.sg.SequenceGrabber; +import quicktime.util.RawEncodedImage; + +import jp.nyatla.nyartoolkit.NyARException; + +/** + * QuickTimeキャプチャクラス + * + */ +public class QtCameraCapture implements ActionListener +{ + + private Dimension image_size; + + private QtCaptureListener capture_listener; + + protected float fps = 30; // キャプチャ画像を取得するfps + + protected byte[] pixels; // キャプチャ画像の実データを保持するバイト型配列 + + // キャプチャに使うタイマー + private Timer timer; + + // QTJava用のあれこれ + private QDGraphics graphics; + + private QDRect bounds; + + private SequenceGrabber grabber; + + private SGVideoChannel channel; + + private RawEncodedImage rawEncodedImage; + + private Movie movie; + + // ピクセルフォーマット変換用の一時変数 + private int[] pixels_int; + + public static final int PIXEL_FORMAT_RGB = quicktime.util.EndianOrder.isNativeLittleEndian() ? QDConstants.k32BGRAPixelFormat : QDGraphics.kDefaultPixelFormat; + + public QtCameraCapture(int i_width, int i_height, float i_rate) + { + image_size = new Dimension(i_width, i_height); + fps = i_rate; + } + + public Dimension getSize() + { + return image_size; + } + + public byte[] readBuffer() throws NyARException + { + if (grabber == null) { + throw new NyARException(); + } + return pixels; + } + + public void setCaptureListener(QtCaptureListener i_listener) throws NyARException + { + if (grabber != null) { + throw new NyARException(); + } + capture_listener = i_listener; + + } + + /** + * @param input + * @throws QTException + */ + public void prepSetInput(Object input) throws QTException + { + QTSession.open(); + bounds = new QDRect(image_size.width, image_size.height); + graphics = new QDGraphics(quicktime.util.EndianOrder.isNativeLittleEndian() ? QDConstants.k32BGRAPixelFormat : QDGraphics.kDefaultPixelFormat, bounds); + if (input != null && input.getClass().equals(File.class)) { + movie = quicktime.std.movies.Movie.fromDataRef(new DataRef(new QTFile((File) input)), StdQTConstants.newMovieActive); + } else { + grabber = new SequenceGrabber(); + grabber.setGWorld(graphics, null); + //Please check WinVDIG if you got couldntGetRequiredComponent exception on Windows. + channel = new SGVideoChannel(grabber); + channel.setBounds(bounds); + + // seqGrabPreview == 2, Processingでmagic numberとしてハードコートされていた… + channel.setUsage(StdQTConstants.seqGrabPreview); + + if (input != null) { + try { + channel.setDevice(input.toString()); + } catch (QTException e) { + e.printStackTrace(); + throw e; + } + } + } + } + + /** + * Webcamの設定ダイアログを表示する。 + * 既定のWebcamでは駄目な場合(複数のWebcamが接続されているPCなど)ではこれを実行するとよい。 + */ + public void prepShowDialog() throws QTException + { + channel.settingsDialog(); + } + + public void start() throws NyARException + { + try { + + if (grabber == null) + prepSetInput(null); + + if (movie == null) { + grabber.prepare(true, false); // あってもなくてもよさそう + grabber.startPreview(); + } else { + movie.preroll(0, 1.0f); + while (movie.maxLoadedTimeInMovie() == 0) + movie.task(100); + movie.setRate(1); + movie.getPict(movie.getTime()).draw(graphics, bounds); + } + PixMap pixmap = graphics.getPixMap(); + rawEncodedImage = pixmap.getPixelData(); + + image_size.width = rawEncodedImage.getRowBytes() / 4; + pixels = new byte[image_size.width * image_size.height * 3]; + pixels_int = new int[image_size.width * image_size.height]; + } catch (QTException e) { + QTSession.close(); + throw new NyARException(e); + } + + // キャプチャイメージを定期的に更新するタイマー + timer = new Timer((int) (1000 / fps), this); + timer.start(); + } + + public void stop() + { + finalize(); + } + + /** タイマー処理。キャプチャイメージの更新結果をリスナに伝える。 */ + public void actionPerformed(ActionEvent event) + { + + // 画像をQTJavaのRawEncodedImageとして取得 + try { + if (movie == null) { + grabber.idle(); + } else { + if (movie.isDone()) + movie.goToBeginning(); + movie.getPict(movie.getTime()).draw(graphics, bounds); + } + } catch (QTException e) { + QTSession.close(); + e.printStackTrace(); + } + + // RawEncodedImageをint列に落とし込む + rawEncodedImage.copyToArray(0, pixels_int, 0, pixels_int.length); + + // バイト列を生成する + int idx_byte = 0; + for (int idx = 0; idx < image_size.width * image_size.height; idx++) { + pixels[idx_byte++] = (byte) (pixels_int[idx] >> 16); + pixels[idx_byte++] = (byte) (pixels_int[idx] >> 8 & 0xff); + pixels[idx_byte++] = (byte) (pixels_int[idx] & 0xff); + } + + // 各リスナに更新されたバイト列を渡す + capture_listener.onUpdateBuffer(pixels); + } + + protected void finalize() + { + try { + if (movie == null) { + grabber.stop(); + grabber.release(); + grabber.disposeChannel(channel); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + QTSession.close(); + } + timer.stop(); + } + +} diff --git a/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCaptureListener.java b/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCaptureListener.java new file mode 100644 index 0000000..eaef79c --- /dev/null +++ b/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtCaptureListener.java @@ -0,0 +1,35 @@ +/* + * PROJECT: NyARToolkit Quicktime utilities. + * -------------------------------------------------------------------------------- + * Copyright (C)2008 arc@dmz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this framework; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information please contact. + * + * + * + */ +package jp.nyatla.nyartoolkit.qt.utils; + +/** + * QuickTime リスナクラス + * + */ +public interface QtCaptureListener +{ + public void onUpdateBuffer(byte[] i_buffer); + +} \ No newline at end of file diff --git a/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtNyARRaster_RGB.java b/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtNyARRaster_RGB.java new file mode 100644 index 0000000..fc1bbb8 --- /dev/null +++ b/utils/qt/src/jp/nyatla/nyartoolkit/qt/utils/QtNyARRaster_RGB.java @@ -0,0 +1,98 @@ +/* + * PROJECT: NyARToolkit Quicktime utilities. + * -------------------------------------------------------------------------------- + * Copyright (C)2008 arc@dmz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this framework; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For further information please contact. + * + * + * + */ +package jp.nyatla.nyartoolkit.qt.utils; + + +import jp.nyatla.nyartoolkit.NyARException; +import jp.nyatla.nyartoolkit.core.raster.rgb.*; +import jp.nyatla.nyartoolkit.core.rasterreader.*; +import jp.nyatla.nyartoolkit.core.types.*; + +/** + * RGB形式のbyte配列をラップするNyARRasterです。 + * 保持したデータからBufferedImageを出力する機能も持ちます。 + */ +public class QtNyARRaster_RGB implements INyARRgbRaster +{ + private NyARIntSize _size; + private byte[] _buffer; + private NyARRgbPixelReader_BYTE1D_R8G8B8_24 _reader; + private int _buffer_type; + + /** + * QuickTimeオブジェクトからイメージを取得するラスタオブジェクトを作ります。 + * この + * @param i_width + * @param i_height + */ + public QtNyARRaster_RGB(int i_width, int i_height) + { + this._size=new NyARIntSize(i_width,i_height); + this._buffer= null; + this._buffer_type=NyARBufferType.BYTE1D_R8G8B8_24; + this._reader = new NyARRgbPixelReader_BYTE1D_R8G8B8_24(null,this._size); + } + + final public int getWidth() + { + return this._size.w; + } + + final public int getHeight() + { + return this._size.h; + } + + final public NyARIntSize getSize() + { + return this._size; + } + final public int getBufferType() + { + return this._buffer_type; + } + final public INyARRgbPixelReader getRgbPixelReader() + { + return this._reader; + } + final public boolean hasBuffer() + { + return this._buffer!=null; + } + final public Object getBuffer() + { + assert(this._buffer!=null); + return this._buffer; + } + final public boolean isEqualBufferType(int i_type_value) + { + return this._buffer_type==i_type_value; + } + final public void wrapBuffer(Object i_ref_buf) throws NyARException + { + this._buffer=(byte[])i_ref_buf; + this._reader.switchBuffer(i_ref_buf); + } +} -- 2.11.0