Android Open Source - FxCameraApp Gl Preview






From Project

Back to project page FxCameraApp.

License

The source code is released under:

MIT License

If you think the Android project FxCameraApp listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.af.experiments.FxCameraApp.View;
/*  w ww .j a  v  a2s.com*/
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import com.af.experiments.FxCameraApp.Utils.Fps;
import com.af.experiments.FxCameraApp.Utils.OpenGlUtils;
import com.af.experiments.FxCameraApp.camera.CameraHelper;
import com.af.experiments.FxCameraApp.ogles.*;
import com.af.experiments.FxCameraApp.renderer.GLES20FramebufferObject;
import com.af.experiments.FxCameraApp.renderer.GlFrameBufferObjectRenderer;
import com.af.experiments.FxCameraApp.shaders.GlPreviewShader;
import com.af.experiments.FxCameraApp.shaders.GlShader;
import com.af.experiments.FxCameraApp.shaders.fx.GlLutShader;

import javax.microedition.khronos.egl.EGLConfig;
import java.io.IOException;

import static android.opengl.GLES20.*;

public class GlPreview  extends GLSurfaceView implements CameraView.Preview, Camera.PictureCallback {

    CameraHelper mCameraHelper;
    Renderer mRenderer;

    boolean mFaceMirror = true;
    public GlPreview(final Context context) {
        super(context);
        initialize(context);
    }

    public GlPreview(final Context context, final AttributeSet attrs) {
        super(context, attrs);
        initialize(context);
    }

    private void initialize(final Context context) {
        setEGLConfigChooser(new GLES20ConfigChooser(false));
        setEGLContextFactory(new GLES20ContextFactory());

        mRenderer = new Renderer();
        setRenderer(mRenderer);

        setRenderMode(RENDERMODE_WHEN_DIRTY);
    }

    public final boolean isFaceMirror() {
        return mFaceMirror;
    }

    public final void setFaceMirror(final boolean mirror) {
        mFaceMirror = mirror;
    }

    private GlShader mShader;

    public void setShader(final GlShader shader) {
        mShader = shader;
        queueEvent(new Runnable() {
            @Override
            public void run() {
                mRenderer.setShader(shader);
            }
        });
    }
    public void setInputTexture(final Texture texture) {
        queueEvent(new Runnable() {
            @Override
            public void run() {
                mRenderer.setTexture(texture);
            }
        });
    }

    public void setFps(final Fps fps) {
        queueEvent(new Runnable() {
            @Override
            public void run() {
                mRenderer.setFps(fps);
            }
        });
    }

    //////////////////////////////////////////////////////////////////////////

    @Override
    public void setCameraHelper(final CameraHelper helper) {
        mCameraHelper = helper;
    }

    @Override
    public boolean isSquareFrameSupported() {
        return true;
    }
    @Override public void onOpenCamera() {}

    @Override public void onReleaseCamera() {}

    private boolean mPreviewing;

    private int mMeasurePreviewWidth;
    private int mMeasurePreviewHeight;
    private CameraView.CameraStateListener mCameraStateListener;
    private boolean mWaitingStartPreview;

    @Override
    public void startPreview(final int measurePreviewWidth, final int measurePreviewHeight, final CameraView.CameraStateListener listener) {
        synchronized (this) {
            mMeasurePreviewWidth = measurePreviewWidth;
            mMeasurePreviewHeight = measurePreviewHeight;
            mCameraStateListener = listener;

            if (mRenderer.mMaxTextureSize != 0) {
                startPreview();
            } else {
                mWaitingStartPreview = true;
            }
        }
    }

    void onRendererInitialized() {
        if (mWaitingStartPreview) {
            mWaitingStartPreview = false;
            startPreview();
        }
    }

    private void startPreview() {
        synchronized (this) {
            mPreviewing = false;

            if (mMeasurePreviewWidth > 0 && mMeasurePreviewHeight > 0) {
                mCameraHelper.setupOptimalPreviewSizeAndPictureSize(mMeasurePreviewWidth, mMeasurePreviewHeight, mRenderer.mMaxTextureSize);
            }
            requestLayout();

            queueEvent(new Runnable() {
                @Override
                public void run() {
                    mRenderer.onStartPreview();
                }
            });
        }
    }

