how to capture an image in background without using the camera application

前端 未结 3 530
滥情空心
滥情空心 2020-11-29 02:04

I have an android app which consists of a Button.
When you click on Button, an image should be captured from the camera without opening the camera application (the image

相关标签:
3条回答
  • 2020-11-29 02:39

    You have to create a fake Surface view that doesn't appears to the users and then you can achieve by the following code

    public class MainActivity extends Activity {
        public static final int DONE = 1;
        public static final int NEXT = 2;
        public static final int PERIOD = 1;
        private Camera camera;
        private int cameraId = 0;
        private ImageView display;
        private Timer timer;
        SurfaceHolder previewHolder;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            display = (ImageView) findViewById(R.id.imageView1);
            // do we have a camera?
            if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) 
            {
                Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
                        .show();
            } 
            else 
            {
                cameraId = findFrontFacingCamera();
                if (cameraId < 0)
                {
                    Toast.makeText(this, "No front facing camera found.",
                            Toast.LENGTH_LONG).show();
                }
                else
                {
                    safeCameraOpen(cameraId);
                }
            }
            // THIS IS JUST A FAKE SURFACE TO TRICK THE CAMERA PREVIEW
            // http://stackoverflow.com/questions/17859777/how-to-take-pictures-in-android-
            // application-without-the-user-interface
    
    
            SurfaceView dummy = new SurfaceView(this);
            previewHolder = dummy.getHolder();
    
            previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            try {
                camera.setPreviewDisplay(previewHolder);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            /*SurfaceView view = new SurfaceView(this);
            try {
                //  camera.setPreviewDisplay(view.getHolder());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
    
            Camera.Parameters params = camera.getParameters();
            params.setJpegQuality(100);
            camera.setParameters(params);
            // We need something to trigger periodically the capture of a
            // picture to be processed
            timer = new Timer(getApplicationContext(), threadHandler);
            timer.execute();
        }
    
        // thread Handler //
        private Handler threadHandler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case DONE:
                    camera.startPreview();
                    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
                    try {
                        camera.setPreviewDisplay(previewHolder);
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
    
    
                    camera.takePicture(null, null, mCall);
                    break;
                case NEXT:
                    timer = new Timer(getApplicationContext(), threadHandler);
                    timer.execute();
                    break;
                }
            }
        };
        Camera.PictureCallback mCall = new Camera.PictureCallback() {
            public void onPictureTaken(byte[] data, Camera camera) {
                // decode the data obtained by the camera into a Bitmap
                // display.setImageBitmap(photo);
                Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0,
                        data.length);
                display.setImageBitmap(bitmapPicture);
                Message.obtain(threadHandler, MainActivity.NEXT, "").sendToTarget();
                // Log.v("MyActivity","Length: "+data.length);
            }
        };
    
        private int findFrontFacingCamera() {
            int cameraId = -1;
            // Search for the front facing camera
            int numberOfCameras = Camera.getNumberOfCameras();
            for (int i = 0; i < numberOfCameras; i++) {
                CameraInfo info = new CameraInfo();
                Camera.getCameraInfo(i, info);
                if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                    Log.v("MyActivity", "Camera found");
                    cameraId = i;
                    break;
                }
            }
            return cameraId;
        }
    
        @Override
        protected void onPause() {
            if (timer != null) {
                timer.cancel(true);
            }
            releaseCamera();
            super.onPause();
        }
    
        // I think Android Documentation recommends doing this in a separate
        // task to avoid blocking main UI
        private boolean safeCameraOpen(int id) {
            boolean qOpened = false;
            try {
                releaseCamera();
                camera = Camera.open(id);
                qOpened = (camera != null);
            } catch (Exception e) {
                Log.e(getString(R.string.app_name), "failed to open Camera");
                e.printStackTrace();
            }
            return qOpened;
        }
    
        private void releaseCamera() {
            if (camera != null) {
                camera.stopPreview();
                camera.release();
                camera = null;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 02:55

    Here is my whole working project of How to capture image in background without SurfaceView.

    // You can start your service to capturing image wherever you want not should from activity.

    also need to ask need permission in your Activity

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
    Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, APP_PERMISSION_REQUEST);
    } 
    

    handle intent in click or where you needed

    Intent front_translucent = new Intent(getApplication()
                            .getApplicationContext(), CameraService.class);
                    front_translucent.putExtra("Front_Request", true);
                    front_translucent.putExtra("Quality_Mode",
                            camCapture.getQuality());
                    getApplication().getApplicationContext().startService(
                            front_translucent);
    
    
    public class CamerService extends Service implements
            SurfaceHolder.Callback {
    
        // Camera variables
        // a surface holder
        // a variable to control the camera
        private Camera mCamera;
        // the camera parameters
        private Parameters parameters;
        private Bitmap bmp;
        FileOutputStream fo;
        private String FLASH_MODE;
        private int QUALITY_MODE = 0;
        private boolean isFrontCamRequest = false;
        private Camera.Size pictureSize;
        SurfaceView sv;
        private SurfaceHolder sHolder;
        private WindowManager windowManager;
        WindowManager.LayoutParams params;
        public Intent cameraIntent;
        SharedPreferences pref;
        Editor editor;
        int width = 0, height = 0;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate() {
            super.onCreate();
    
        }
    
        private Camera openFrontFacingCameraGingerbread() {
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.release();
            }
            int cameraCount = 0;
            Camera cam = null;
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            cameraCount = Camera.getNumberOfCameras();
            for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
                Camera.getCameraInfo(camIdx, cameraInfo);
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    try {
                        cam = Camera.open(camIdx);
                    } catch (RuntimeException e) {
                        Log.e("Camera",
                                "Camera failed to open: " + e.getLocalizedMessage());
                        /*
                         * Toast.makeText(getApplicationContext(),
                         * "Front Camera failed to open", Toast.LENGTH_LONG)
                         * .show();
                         */
                    }
                }
            }
            return cam;
        }
    
        private void setBesttPictureResolution() {
            // get biggest picture size
            width = pref.getInt("Picture_Width", 0);
            height = pref.getInt("Picture_height", 0);
    
            if (width == 0 | height == 0) {
                pictureSize = getBiggesttPictureSize(parameters);
                if (pictureSize != null)
                    parameters
                            .setPictureSize(pictureSize.width, pictureSize.height);
                // save width and height in sharedprefrences
                width = pictureSize.width;
                height = pictureSize.height;
                editor.putInt("Picture_Width", width);
                editor.putInt("Picture_height", height);
                editor.commit();
    
            } else {
                // if (pictureSize != null)
                parameters.setPictureSize(width, height);
            }
        }
    
        private Camera.Size getBiggesttPictureSize(Camera.Parameters parameters) {
            Camera.Size result = null;
    
            for (Camera.Size size : parameters.getSupportedPictureSizes()) {
                if (result == null) {
                    result = size;
                } else {
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;
    
                    if (newArea > resultArea) {
                        result = size;
                    }
                }
            }
    
            return (result);
        }
    
        /** Check if this device has a camera */
        private boolean checkCameraHardware(Context context) {
            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_CAMERA)) {
                // this device has a camera
                return true;
            } else {
                // no camera on this device
                return false;
            }
        }
    
        /** Check if this device has front camera */
        private boolean checkFrontCamera(Context context) {
            if (context.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_CAMERA_FRONT)) {
                // this device has front camera
                return true;
            } else {
                // no front camera on this device
                return false;
            }
        }
    
        Handler handler = new Handler();
    
        private class TakeImage extends AsyncTask<Intent, Void, Void> {
    
            @Override
            protected Void doInBackground(Intent... params) {
                takeImage(params[0]);
                return null;
            }
    
            @Override
            protected void onPostExecute(Void result) {
            }
        }
    
        private synchronized void takeImage(Intent intent) {
    
            if (checkCameraHardware(getApplicationContext())) {
                Bundle extras = intent.getExtras();
                if (extras != null) {
                    String flash_mode = extras.getString("FLASH");
                    FLASH_MODE = flash_mode;
    
                    boolean front_cam_req = extras.getBoolean("Front_Request");
                    isFrontCamRequest = front_cam_req;
    
                    int quality_mode = extras.getInt("Quality_Mode");
                    QUALITY_MODE = quality_mode;
                }
    
                if (isFrontCamRequest) {
    
                    // set flash 0ff
                    FLASH_MODE = "off";
                    // only for gingerbread and newer versions
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
    
                        mCamera = openFrontFacingCameraGingerbread();
                        if (mCamera != null) {
    
                            try {
                                mCamera.setPreviewDisplay(sv.getHolder());
                            } catch (IOException e) {
                                handler.post(new Runnable() {
    
                                    @Override
                                    public void run() {
                                        Toast.makeText(getApplicationContext(),
                                                "API dosen't support front camera",
                                                Toast.LENGTH_LONG).show();
                                    }
                                });
    
                                stopSelf();
                            }
                            Camera.Parameters parameters = mCamera.getParameters();  
                            pictureSize = getBiggesttPictureSize(parameters);
                            if (pictureSize != null)
                                parameters
                                        .setPictureSize(pictureSize.width, pictureSize.height);
    
                            // set camera parameters
                            mCamera.setParameters(parameters);
                            mCamera.startPreview();
                            mCamera.takePicture(null, null, mCall);
    
                            // return 4;
    
                        } else {
                            mCamera = null;
                            handler.post(new Runnable() {
    
                                @Override
                                public void run() {
                                    Toast.makeText(
                                            getApplicationContext(),
                                            "Your Device dosen't have Front Camera !",
                                            Toast.LENGTH_LONG).show();
                                }
                            });
    
                            stopSelf();
                        }
                        /*
                         * sHolder = sv.getHolder(); // tells Android that this
                         * surface will have its data // constantly // replaced if
                         * (Build.VERSION.SDK_INT < 11)
                         * 
                         * sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
                         */
                    } else {
                        if (checkFrontCamera(getApplicationContext())) {
                            mCamera = openFrontFacingCameraGingerbread();
    
                            if (mCamera != null) {
    
                                try {
                                    mCamera.setPreviewDisplay(sv.getHolder());
                                } catch (IOException e) {
                                    handler.post(new Runnable() {
    
                                        @Override
                                        public void run() {
                                            Toast.makeText(
                                                    getApplicationContext(),
                                                    "API dosen't support front camera",
                                                    Toast.LENGTH_LONG).show();
                                        }
                                    });
    
                                    stopSelf();
                                }
                                Camera.Parameters parameters = mCamera.getParameters();  
                                pictureSize = getBiggesttPictureSize(parameters);
                                if (pictureSize != null)
                                    parameters
                                            .setPictureSize(pictureSize.width, pictureSize.height);
    
                                // set camera parameters
                                mCamera.setParameters(parameters);
                                mCamera.startPreview();
                                mCamera.takePicture(null, null, mCall);
                                // return 4;
    
                            } else {
                                mCamera = null;
                                /*
                                 * Toast.makeText(getApplicationContext(),
                                 * "API dosen't support front camera",
                                 * Toast.LENGTH_LONG).show();
                                 */
                                handler.post(new Runnable() {
    
                                    @Override
                                    public void run() {
                                        Toast.makeText(
                                                getApplicationContext(),
                                                "Your Device dosen't have Front Camera !",
                                                Toast.LENGTH_LONG).show();
    
                                    }
                                });
    
                                stopSelf();
    
                            }
                            // Get a surface
                            /*
                             * sHolder = sv.getHolder(); // tells Android that this
                             * surface will have its data // constantly // replaced
                             * if (Build.VERSION.SDK_INT < 11)
                             * 
                             * sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS
                             * );
                             */
                        }
    
                    }
    
                } else {
    
                    if (mCamera != null) {
                        mCamera.stopPreview();
                        mCamera.release();
                        mCamera = Camera.open();
                    } else
                        mCamera = getCameraInstance();
    
                    try {
                        if (mCamera != null) {
                            mCamera.setPreviewDisplay(sv.getHolder());
                            parameters = mCamera.getParameters();
                            if (FLASH_MODE == null || FLASH_MODE.isEmpty()) {
                                FLASH_MODE = "auto";
                            }
                            parameters.setFlashMode(FLASH_MODE);
                            // set biggest picture
                            setBesttPictureResolution();
                            // log quality and image format
                            Log.d("Qaulity", parameters.getJpegQuality() + "");
                            Log.d("Format", parameters.getPictureFormat() + "");
    
                            // set camera parameters
                            mCamera.setParameters(parameters);
                            mCamera.startPreview();
                            Log.d("ImageTakin", "OnTake()");
                            mCamera.takePicture(null, null, mCall);
                        } else {
                            handler.post(new Runnable() {
    
                                @Override
                                public void run() {
                                    Toast.makeText(getApplicationContext(),
                                            "Camera is unavailable !",
                                            Toast.LENGTH_LONG).show();
                                }
                            });
    
                        }
                        // return 4;
    
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        Log.e("TAG", "CmaraHeadService()::takePicture", e);
                    }
                    // Get a surface
                    /*
                     * sHolder = sv.getHolder(); // tells Android that this surface
                     * will have its data constantly // replaced if
                     * (Build.VERSION.SDK_INT < 11)
                     * 
                     * sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
                     */
    
                }
    
            } else {
                // display in long period of time
                /*
                 * Toast.makeText(getApplicationContext(),
                 * "Your Device dosen't have a Camera !", Toast.LENGTH_LONG)
                 * .show();
                 */
                handler.post(new Runnable() {
    
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Your Device dosen't have a Camera !",
                                Toast.LENGTH_LONG).show();
                    }
                });
                stopSelf();
            }
    
            // return super.onStartCommand(intent, flags, startId);
    
        }
    
        @SuppressWarnings("deprecation")
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // sv = new SurfaceView(getApplicationContext());
            cameraIntent = intent;
            Log.d("ImageTakin", "StartCommand()");
            pref = getApplicationContext().getSharedPreferences("MyPref", 0);
            editor = pref.edit();
    
            windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    
            params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_PHONE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);
    
            params.gravity = Gravity.TOP | Gravity.LEFT;
            params.width = 1;
            params.height = 1;
            params.x = 0;
            params.y = 0;
            sv = new SurfaceView(getApplicationContext());
    
            windowManager.addView(sv, params);
            sHolder = sv.getHolder();
            sHolder.addCallback(this);
    
            // tells Android that this surface will have its data constantly
            // replaced
            if (Build.VERSION.SDK_INT < 11)
                sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            return 1;
        }
    
        Camera.PictureCallback mCall = new Camera.PictureCallback() {
    
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                // decode the data obtained by the camera into a Bitmap
                Log.d("ImageTakin", "Done");
                if (bmp != null)
                    bmp.recycle();
                System.gc();
                bmp = decodeBitmap(data);
                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                if (bmp != null && QUALITY_MODE == 0)
                    bmp.compress(Bitmap.CompressFormat.JPEG, 70, bytes);
                else if (bmp != null && QUALITY_MODE != 0)
                    bmp.compress(Bitmap.CompressFormat.JPEG, QUALITY_MODE, bytes);
    
                File imagesFolder = new File(
                        Environment.getExternalStorageDirectory(), "MYGALLERY");
                if (!imagesFolder.exists())
                    imagesFolder.mkdirs(); // <----
                File image = new File(imagesFolder, System.currentTimeMillis()
                        + ".jpg");
    
                // write the bytes in file
                try {
                    fo = new FileOutputStream(image);
                } catch (FileNotFoundException e) {
                    Log.e("TAG", "FileNotFoundException", e);
                    // TODO Auto-generated catch block
                }
                try {
                    fo.write(bytes.toByteArray());
                } catch (IOException e) {
                    Log.e("TAG", "fo.write::PictureTaken", e);
                    // TODO Auto-generated catch block
                }
    
                // remember close de FileOutput
                try {
                    fo.close();
                    if (Build.VERSION.SDK_INT < 19)
                        sendBroadcast(new Intent(
                                Intent.ACTION_MEDIA_MOUNTED,
                                Uri.parse("file://"
                                        + Environment.getExternalStorageDirectory())));
                    else {
                        MediaScannerConnection
                                .scanFile(
                                        getApplicationContext(),
                                        new String[] { image.toString() },
                                        null,
                                        new MediaScannerConnection.OnScanCompletedListener() {
                                            public void onScanCompleted(
                                                    String path, Uri uri) {
                                                Log.i("ExternalStorage", "Scanned "
                                                        + path + ":");
                                                Log.i("ExternalStorage", "-> uri="
                                                        + uri);
                                            }
                                        });
                    }
    
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (mCamera != null) {
                    mCamera.stopPreview();
                    mCamera.release();
                    mCamera = null;
                }
                /*
                 * Toast.makeText(getApplicationContext(),
                 * "Your Picture has been taken !", Toast.LENGTH_LONG).show();
                 */
                com.integreight.onesheeld.Log.d("Camera", "Image Taken !");
                if (bmp != null) {
                    bmp.recycle();
                    bmp = null;
                    System.gc();
                }
                mCamera = null;
                handler.post(new Runnable() {
    
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Your Picture has been taken !", Toast.LENGTH_SHORT)
                                .show();
                    }
                });
                stopSelf();
            }
        };
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        public static Camera getCameraInstance() {
            Camera c = null;
            try {
                c = Camera.open(); // attempt to get a Camera instance
            } catch (Exception e) {
                // Camera is not available (in use or does not exist)
            }
            return c; // returns null if camera is unavailable
        }
    
        @Override
        public void onDestroy() {
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }
            if (sv != null)
                windowManager.removeView(sv);
            Intent intent = new Intent("custom-event-name");
            // You can also include some extra data.
            intent.putExtra("message", "This is my message!");
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    
            super.onDestroy();
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            if (cameraIntent != null)
                new TakeImage().execute(cameraIntent);
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }
        }
    
        public static Bitmap decodeBitmap(byte[] data) {
    
            Bitmap bitmap = null;
            BitmapFactory.Options bfOptions = new BitmapFactory.Options();
            bfOptions.inDither = false; // Disable Dithering mode
            bfOptions.inPurgeable = true; // Tell to gc that whether it needs free
                                            // memory, the Bitmap can be cleared
            bfOptions.inInputShareable = true; // Which kind of reference will be
                                                // used to recover the Bitmap data
                                                // after being clear, when it will
                                                // be used in the future
            bfOptions.inTempStorage = new byte[32 * 1024];
    
            if (data != null)
                bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
                        bfOptions);
    
            return bitmap;
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 02:55

    If you are using CAMERA2 API (added in API 21), then kindly check my answer here Capture picture without preview using camera2 API

    Hope that helped :)

    0 讨论(0)
提交回复
热议问题