Search code examples
androidbitmapandroid-camerasurfaceviewfront-camera

Android take photo with a custom UI


In my app I have to take a picture with the FRONT CAMERA, but I do NOT need to use the camera app. I have a custom layout with a button to take the picture. Also I need to save the photo to a Bitmap because I have to send it to my webservice.

An example would be really helpful.

I have gone through the Official Documentation but I didn't get it too well. I know that I have to use a CameraPreview class and A CameraACtivity but so far I couldn't make it. Need help.


Solution

  • There you go dude, this code does exactly what you are looking for:

    You can download the whole project from here and play with it.

    public class MainActivity extends Activity implements SurfaceHolder.Callback
    {
        private final int ANIMATION_DURATION = 500;
        private final int MEDIA_TYPE_IMAGE = 1;
        private final int MEDIA_TYPE_VIDEO = 2;
        private Context context = MainActivity.this;
        private Camera camera;
        private SurfaceView surfaceView;
        private SurfaceHolder surfaceHolder;
        private ImageView btn_shutter;
        private LinearLayout btn_layout;
        private TextView btn_retake;
        private TextView btn_keep;
        private boolean previewing = false;
        private ImageView temp_pic;
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.main_layout);
    
            surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
            btn_shutter = (ImageView) findViewById(R.id.btn_shutter);
            btn_layout = (LinearLayout) findViewById(R.id.btn_layout);
            btn_retake = (TextView) findViewById(R.id.btn_retake);
            btn_keep = (TextView) findViewById(R.id.btn_keep);
            temp_pic = (ImageView) findViewById(R.id.temp_pic);
    
            try
            {
                surfaceHolder = surfaceView.getHolder();
                surfaceHolder.addCallback(this);
                surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    
                camera = Camera.open();
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
                previewing = true;
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
    
            OnClickListener click = new OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    switch(v.getId())
                    {
                        case R.id.btn_shutter:
                        {
                            camera.takePicture(null, null, mPicture);
    
                            onTakePick();
                            break;
                        }
                        case R.id.btn_retake:
                        {
                            camera.startPreview();
    
                            onRetakePic();
    
                            break;
                        }
                        case R.id.btn_keep:
                        {
                            new TakeScreeShot().execute();
    
                            break;
                        }
                    }
                }
            };
    
            btn_shutter.setOnClickListener(click);
            btn_retake.setOnClickListener(click);
            btn_keep.setOnClickListener(click);
        }
    
    
    
    
        private final String TAG = "horia";
        private PictureCallback mPicture = new PictureCallback()
        {
            @Override
            public void onPictureTaken(byte [] data, Camera camera)
            {
                new ProcessRawBitmap(data).execute();
            }
        };
    
    
    
        public static Bitmap getBitmapFromBytes(byte[] imageContent)
        {
            try
            {
                return BitmapFactory.decodeByteArray(imageContent, 0, imageContent.length);
            }
            catch(Exception e)
            {
                e.printStackTrace();
                return null;
            }
        }
    
    
    
        private void onRetakePic()
        {
            temp_pic.setVisibility(View.GONE);
            surfaceView.setVisibility(View.VISIBLE);
    
            final TranslateAnimation anim_hide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, 
                                                                        Animation.RELATIVE_TO_SELF, 0, 
                                                                        Animation.RELATIVE_TO_PARENT, 0, 
                                                                        Animation.RELATIVE_TO_PARENT, 1);
            anim_hide.setDuration(ANIMATION_DURATION);
            anim_hide.setFillAfter(true);
    
            anim_hide.setAnimationListener(new AnimationListener()
            {
                @Override
                public void onAnimationStart(Animation animation)
                {
    
                }
    
                @Override
                public void onAnimationRepeat(Animation animation)
                {
    
                }
    
                @Override
                public void onAnimationEnd(Animation animation)
                {
                    btn_layout.setVisibility(View.GONE);
                    btn_layout.setAnimation(null);
    
                    final TranslateAnimation anim_show = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, 
                                                                                Animation.RELATIVE_TO_SELF, 0, 
                                                                                Animation.RELATIVE_TO_PARENT, 1,
                                                                                Animation.RELATIVE_TO_PARENT, 0);
                    anim_show.setDuration(ANIMATION_DURATION);
                    anim_show.setFillAfter(true);
    
                    anim_show.setAnimationListener(new AnimationListener()
                    {
                        @Override
                        public void onAnimationStart(Animation animation)
                        {
                            btn_shutter.setVisibility(View.VISIBLE);
                        }
    
                        @Override
                        public void onAnimationRepeat(Animation animation)
                        {
    
                        }
    
                        @Override
                        public void onAnimationEnd(Animation animation)
                        {
                            btn_shutter.setAnimation(null);
                        }
                    });
    
                    btn_shutter.startAnimation(anim_show);
                }
            });
    
            btn_layout.startAnimation(anim_hide);
        }
    
    
    
        private void onTakePick()
        {
            final TranslateAnimation anim_hide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, 
                                                                                Animation.RELATIVE_TO_SELF, 0, 
                                                                                Animation.RELATIVE_TO_PARENT, 0, 
                                                                                Animation.RELATIVE_TO_PARENT, 1);
            anim_hide.setDuration(ANIMATION_DURATION);
            anim_hide.setFillAfter(true);
    
            anim_hide.setAnimationListener(new AnimationListener()
            {
                @Override
                public void onAnimationStart(Animation animation)
                {
    
                }
    
                @Override
                public void onAnimationRepeat(Animation animation)
                {
    
                }
    
                @Override
                public void onAnimationEnd(Animation animation)
                {
                    btn_shutter.setVisibility(View.GONE);
                    btn_shutter.setAnimation(null);
    
                    final TranslateAnimation anim_show = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, 
                                                                                        Animation.RELATIVE_TO_SELF, 0, 
                                                                                        Animation.RELATIVE_TO_PARENT, 1, 
                                                                                        Animation.RELATIVE_TO_PARENT, 0);
                    anim_show.setDuration(ANIMATION_DURATION);
                    anim_show.setFillAfter(true);
    
                    anim_show.setAnimationListener(new AnimationListener()
                    {
                        @Override
                        public void onAnimationStart(Animation animation)
                        {
                            btn_layout.setVisibility(View.VISIBLE);
                        }
    
                        @Override
                        public void onAnimationRepeat(Animation animation)
                        {
    
                        }
    
                        @Override
                        public void onAnimationEnd(Animation animation)
                        {
                            btn_layout.setAnimation(null);
                        }
                    });
    
                    btn_layout.startAnimation(anim_show);
                }
            });
    
            btn_shutter.startAnimation(anim_hide);
        }
    
    
    
        @Override
        protected void onDestroy()
        {
            super.onDestroy();
    
            try
            {
                try
                {
                    if(null != camera)
                    {
                        camera.stopPreview();
                        camera.release();
                        camera = null;
                    }
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
        {
            try
            {
                if (previewing)
                {
                    camera.stopPreview();
                }
    
                if(null != camera)
                {
                    Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
    
                    if(display.getRotation() == Surface.ROTATION_0)
                    {
    //                  LOG.x("ROTATION_0");
                        camera.setDisplayOrientation(90);
                    }
    
                    if(display.getRotation() == Surface.ROTATION_90)
                    {
    //                  LOG.x("ROTATION_90");
                    }
    
                    if(display.getRotation() == Surface.ROTATION_180)
                    {
    //                  LOG.x("ROTATION_180");
                    }
    
                    if(display.getRotation() == Surface.ROTATION_270)
                    {
    //                  LOG.x("ROTATION_270");
                        camera.setDisplayOrientation(180);
                    }
    
                    previewCamera();
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    
    
        @Override
        public void surfaceCreated(SurfaceHolder holder)
        {
    
        }
    
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder)
        {
    
        }
    
    
    
        public void previewCamera()
        {        
            try 
            {
                camera.setPreviewDisplay(surfaceHolder);          
                camera.startPreview();
                previewing = true;
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    
    
    
        private File getOutputMediaFile(int type)
        {
            if (true == isExternalStoragePresent())
            {
                File mediaStorageDir = new File(Environment.getExternalStorageDirectory().toString() + "/MyTestPicsFolder");
    
                if (!mediaStorageDir.exists())
                {
                    if (!mediaStorageDir.mkdirs())
                    {
                        Log.d("MyCameraApp", "failed to create directory");
                        return null;
                    }
                }
    
                String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                File mediaFile;
    
                if (type == MEDIA_TYPE_IMAGE)
                {
                    mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
                }
                else if (type == MEDIA_TYPE_VIDEO)
                {
                    mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");
                }
                else
                {
                    return null;
                }
    
                return mediaFile;
            }
            else
            {
                try
                {
                    new AlertDialog.Builder(context).setMessage("No storage space found, can't save the video.").setPositiveButton("Ok", null).show();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
    
                return null;
            }
        }
    
    
    
        private class TakeScreeShot extends AsyncTask<Object, Object, Object>
        {
            @Override
            protected Object doInBackground(Object... params)
            {
                try
                {
                    View v1 = getWindow().getDecorView().getRootView();
                    v1.setDrawingCacheEnabled(true);
    
                    Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
                    v1.setDrawingCacheEnabled(false);
    
                    File imageFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);      
                    if (imageFile == null)
                    {
                        Log.d(TAG, "Error creating media file, check storage permissions");
                        return null;
                    }
    
    
                    OutputStream fout = new FileOutputStream(imageFile);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
                    fout.flush();
                    fout.close();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
    
                return null;
            }
        }
    
    
    
        private Bitmap bitmapRotate(File f)
        {
            try
            {
                ExifInterface exif = new ExifInterface(f.getPath());
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
    
                int angle = 0;
    
                if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
                {
                    angle = 90;
                }
                else if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
                {
                    angle = 180;
                }
                else if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
                {
                    angle = 270;
                }
    
                Matrix mat = new Matrix();
                mat.postRotate(angle);
    
                Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, null);
                return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
            }
            catch (Exception e)
            {
                e.printStackTrace();
                return null;
            }
        }
    
    
    
        private class ProcessRawBitmap extends AsyncTask<Object, Object, Object>
        {
            private byte [] data;
    
            public ProcessRawBitmap(byte [] data)
            {
                this.data = data;
            }
    
            @Override
            protected Object doInBackground(Object... params)
            {
                Bitmap bit = getBitmapFromBytes(data);
    
                File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
    
                if (pictureFile == null)
                {
                    Log.d(TAG, "Error creating media file, check storage permissions");
                    return null;
                }
    
                try
                {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();
    
                    bit = bitmapRotate(pictureFile);
    
                    if(null != bit)
                    {
                        temp_pic.setVisibility(View.VISIBLE);
                        temp_pic.setImageBitmap(bit);
                        surfaceView.setVisibility(View.GONE);
                    }
    
                    pictureFile.delete();
                }
                catch (Exception e)
                {
                    Log.d(TAG, "File not found: " + e.getMessage());
                }
                return null;
            }
        }
    
    
        public static boolean isExternalStoragePresent()
        {
            boolean mExternalStorageAvailable = false;
            boolean mExternalStorageWriteable = false;
            String state = Environment.getExternalStorageState();
    
            if (Environment.MEDIA_MOUNTED.equals(state))
            {
                // We can read and write the media
                mExternalStorageAvailable = mExternalStorageWriteable = true;
            }
            else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state))
            {
                // We can only read the media
                mExternalStorageAvailable = true;
                mExternalStorageWriteable = false;
            }
            else
            {
                mExternalStorageAvailable = mExternalStorageWriteable = false;
            }
            if (false == ((mExternalStorageAvailable) && (mExternalStorageWriteable)))
            {
                // Toast.makeText(context, "SD card not present",
            }
    
            return (mExternalStorageAvailable) && (mExternalStorageWriteable);
        }
    }