    void onStartPreviewFinished() {
        synchronized (this) {
            if (!mPreviewing && mCameraHelper.isOpened()) {
                mCameraHelper.startPreview();
                mPreviewing = true;

                if (mCameraStateListener != null) {
                    mCameraStateListener.onStartPreview();
                    mCameraStateListener = null;
                }
            }
        }
    }

    @Override
    public void onStopPreview() {
        synchronized (this) {
            mWaitingStartPreview = false;
            mPreviewing = false;
        }
    }

    private CameraView.CaptureCallback mCaptureCallback;

    @Override
    public void takePicture(final CameraView.CaptureCallback callback) {
        takePicture(callback, true);
    }

    @Override
    public void takePicture(final CameraView.CaptureCallback callback, final boolean autoFocus) {
        mCaptureCallback = callback;
        mCameraHelper.takePicture(this, autoFocus);
    }

    @Override
    public void onPictureTaken(final byte[] data, final Camera camera) {
        mCameraHelper.stopPreview();
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        Renderer finalRenderer = new Renderer();
        if (mShader instanceof GlLutShader) {
            //((GlLutShader) mShader).reset();
        }
        finalRenderer.setShader(mShader);
        PixelBuffer buffer = new PixelBuffer(bitmap.getWidth(), bitmap.getHeight());
        buffer.setRenderer(finalRenderer);
        finalRenderer.setTexture(new GlImageBitmapTexture(bitmap, false));
        bitmap = buffer.getBitmap();
        buffer.destroy();
        onImageCapture(bitmap);
    }


    public void capture(final CameraView.CaptureCallback callback) {
        mCaptureCallback = callback;

        queueEvent(new Runnable() {
            @Override
            public void run() {
                mRenderer.capture();
            }
        });
    }

    void onImageCapture(final Bitmap bitmap) {
        if (!mCaptureCallback.onImageCapture(bitmap) && bitmap != null) {
            bitmap.recycle();
        }
        mCaptureCallback = null;
    }

    private final class Renderer extends GlFrameBufferObjectRenderer implements PreviewTexture.OnFrameAvailableListener {

        private static final String TAG = "GLES20Preview.Renderer";

        private final Handler mHandler = new Handler();

        private PreviewTexture mPreviewTexture;
        private boolean mUpdateSurface = false;

        private Texture mImageTexture;
        private boolean mUploadTexture;

        private int mTexName;

        private float[] mMVPMatrix  = new float[16];
        private float[] mProjMatrix = new float[16];
        private float[] mMMatrix    = new float[16];
        private float[] mVMatrix    = new float[16];
        private float[] mSTMatrix   = new float[16];
        private float mCameraRatio  = 1.0f;

        private GLES20FramebufferObject mFramebufferObject;
        private GlPreviewShader mPreviewShader;
        private GlPreviewShader mImageShader;

        private GlShader mShader;
        private boolean mIsNewShader;
        int mMaxTextureSize;

        public Renderer() {
            super();
            Matrix.setIdentityM(mSTMatrix, 0);
        }

        public void setShader(final GlShader shader) {
            if (mShader != null) {
                mShader.release();
            }
            if (shader != null) {
                mIsNewShader = true;
            }
            mShader = shader;
            mIsNewShader = true;
            requestRender();
        }

