32 votes

Superposer des images sur l'aperçu de l'appareil photo SurfaceView

J'ai un SurfaceView qui est utilisé pour dessiner des images, et je tiens à les superposer sur un fil en direct de la caméra du téléphone.

Actuellement, l' SurfaceView qui contient les images ont un fond blanc, mais si je devais en superposition sur la caméra du téléphone se nourrir, ils devraient être transparentes. La caméra et l'animation, le dessin ne peut pas être fait sur le même SurfaceView.

Quel est le meilleur cours pour poursuivre l'utilisation de plusieurs points de vue qui impliquent la gestion de la caméra et le dessin des images? Est-il possible de faire un SurfaceView transparent?

20voto

bala singareddy Points 183

Eh bien voici comment je l'ai fait ... j'espère que quelqu'un trouve qu'il est utile si le Qualcomm AR des choses est de sortie.. il peut être obselete.. oh, et, fondamentalement, ce que cela fait, c'est -- générer deux funky cubes de que Android Exemple, des fonctionnalités supplémentaires introduites sont les événements tactiles, bien que la rotation des vecteurs sont par beaucoup-juste pour une démonstration de toute façon et bien sûr les cubes placée au-dessus de l'aperçu de la caméra qui peut être déplacé sur un écran..


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

Le TouchSurfaceView est défini ci-dessous:


   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;


}

Et le CubeRenderer est donnée par:


    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;

}
   

Et enfin le Cube lui-même est donnée par:


    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;

    }
   

Bien espère que quelqu'un le trouve utile...

6voto

matekm Points 2098

Je fais aussi une application augustée et j'ai rencontré le même problème que vous avez rencontré. Il y a très peu d'informations sur la façon de le résoudre correctement. Mais j'ai trouvé un framework appelé "mixare" - il vous permet de créer une application AR pour Android. Vous devriez certainement le regarder à la source - il semble très prometteur. J'espère que cela vous aidera

À votre santé

6voto

Frank Points 1756

J'ai eu du succès avec l'approche suivante.

D'abord faire une mise en page fichier xml qui ressemble à quelque chose comme ceci (notez l'ordre de deux points de vue):

<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 est une sous-classe de SurfaceView avec le dessin et l'animation fil des implémentations. Les autres SurfaceView sera de la surface qui gère l'aperçu de la Caméra. À l'intérieur de l' onCreate vous devez configurer votre point de vue comme ceci:

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

Vous devez ajouter un SurfaceHolder.Callback de la mise en œuvre de l' SurfaceHolder de mView qui gère l'animation du fil. Un exemple de mise en œuvre de cette dans le sous-classe et à l'aide de l'animation/dessin threads peuvent être trouvés dans l'ancien LunarLander exemple ici: http://developer.android.com/resources/samples/LunarLander/src/com/example/android/lunarlander/LunarView.html

En plus vous pouvez configurer la caméra SurfaceView de la même façon que cet exemple: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html

1voto

Pontus Gagge Points 12950

Ce code pourrait- il aider?

0voto

pootle Points 73

Juste trouvé un peu étrange réplique de mise à jour de mon combiné pour 4.0.4. J'ai un translucide gl totalité de l'écran de superposition sur l'ensemble de l'écran de prévisualisation de la caméra, qui a travaillé très heureux de la version ics construire (je pense que c'était 4.0.3, mais pas certain). Après la mise à jour 4.0.4, l'aperçu est allé un peu désordonnée, avec l'image de la caméra montrant psychédélique principales zones de couleur sur les parties les plus lumineuses de l'image de la caméra (parties plus foncées avait l'air correct). Finalement trouvé que la modification glclearcolour à 0,0,0,0 de 0.5, 0.5, 0.5. 0 il triés.

Il semble que, même si l'alpha était de zéro sur les parties non utilisées de la gl de superposition, la fonction fusion était toujours en tenant compte du gris gl arrière-plan.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X