画像の描画に使用されてSurfaceView
いる があり、電話のカメラからのライブ フィードにオーバーレイしたいと考えています。
現在、SurfaceView
画像を含む の背景は白ですが、携帯電話のカメラ フィードに重ねる場合は透明にする必要があります。カメラとアニメーションの描画は、同じ で行うことはできませんSurfaceView
。
カメラの管理と画像の描画を含む複数のビューの使用を追求するための最良のコースは何ですか? SurfaceView
透明にすることは可能ですか?
画像の描画に使用されてSurfaceView
いる があり、電話のカメラからのライブ フィードにオーバーレイしたいと考えています。
現在、SurfaceView
画像を含む の背景は白ですが、携帯電話のカメラ フィードに重ねる場合は透明にする必要があります。カメラとアニメーションの描画は、同じ で行うことはできませんSurfaceView
。
カメラの管理と画像の描画を含む複数のビューの使用を追求するための最良のコースは何ですか? SurfaceView
透明にすることは可能ですか?
さて、これが私がそれをした方法です... Qualcomm ARのものが出ていますが、誰かがそれが役に立つと思うことを願っています..それは時代遅れかもしれません..ああそして基本的にこれは何をしますか-そのAndroidの例から2つのファンキーなキューブを生成します、追加機能タッチイベントが導入されていますが、回転ベクトルは大幅にずれています。とにかくデモンストレーションの目的で、もちろん、画面上で移動できるカメラプレビューの上にキューブがオーバーレイされています。
public class TakeRecieptPicture extends Activity implements Callback {
private Camera camera;
private SurfaceView mSurfaceView;
SurfaceHolder mSurfaceHolder;
private TouchSurfaceView mGLSurfaceView;
ShutterCallback shutter = new ShutterCallback(){
@Override
public void onShutter() {
// TODO Auto-generated method stub
// No action to be perfomed on the Shutter callback.
}
};
PictureCallback raw = new PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
// No action taken on the raw data. Only action taken on jpeg data.
}
};
PictureCallback jpeg = new PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
FileOutputStream outStream = null;
try{
outStream = new FileOutputStream("/sdcard/test.jpg");
outStream.write(data);
outStream.close();
}catch(FileNotFoundException e){
Log.d("Camera", e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("Camera", e.getMessage());
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mGLSurfaceView = new TouchSurfaceView(this);
addContentView(mGLSurfaceView, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
mSurfaceView = new SurfaceView(this);
addContentView(mSurfaceView, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT|LayoutParams.FLAG_BLUR_BEHIND);
}
private void takePicture() {
// TODO Auto-generated method stub
camera.takePicture(shutter, raw, jpeg);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(arg2, arg3);
try {
camera.setPreviewDisplay(arg0);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
}
}
TouchSurfaceViewは次のように定義されています。
class TouchSurfaceView extends GLSurfaceView {
public TouchSurfaceView(Context context) {
super(context);
cr = new CubeRenderer(true);
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.setRenderer(cr);
this.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
this.getHolder().setFormat(PixelFormat.TRANSPARENT);
}
public boolean onTrackballEvent(MotionEvent e) {
cr.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR;
cr.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR;
requestRender();
return true; }
@Override
public boolean onTouchEvent(MotionEvent e) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;
float dy = y - mPreviousY;
cr.mAngleX += dx * TOUCH_SCALE_FACTOR;
cr.mAngleY += dy * TOUCH_SCALE_FACTOR;
requestRender();
}
mPreviousX = x;
mPreviousY = y;
return true;
}
private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
private final float TRACKBALL_SCALE_FACTOR = 36.0f;
public CubeRenderer cr ;
private float mPreviousX;
private float mPreviousY;
}
そして、CubeRendererは次のように与えられます。
class CubeRenderer implements GLSurfaceView.Renderer {
public CubeRenderer(boolean useTranslucentBackground) {
mTranslucentBackground = useTranslucentBackground;
mCube = new Cube();
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -5.0f);
gl.glRotatef(mAngle, 0, 1, 0);
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mCube.draw(gl);
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
gl.glTranslatef(0.5f, 0.5f, 0.5f);
mCube.draw(gl);
mAngle += 1.2f;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
if (mTranslucentBackground) {
gl.glClearColor(0,0,0,0);
} else {
gl.glClearColor(1,1,1,1);
}
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
public void setAngle(float _angle){
}
private boolean mTranslucentBackground;
private Cube mCube;
private float mAngle;
public float mAngleX;
public float mAngleY;
}
そして最後に、キューブ自体は次のように与えられます。
class Cube{
public Cube()
{ int one = 0x10000;
int vertices[] = {
-one, -one, -one,
one, -one, -one,
one, one, -one,
-one, one, -one,
-one, -one, one,
one, -one, one,
one, one, one,
-one, one, one, };
float[] colors = {
0f, 0f, 0f, 0.5f,
1f , 0f, 0f, 0.1f,
1f,1f,0f,0.5f,
0f, 1f, 0f, 0.1f,
0f, 0f, 1f, 0.1f,
1f, 0f, 1f, 0.2f,
1f, 1f, 1f, 0.1f,
0f, 1f, 1f, 0.1f, };
byte indices[] = {
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2 };
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asFloatBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0); }
public void draw(GL10 gl) {
gl.glFrontFace(gl.GL_CW);
gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer); }
private IntBuffer mVertexBuffer;
private FloatBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}
誰かがこれが役に立つと思うことを願っています...
私は次のアプローチで成功しました。
まず、次のようなレイアウト xml ファイルを作成します (2 つのビューの順序に注意してください)。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<com.yourcustom.OverlayView
android:id="@+id/overlay" android:layout_width="fill_parent"
android:layout_height="fill_parent">
</com.yourcustom.OverlayView>
<SurfaceView android:id="@+id/surface"
android:layout_width="fill_parent" android:layout_height="fill_parent">
</SurfaceView>
</FrameLayout>
OverlayView
SurfaceView
は、描画およびアニメーション スレッドの実装を持つ のサブクラスです。もう一方の SurfaceView は、カメラ プレビューを処理するサーフェスになります。内部では、次のonCreate
ようにビューを設定する必要があります。
mView = (OverlayView)this.findViewById(R.id.overlay);
mView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
mSurfaceView = (SurfaceView)this.findViewById(R.id.surface);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
アニメーション スレッドを処理するSurfaceHolder.Callback
実装を にSurfaceHolder
追加する必要があります。mView
サブクラス内でこれを実装し、アニメーション/描画スレッドを使用する例は、ここの古い LunarLander の例にあります:
http://developer.android.com/resources/samples/LunarLander/src/com/example/android/lunarlander/ LunarView.html
それに加えて、次の例と同じ方法でカメラ SurfaceView をセットアップします: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html
私も拡張アプリケーションを行っており、あなたが遭遇したのと同じ問題に遭遇しました。それを正しく解決する方法に関する情報はほとんどありません。しかし、 mixareというフレームワークを見つけました。このフレームワークを使用すると、Android 用の AR アプリを作成できます。あなたは間違いなくそれのソースを見るべきです- それはかなり有望に見えます. これがあなたを助けることを願っています。
このコードは役に立ちますか?`
ハンドセットを 4.0.4 にアップグレードしたところ、少し奇妙な余震がありました。全画面カメラ プレビューに半透明の全画面オーバーレイがあり、これは以前の ics ビルド (4.0.3 だったと思いますが、確実ではありません) で非常にうまく機能していました。4.0.4 にアップグレードした後、プレビューは少し混乱し、カメラ画像の明るい部分にサイケデリックな原色領域が表示されました (暗い部分は問題ないように見えました)。最終的に、glclearcolor を 0.5、0.5、0.5 から 0,0,0,0 に変更することがわかりました。0 整理しました。
gl オーバーレイの未使用部分のアルファがゼロであったとしても、ブレンディング関数は灰色の gl 背景を考慮しているようです。