        public void onStartPreview() {
            Matrix.setIdentityM(mMMatrix, 0);
            Matrix.rotateM(mMMatrix, 0, -mCameraHelper.getOptimalOrientation(), 0.0f, 0.0f, 1.0f);
            if (mCameraHelper.isFaceCamera() && !mFaceMirror) {
                Matrix.scaleM(mMMatrix, 0, 1.0f, -1.0f, 1.0f);
            }

            final Camera.Size previewSize = mCameraHelper.getPreviewSize();
            mCameraRatio = (float) previewSize.width / previewSize.height;

            try {
                mPreviewTexture.setup(mCameraHelper);
            } catch (final IOException e) {
                Log.e(TAG, "Cannot set preview texture target!");
            }

            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    onStartPreviewFinished();
                }
            });
        }

        public void setTexture(final Texture texture) {
            synchronized (this) {
                if (mImageTexture != null) {
                    mImageTexture.release();
                }
                Matrix.setIdentityM(mMMatrix, 0);
                mImageTexture = texture;
                mUploadTexture = true;
            }
            requestRender();
        }

        private static final int GINGERBREAD = 9;

        public void capture() {
            final Bitmap bitmap;
            if (mCameraHelper != null) {
                bitmap= getBitmap(mCameraHelper.getOrientation(), Integer.parseInt(Build.VERSION.SDK) < GINGERBREAD && mCameraHelper.isFaceCamera());
            } else {
                bitmap= getBitmap();
            }
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    onImageCapture(bitmap);
                }
            });
        }

        @Override
        public void onSurfaceCreated(final EGLConfig config) {
            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

            final int[] args = new int[1];

            glGenTextures(args.length, args, 0);
            mTexName = args[0];

            mPreviewTexture = GlPreviewTextureFactory.newPreviewTexture(mTexName);
            mPreviewTexture.setOnFrameAvailableListener(this);

            glBindTexture(mPreviewTexture.getTextureTarget(), mTexName);
            OpenGlUtils.setupSampler(mPreviewTexture.getTextureTarget(), GL_LINEAR, GL_NEAREST);
            glBindTexture(GL_TEXTURE_2D, 0);

            mFramebufferObject = new GLES20FramebufferObject();
            mPreviewShader = new GlPreviewShader(mPreviewTexture.getTextureTarget());
            mPreviewShader.setup();
            mImageShader = new GlPreviewShader(GL_TEXTURE_2D);
            mImageShader.setup();

            Matrix.setLookAtM(mVMatrix, 0,
                    0.0f, 0.0f, 5.0f,
                    0.0f, 0.0f, 0.0f,
                    0.0f, 1.0f, 0.0f
            );

            synchronized (this) {
                mUpdateSurface = false;
            }
            if (mImageTexture != null) {
                mUploadTexture = true;
            }
            if (mShader != null) {
                mIsNewShader = true;
            }

            glGetIntegerv(GL_MAX_TEXTURE_SIZE, args, 0);
            mMaxTextureSize = args[0];

            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    onRendererInitialized();
                }
            });
        }

        @Override
        public void onSurfaceChanged(final int width, final int height) {
            mFramebufferObject.setup(width, height);
            mPreviewShader.setFrameSize(width, height);
            mImageShader.setFrameSize(width, height);
            if (mShader != null) {
                mShader.setFrameSize(width, height);
            }

            final float aspectRatio = (float) width / height;
            Matrix.frustumM(mProjMatrix, 0, -aspectRatio, aspectRatio, -1, 1, 5, 7);
        }

        @Override
        public void onDrawFrame(final GLES20FramebufferObject fbo) {

            synchronized (this) {
                if (mUpdateSurface) {
                    mPreviewTexture.updateTexImage();
                    mPreviewTexture.getTransformMatrix(mSTMatrix);
                    mUpdateSurface = false;
                }
            }

            if (mUploadTexture) {
                mImageTexture.setup();
                mCameraRatio = (float) mImageTexture.getWidth() / mImageTexture.getHeight();
                Matrix.setIdentityM(mSTMatrix, 0);
                mUploadTexture = false;
            }

            if (mIsNewShader) {
                if (mShader != null) {
                    mShader.setup();
                    mShader.setFrameSize(fbo.getWidth(), fbo.getHeight());
                }
                mIsNewShader = false;
            }

            if (mShader != null) {
                mFramebufferObject.enable();
                glViewport(0, 0, mFramebufferObject.getWidth(), mFramebufferObject.getHeight());
            }

            glClear(GL_COLOR_BUFFER_BIT);

            Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);      // ????????????????????????????
            Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);  // ???????????????????

            if (mImageTexture != null) {
                mImageShader.draw(mImageTexture.getTexName(), mMVPMatrix, mSTMatrix, mCameraRatio);
            } else {
                mPreviewShader.draw(mTexName, mMVPMatrix, mSTMatrix, mCameraRatio);
            }

            if (mShader != null) {
                fbo.enable();
                glViewport(0, 0, fbo.getWidth(), fbo.getHeight());
                glClear(GL_COLOR_BUFFER_BIT);
                mShader.draw(mFramebufferObject.getTexName(), fbo);
            }
        }

        @Override
        public synchronized void onFrameAvailable(final PreviewTexture previewTexture) {
            mUpdateSurface = true;
            requestRender();
        }
    }
}




