0

Hi I've been doing this for 4 days but I can't solve it. I have a class which is the camera preview class and I created a get bitmap function inside the class and I want to call this function in another class to get the bitmap.

This is my coding for calling the get bitmap function:

public class Stage extends GLSurfaceView {

private float w, h;
private int screenWidth, screenHeight;
private String img;
private boolean SC;
private Bitmap screen, imgB;
private boolean c;
MyRenderer mRenderer;
//here declare class of camera <<<<<<<
CameraSurfaceView csv;

public Stage(Context context, AttributeSet attrs) {
    super(context, attrs);
    setEGLConfigChooser(8, 8, 8, 8, 0, 0);
    getHolder().setFormat(PixelFormat.TRANSPARENT);
    setZOrderOnTop(true);
    mRenderer = new MyRenderer();
    setRenderer(mRenderer);
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    //here the camera class declare.........
    csv = new CameraSurfaceView(context);
}

public class MyRenderer implements GLSurfaceView.Renderer {

    public void setSC(boolean yn){
        SC = yn;
        requestRender();
    }

    public void setC(boolean y){
        c=y;
    }

    public final void onDrawFrame(GL10 gl) {
        gl.glClear(GLES10.GL_COLOR_BUFFER_BIT);

        if(SC==true){

            if(c==true){
                //capture camera scene and convert to Bitmap
                //here is the code of get bitmap for camera class
                imgB = csv.getCameraBitmap();
            }
            else{


            }

            String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/OpenGL";
            File dir = new File(file_path);
            if(!dir.exists()){
                dir.mkdirs();
            }
            String format = new SimpleDateFormat("yyyyMMddHHmmss", java.util.Locale.getDefault()).format(new Date());
            File file = new File(file_path, format + ".png");
            FileOutputStream fOut;
            try {
                fOut = new FileOutputStream(file);
                imgB.compress(Bitmap.CompressFormat.PNG, 85, fOut);
                fOut.flush();
                fOut.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            SC = false;
        }
    }

    public final void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glClearColor(0, 0, 0, 0);

        if(width > height) {
            h = 600;
            w = width * h / height;
        } else {
            w = 600;
            h = height * w / width;
        }
        screenWidth = width;
        screenHeight = height;


        gl.glViewport(0, 0, screenWidth, screenHeight);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0, w, h, 0, -1, 1);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public final void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // Set up alpha blending
        gl.glEnable(GL10.GL_ALPHA_TEST);
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

        // We are in 2D. Why needs depth?
        gl.glDisable(GL10.GL_DEPTH_TEST);

        // Enable vertex arrays (we'll use them to draw primitives).
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        // Enable texture coordination arrays.
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        tex.load(getContext());
    }

}

}

This is my camera class:

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraSurfaceView";

private SurfaceHolder mSurfaceHolder;
private Camera mCamera = null;
private Bitmap mBitmap;
private Context mContext;
private Camera.Parameters mParameters;
private byte[] byteArray;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
Bitmap cameraBitmap;

public CameraSurfaceView (Context context) {
    this(context, null);
}

public CameraSurfaceView (Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public CameraSurfaceView (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mContext = context;

    try {
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceCreated(final SurfaceHolder surfaceHolder) {
    if (mCamera == null) {
        try {
            mCamera = Camera.open();
        } catch (RuntimeException ignored) {
        }
    }

    try {
        if (mCamera != null) {
            WindowManager winManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
            mCamera.setPreviewDisplay(mSurfaceHolder);
        }
    } catch (Exception e) {
        if (mCamera != null)
            mCamera.release();
        mCamera = null;
    }

    if (mCamera == null) {
        return;
    } else {
        mCamera.setPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] bytes, Camera camera) {
                if (mParameters == null)
                {
                    return;
                }
                byteArray = bytes;
                cameraBitmap = getBitmap();
            }
        });
    }

    setWillNotDraw(false);
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
    try {
        mParameters = mCamera.getParameters();

        List<Camera.Size> cameraSize = mParameters.getSupportedPreviewSizes();
        mPreviewSize = cameraSize.get(0);

        for (Camera.Size s : cameraSize) {
            if ((s.width * s.height) > (mPreviewSize.width * mPreviewSize.height)) {
                mPreviewSize = s;
            }
        }

        mParameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setParameters(mParameters);
        mCamera.startPreview();

    } catch (Exception e) {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }
}


@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    if (mCamera != null) {
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
}

public Bitmap getBitmap() {
    try {
        if (mParameters == null)
            return null;

        if (mPreviewSize == null)
            return null;

        int format = mParameters.getPreviewFormat();
        YuvImage yuvImage = new YuvImage(byteArray, format, mPreviewSize.width, mPreviewSize.height, null);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        Rect rect = new Rect(0, 0, mPreviewSize.width, mPreviewSize.height);

        yuvImage.compressToJpeg(rect, 75, byteArrayOutputStream);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPurgeable = true;
        options.inInputShareable = true;
        mBitmap = BitmapFactory.decodeByteArray(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size(), options);

        byteArrayOutputStream.flush();
        byteArrayOutputStream.close();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }

    return mBitmap;
}

public Bitmap getCameraBitmap() {
    return cameraBitmap;
}
}

Any guidance will be appreciated~

fadden
  • 51,356
  • 5
  • 116
  • 166
Le Parkour
  • 97
  • 1
  • 15

1 Answers1

0

To start working with the camera, you must display the CameraSurfaceView - create it "in the air" is not enough. Please see a recent related discussion: Take a photo using a service on OnePlus One - using WindowManager hack.

You don't need the takePicture() part, but waiting for a preview frame to be cloned into byteArray is similarly asynchronous.

The bottom line is, you can not receive the bitmap synchronously. You can request a bitmap, and have it delivered in a callback, e.g.

CameraSurfaceView csv = new CameraSurfaceView(getContext());
((Activity) getContext()).addContentsView(csv);
csv.requestBitmap(imageView);

and somewhere in CameraSurfaceView.java:

public void onPreviewFrame(byte[] bytes, Camera camera) {
  byteArray = bytes;
  Bitmap imgB = getBitmap();
  imageView.setBitmap(imgB);
}
Community
  • 1
  • 1
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307