April 11, 2020 /   android   screenshot   bitmap   canvas

While developing android apps, many times we come across a feature where we want to save or download an Android View as Image for many purposes like sharing it externally. Most common use cases where we need to save a view are -

► To save a collage which contains multiple Image Views inside a parent View

► Save Image and text combinations that are contained inside a view

► Saving Photo Frames where a photo is fitted inside a frame where either Photo is at background or Frame is at background.

Android Save View as Image

We can save a view as image using Canvas and Bitmap. We will first create a Bitmap and then we will save Bitmap to storage as Image.

Creating Bitmap from View

private Bitmap generateBimap(View view) {

        // Create a bitmap with same dimensions as view
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);

        // Create a canvas using bitmap
        Canvas canvas = new Canvas(bitmap);

        /**
          We need to check if view as backround image. 
          It is important in case of overlays like photo frame feature
        */
        Drawable baground = view.getBackground();
        if (baground != null) {
            baground.draw(canvas);
        } else {
            canvas.drawColor(Color.WHITE);
        }

        // draw the view on the canvas
        view.draw(canvas);

        // final bitmap
        return bitmap;
}

Saving Bitmap as Image

private String saveImage(Bitmap bitmap) {

        // Get the destination folder for saved images defined in strings.xml
        String dstFolder = getString(R.string.dst_folder);

    // Create Destination folder in external storage. This will require EXTERNAL STORAGE permission
        File externalStorageDirectory = Environment.getExternalStorageDirectory();
        File imgDir = new File(externalStorageDirectory.getAbsolutePath(), dstFolder);
        imgDir.mkdirs();

        // Generate a random file name for image
        String imageName = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".jpeg";
        File localFile = new File(imgDir, imageName);
        localFile.renameTo(localFile);
        String path = "file://" + externalStorageDirectory.getAbsolutePath() + "/" + dstFolder;

        try {
            FileOutputStream fos = new FileOutputStream(localFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
            sendBroadcast(new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE", Uri.fromFile(new File(path))));
        } catch (Exception e)  {
            e.printStackTrace();
        }

    // Local path to be shown to User to tell where the Image has been saved.
        return path;
}

Sharing Image externally

private void share(Bitmap bitmap) {
        try {
            Uri shareUri = getImageUri(this, bitmap);
            Intent localIntent = new Intent();
            localIntent.setAction("android.intent.action.SEND");
            localIntent.putExtra("android.intent.extra.STREAM", shareUri);
            localIntent.setType("image/jpg");
            localIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            this.startActivity(localIntent);
        } catch (Exception e) {
            Toast.makeText(this, "" + e, Toast.LENGTH_LONG).show();
        }
}

private Uri getImageUri(Context context, Bitmap bitmap) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), bitmap, "Title", null);
        return Uri.parse(path);
}