Java Source Code List

com.af.experiments.FxCameraApp.FilterAdapter.java
com.af.experiments.FxCameraApp.MyActivity.java
com.af.experiments.FxCameraApp.Utils.BitmapFactoryUtils.java
com.af.experiments.FxCameraApp.Utils.ExifUtils.java
com.af.experiments.FxCameraApp.Utils.Fps.java
com.af.experiments.FxCameraApp.Utils.LogWriter.java
com.af.experiments.FxCameraApp.Utils.OpenGlUtils.java
com.af.experiments.FxCameraApp.View.CameraView.java
com.af.experiments.FxCameraApp.View.DefaultPreview.java
com.af.experiments.FxCameraApp.View.GlPreview.java
com.af.experiments.FxCameraApp.View.PreviewTexture.java
com.af.experiments.FxCameraApp.camera.CameraHelperBase.java
com.af.experiments.FxCameraApp.camera.CameraHelperCupcake.java
com.af.experiments.FxCameraApp.camera.CameraHelperDonut.java
com.af.experiments.FxCameraApp.camera.CameraHelperEclair.java
com.af.experiments.FxCameraApp.camera.CameraHelperFactory.java
com.af.experiments.FxCameraApp.camera.CameraHelperFroyo.java
com.af.experiments.FxCameraApp.camera.CameraHelperGingerbread.java
com.af.experiments.FxCameraApp.camera.CameraHelperHonycomb.java
com.af.experiments.FxCameraApp.camera.CameraHelperICS.java
com.af.experiments.FxCameraApp.camera.CameraHelper.java
com.af.experiments.FxCameraApp.display.DisplayHelperBase.java
com.af.experiments.FxCameraApp.display.DisplayHelperFactory.java
com.af.experiments.FxCameraApp.display.DisplayHelperFroyo.java
com.af.experiments.FxCameraApp.display.DisplayHelperHoneycombMR2.java
com.af.experiments.FxCameraApp.display.DisplayHelperHoneycomb.java
com.af.experiments.FxCameraApp.display.DisplayHelper.java
com.af.experiments.FxCameraApp.ogles.DefaultConfigChooser.java
com.af.experiments.FxCameraApp.ogles.DefaultContextFactory.java
com.af.experiments.FxCameraApp.ogles.DefaultWindowSurfaceFactory.java
com.af.experiments.FxCameraApp.ogles.EGLLogWrapper.java
com.af.experiments.FxCameraApp.ogles.GLES20ConfigChooser.java
com.af.experiments.FxCameraApp.ogles.GLES20ContextFactory.java
com.af.experiments.FxCameraApp.ogles.GlImageBitmapTexture.java
com.af.experiments.FxCameraApp.ogles.GlImageResourceTexture.java
com.af.experiments.FxCameraApp.ogles.GlImageTexture.java
com.af.experiments.FxCameraApp.ogles.GlPreviewTextureFactory.java
com.af.experiments.FxCameraApp.ogles.GlSurfaceTexture.java
com.af.experiments.FxCameraApp.ogles.GlTextureView.java
com.af.experiments.FxCameraApp.ogles.PixelBuffer.java
com.af.experiments.FxCameraApp.ogles.PreviewSurfaceHelperBase.java
com.af.experiments.FxCameraApp.ogles.PreviewSurfaceHelperFactory.java
com.af.experiments.FxCameraApp.ogles.PreviewSurfaceHelper.java
com.af.experiments.FxCameraApp.ogles.Texture.java
com.af.experiments.FxCameraApp.renderer.GLES20FramebufferObject.java
com.af.experiments.FxCameraApp.renderer.GlFrameBufferObjectRenderer.java
com.af.experiments.FxCameraApp.renderer.MainRenderer.java
com.af.experiments.FxCameraApp.shaders.GlBilateralShader.java
com.af.experiments.FxCameraApp.shaders.GlBoxBlurShader.java
com.af.experiments.FxCameraApp.shaders.GlBulgeDistortionShader.java
com.af.experiments.FxCameraApp.shaders.GlCGAColorspaceShader.java
com.af.experiments.FxCameraApp.shaders.GlColorInvertShader.java
com.af.experiments.FxCameraApp.shaders.GlColorMatrixShader.java
com.af.experiments.FxCameraApp.shaders.GlColorPackingShader.java
com.af.experiments.FxCameraApp.shaders.GlConvolutionShader.java
com.af.experiments.FxCameraApp.shaders.GlEmbossShader.java
com.af.experiments.FxCameraApp.shaders.GlFalseColorShader.java
com.af.experiments.FxCameraApp.shaders.GlFastBlurShader.java
com.af.experiments.FxCameraApp.shaders.GlGaussianBlurShader.java
com.af.experiments.FxCameraApp.shaders.GlGlassSphereShader.java
com.af.experiments.FxCameraApp.shaders.GlGrayScaleShader.java
com.af.experiments.FxCameraApp.shaders.GlHarrisCornerDetectionShader.java
com.af.experiments.FxCameraApp.shaders.GlHazeShader.java
com.af.experiments.FxCameraApp.shaders.GlMonochromeShader.java
com.af.experiments.FxCameraApp.shaders.GlNobleCornerDetectionShader.java
com.af.experiments.FxCameraApp.shaders.GlPerlinNoiseShader.java
com.af.experiments.FxCameraApp.shaders.GlPinchDistortionShader.java
com.af.experiments.FxCameraApp.shaders.GlPixellateShader.java
com.af.experiments.FxCameraApp.shaders.GlPolarPixellateShader.java
com.af.experiments.FxCameraApp.shaders.GlPolkaDotShader.java
com.af.experiments.FxCameraApp.shaders.GlPosterizeShader.java
com.af.experiments.FxCameraApp.shaders.GlPreviewShader.java
com.af.experiments.FxCameraApp.shaders.GlSepiaShader.java
com.af.experiments.FxCameraApp.shaders.GlShaderGroup.java
com.af.experiments.FxCameraApp.shaders.GlShader.java
com.af.experiments.FxCameraApp.shaders.GlSharpenShader.java
com.af.experiments.FxCameraApp.shaders.GlShiTomasiFeatureDetectionShader.java
com.af.experiments.FxCameraApp.shaders.GlSobelEdgeDetectionShader.java
com.af.experiments.FxCameraApp.shaders.GlSphereRefractionShader.java
com.af.experiments.FxCameraApp.shaders.GlStretchDistortionShader.java
com.af.experiments.FxCameraApp.shaders.GlThreex3ConvolutionShader.java
com.af.experiments.FxCameraApp.shaders.GlThreex3TextureSamplingShader.java
com.af.experiments.FxCameraApp.shaders.GlToneShader.java
com.af.experiments.FxCameraApp.shaders.GlTwoInputShader.java
com.af.experiments.FxCameraApp.shaders.GlVignetteShader.java
com.af.experiments.FxCameraApp.shaders.GlWeakPixelInclusionShader.java
com.af.experiments.FxCameraApp.shaders.GlWhiteBalanceShader.java
com.af.experiments.FxCameraApp.shaders.GlXRayShader.java
com.af.experiments.FxCameraApp.shaders.GlXYDerivativeShader.java
com.af.experiments.FxCameraApp.shaders.fx.GlLutShader.java