相机

时间:2017-03-01 09:46:57

标签: android android-camera

我想在没有之前的情况下从相机中获取图像。

这是我的 mainactivity.java

    public class MainActivity extends AppCompatActivity {

    private Camera mCamera;
    private byte[] mVideoSource;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);


        mCamera = Camera.open();

        mCamera.setPreviewCallback(new Camera.PreviewCallback() {

int j =2;
            public void onPreviewFrame(final byte[] data, final Camera camera) {
                // Process the contents of byte for whatever you need
                j++;
            }
        });

            mCamera.setDisplayOrientation(0);

            // Finds a suitable resolution.
            Size size= new Size(640,480);


            // Set-up camera size and video format. YCbCr_420_SP
            // should be the default on Android anyway.

            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(size.getWidth(), size.getHeight());

            parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP);
            mCamera.setParameters(parameters);

            PixelFormat pixelFormat = new PixelFormat();
            PixelFormat.getPixelFormatInfo(mCamera.getParameters()
                    .getPreviewFormat(), pixelFormat);

            int sourceSize = size.getWidth() * size.getHeight()
                    * pixelFormat.bitsPerPixel / 8;
            mVideoSource = new byte[sourceSize];

            // Starts receiving pictures from the camera.
            mCamera.addCallbackBuffer(mVideoSource);
            mCamera.startPreview();    
    }

我不明白为什么程序永远不会通过PreviewCallback。在变量中,预览回调函数似乎已经很好地改变了。

事实上我只想从相机中抓取图像。

编辑: 以下是我给你的链接所做的修改。

public class AGLSurfaceView extends GLSurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {

    private final AGLRenderer mRenderer;
    Camera mCamera;

    public AGLSurfaceView(Context context) {
        super(context);

        // Create an OpenGL ES 2.0 context.
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        mRenderer = new AGLRenderer(context);
        setRenderer(mRenderer);

        // Render the view only when there is a change in the drawing data
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);




    }

    private final float TOUCH_SCALE_FACTOR = 180.0f / 3200;
    private float mPreviousX;
    private float mPreviousY;

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        // MotionEvent reports input details from the touch screen
        // and other input controls. In this case, you are only
        // interested in events where the touch position changed.

        float x = e.getX();
        float y = e.getY();

        switch (e.getAction()) {
            case MotionEvent.ACTION_MOVE:

                float dx = x - mPreviousX;
                float dy = y - mPreviousY;

                // reverse direction of rotation above the mid-line
                if (y > getHeight() / 2) {
                    dx = dx * -1 ;
                }

                // reverse direction of rotation to left of the mid-line
                if (x < getWidth() / 2) {
                    dy = dy * -1 ;
                }

                mRenderer.setAngle(mRenderer.getAngleX() + dy * TOUCH_SCALE_FACTOR,
                        mRenderer.getAngleY() + dx * TOUCH_SCALE_FACTOR);  // = 180.0f / 320
                requestRender();
        }

        mPreviousX = x;
        mPreviousY = y;
        return true;
    }

    public void setBackground(Bitmap b)
    {
        mRenderer.setBackground(b);
    }

    public void setAngle(float X,float Y,float Z)
    {
        mRenderer.setAngle(X,Y,Z);
        requestRender();
    }

    public void surfaceCreated(SurfaceHolder holder) {

        mCamera = Camera.open();
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewSize(640, 480);
        mCamera.setParameters(p);

        try {
            mCamera.setPreviewDisplay(getHolder());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        mCamera.startPreview();
        mCamera.setPreviewCallback(this);
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {



      int i = 1;
}

和渲染

public class AGLRenderer implements GLSurfaceView.Renderer {

    private static final String TAG = "AGLRenderer";
    private BackgroundTexture mBackgroundTexture;
    private SquareTexture mSquareTexture;
    private Square mSquare;

    // mMVPMatrix is an abbreviation for "Model View Projection Matrix"
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    private final float[] mRotationMatrix = new float[16];
    private final float[] mRotationMatrixlX = new float[16];
    private final float[] mRotationMatrixlY = new float[16];
    private final float[] mRotationMatrixX = new float[16];
    private final float[] mRotationMatrixY = new float[16];
    private final float[] mRotationMatrixZ = new float[16];
    private final float[] mRotationMatrix0 = new float[16];

    float angleX ,angleY ,angleZ ;
    private float mAngleX;
    private float mAngleY;

    Context localcontext;
    public AGLRenderer(Context context) {
        super();
        localcontext = context;
    }


    public void setAngle(float X,float Y,float Z)
    {
        angleX = X;
        angleY = Y;
        angleZ = Z;

    }

    @Override
    public void onSurfaceCreated(GL10 unused, EGLConfig config) {


        angleX = 0;
        angleY = 0;
        angleZ = 0;

        // Set the background frame color
        GLES20.glClearColor(1.0f, 0.1f, 0.0f, 1.0f);

        mSquareTexture = new SquareTexture(localcontext);
        mSquare = new Square();
        mBackgroundTexture = new BackgroundTexture(localcontext);
        mBackgroundTexture.loadTexture();


    }

    @Override
    public void onDrawFrame(GL10 unused) {
        float[] scratch = new float[16];

        // Draw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);



        // Set the camera position (View matrix)
        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

//        Matrix.setRotateM(mRotationMatrix0, 0, angleX, 0, 1.0f, 0);
        Matrix.setRotateM(mRotationMatrixX, 0, angleX, 0, 1,0);
        Matrix.setRotateM(mRotationMatrixY, 0, angleY, 0, 0,1);
        Matrix.setRotateM(mRotationMatrixZ, 0, angleZ, 1, 0,0);

//        for(int j=0;j<4;j++)
//        {
//          for(int i=0;i<4;i++)
//            {
//              Log.d("tt"," "+(mRotationMatrix0[j*4+i]));
//            }
//        }
        Matrix.multiplyMM(mRotationMatrix0, 0,mRotationMatrixY , 0,  mRotationMatrixZ, 0);
        Matrix.multiplyMM(mRotationMatrix0, 0,mRotationMatrix0 , 0,  mRotationMatrixX, 0);
        Matrix.multiplyMM(mRotationMatrix, 0,mRotationMatrix0  , 0, mViewMatrix , 0);

        // Calculate the projection and view transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mRotationMatrix, 0);

        // Draw square
        //mSquareTexture.draw(mMVPMatrix);
        mSquare.draw(mMVPMatrix);
        //mBackgroundTexture.draw();

    }

    @Override
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        // Adjust the viewport based on geometry changes,
        // such as screen rotation
        GLES20.glViewport(0, 0, width, height);

        float ratio = (float) width / height;

        // this projection matrix is applied to object coordinates
        // in the onDrawFrame() method
        Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 50);

    }

    /**
     * Utility method for compiling a OpenGL shader.
     *
     * <p><strong>Note:</strong> When developing shaders, use the checkGlError()
     * method to debug shader coding errors.</p>
     *
     * @param type - Vertex or fragment shader type.
     * @param shaderCode - String containing the shader code.
     * @return - Returns an id for the shader.
     */
    public static int loadShader(int type, String shaderCode){

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);


        return shader;
    }

    /**
    * Utility method for debugging OpenGL calls. Provide the name of the call
    * just after making it:
    *
    * <pre>
    * mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
    * AGLRenderer.checkGlError("glGetUniformLocation");</pre>
    *
    * If the operation is not successful, the check throws an error.
    *
    * @param glOperation - Name of the OpenGL call to check.
    */
    public static void checkGlError(String glOperation) {
        int error;
        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
            Log.e(TAG, glOperation + ": glError " + error);
            throw new RuntimeException(glOperation + ": glError " + error);
        }
    }

    /**
     * Returns the rotation angle of the triangle shape (mTriangle).
     *
     * @return - A float representing the rotation angle.
     */
    public float getAngleX() {
        return mAngleX;
    }
    public float getAngleY() {
        return mAngleY;
    }

    /**
     * Sets the rotation angle of the triangle shape (mTriangle).
     */
    public void setAngle(float angleX,float angleY) {
        mAngleX = angleX;
        mAngleY = angleY;

    }

    public void setBackground(Bitmap background)
    {
        mBackgroundTexture.loadTexture(background);
    }

}

我在GLSurfaceView上预览了我的相机,但程序不再通过GLSurfaceView.Renderer的onSurfaceCreated,ondrawframe。怎么可能呢?

实际上我的目标是显示相机图像并能够在其上方绘制3d对象。

编辑:

我发现其他程序是我的主要活动:

public class MainActivity extends AppCompatActivity{



 GLSurfaceView glView;
    CameraView cameraView;
    GLClearRenderer clearRenderer;
    @Override
    public void onCreate( Bundle savedInstanceState ) {
        super.onCreate( savedInstanceState );

        // When working with the camera, it's useful to stick to one orientation.
        setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE );

        // Next, we disable the application's title bar...
        requestWindowFeature( Window.FEATURE_NO_TITLE );
        // ...and the notification bar. That way, we can use the full screen.
        getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN );

        // Now let's create an OpenGL surface.
        glView = new GLSurfaceView( this );
        // To see the camera preview, the OpenGL surface has to be created translucently.
        // See link above.
        glView.setEGLConfigChooser( 8, 8, 8, 8, 16, 0 );
        glView.getHolder().setFormat( PixelFormat.TRANSLUCENT );
        // The renderer will be implemented in a separate class, GLView, which I'll show next.
        clearRenderer = new GLClearRenderer();
        glView.setRenderer( clearRenderer );
        // Now set this as the main view.
        setContentView( glView );

        // Now also create a view which contains the camera preview...
        cameraView = new CameraView( this );
        // ...and add it, wrapping the full screen size.
        addContentView( cameraView, new ActionBar.LayoutParams( ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT ) );
    }

    public class GLClearRenderer implements GLSurfaceView.Renderer {

        private BackgroundTexture mBackgroundTexture;
        private SquareTexture mSquareTexture;
        private Square mSquare;

        // mMVPMatrix is an abbreviation for "Model View Projection Matrix"
        private final float[] mMVPMatrix = new float[16];
        private final float[] mProjectionMatrix = new float[16];
        private final float[] mViewMatrix = new float[16];
        private final float[] mRotationMatrix = new float[16];
        private final float[] mRotationMatrixlX = new float[16];
        private final float[] mRotationMatrixlY = new float[16];
        private final float[] mRotationMatrixX = new float[16];
        private final float[] mRotationMatrixY = new float[16];
        private final float[] mRotationMatrixZ = new float[16];
        private final float[] mRotationMatrix0 = new float[16];

        float angleX ,angleY ,angleZ ;
        private float mAngleX;
        private float mAngleY;

        public void onDrawFrame( GL10 gl ) {
            // This method is called per frame, as the name suggests.
            // For demonstration purposes, I simply clear the screen with a random translucent gray.
            float c = 1.0f / 256 * ( System.currentTimeMillis() % 256 );
            GLES20.glClearColor( c, c, c, 0.5f );
            GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT );

            // Draw background color
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);


            // Set the camera position (View matrix)
            Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

            // Calculate the projection and view transformation
            Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

            // Draw square
            mSquare.draw(mMVPMatrix); %%%%%%% NOT DISPLAY
        }


        public void onSurfaceChanged( GL10 gl, int width, int height ) {
            // This is called whenever the dimensions of the surface have changed.
            // We need to adapt this change for the GL viewport.
            GLES20.glViewport( 0, 0, width, height );

            float ratio = (float) width / height;

            // this projection matrix is applied to object coordinates
            // in the onDrawFrame() method
            Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 50);
        }

        public void onSurfaceCreated( GL10 gl, EGLConfig config ) {
            // No need to do anything here.

            angleX = 0;
            angleY = 0;
            angleZ = 0;

            // Set the background frame color
            //GLES20.glClearColor(1.0f, 0.1f, 0.0f, 1.0f);

            mSquare = new Square(); %%%%%%% NOT DISPLAY

        }
    }

    public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
        private Camera camera;

        public CameraView( Context context ) {
            super( context );
            // We're implementing the Callback interface and want to get notified
            // about certain surface events.
            getHolder().addCallback( this );
            // We're changing the surface to a PUSH surface, meaning we're receiving
            // all buffer data from another component - the camera, in this case.
            getHolder().setType( SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS );
        }

        public void surfaceCreated( SurfaceHolder holder ) {
            // Once the surface is created, simply open a handle to the camera hardware.
            camera = Camera.open();
        }

        public void surfaceChanged( SurfaceHolder holder, int format, int width, int height ) {
            // This method is called when the surface changes, e.g. when it's size is set.
            // We use the opportunity to initialize the camera preview display dimensions.
            Camera.Parameters p = camera.getParameters();
            p.setPreviewSize( width, height );
            //camera.setParameters( p );

            // We also assign the preview display to this surface...
            try {
                camera.setPreviewDisplay( holder );
            } catch( IOException e ) {
                e.printStackTrace();
            }
            // ...and start previewing. From now on, the camera keeps pushing preview
            // images to the surface.
            camera.startPreview();
        }

        public void surfaceDestroyed( SurfaceHolder holder ) {
            // Once the surface gets destroyed, we stop the preview mode and release
            // the whole camera since we no longer need it.
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    }


}

屏幕闪烁有效,但我使用的方块不显示。我不明白为什么。

1 个答案:

答案 0 :(得分:0)

查看此主题,了解如何创建预览类以在同一活动中显示相机预览 -  https://developer.android.com/guide/topics/media/camera.html