44

I would like to write an android app that basically layers an overlay on image on another image and then I would like to save the picture with the overlay as a jpg or png. Basically this will be the whole view that I would like to save.

Sample code would be very helpful.

EDIT:

I tried out your suggestions and am getting a null pointer at the Starred Line.

 import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.os.Bundle;
import android.os.Environment;
import android.widget.LinearLayout;
import android.widget.TextView;

    public class EditPhoto extends Activity {
        /** Called when the activity is first created. */
     LinearLayout ll = null;
     TextView tv = null;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            tv = (TextView) findViewById(R.id.text);
            ll = (LinearLayout) findViewById(R.id.layout);
            ll.setDrawingCacheEnabled(true);
            Bitmap b = ll.getDrawingCache();
            File sdCard = Environment.getExternalStorageDirectory();
            File file = new File(sdCard, "image.jpg");
            FileOutputStream fos;
      try {
       fos = new FileOutputStream(file);
       *** b.compress(CompressFormat.JPEG, 95,fos);
      } catch (FileNotFoundException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }

        }
    }
shaneburgess
  • 15,702
  • 15
  • 47
  • 66

3 Answers3

100

You can take advantage of a View's drawing cache.

view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
b.compress(CompressFormat.JPEG, 95, new FileOutputStream("/some/location/image.jpg"));

Where view is your View. The 95 is the quality of the JPG compression. And the file output stream is just that.

Moncader
  • 3,388
  • 3
  • 22
  • 28
  • I tried your code, but where does the root starts for the FileOutputStream? beacause I tried to look in the folders of the emulator and couldn't find the saved image... – Sephy Aug 21 '10 at 12:21
  • 2
    It starts at the phones root. So if you want to load something from the sdcard, use the Environment.getExternalStorageDirectory() to get the root for the sdcard. – Moncader Aug 21 '10 at 15:38
  • So can a LinerLayout be the view in this case and will that grab anything in the LinearLayout? – shaneburgess Aug 23 '10 at 21:16
  • 3
    It looks like it works thanks and to you goes almost all of my rep :). Thanks guys!! – shaneburgess Aug 24 '10 at 01:38
  • On Android 4.3 the provided code does only capture the actual viewable lines of a view. The text which is scrolled outside the viewable area is not captured. Does anyone know a solution for this problem? – kirsche40 Apr 22 '14 at 11:11
  • 1
    I fixed my issue. See [my solution here](https://stackoverflow.com/a/23242744/598802) – kirsche40 Apr 23 '14 at 11:25
  • Unfortunately, this does not work for me. I either get the only the image from the camera feed or I only get the graphic layover. Any ideas? – VollNoob Apr 23 '18 at 14:47
  • Does `view.setDrawingCacheEnabled(true);` have any adverse effects? Why is it false by default? – mcy Aug 12 '21 at 12:54
7
File sdCard = Environment.getExternalStorageDirectory();
File file = new File(sdCard, "image.jpg");
FileOutputStream fos = new FileOutputStream(file);

Use fos reference as a 3rd parameter of b.compress() method in Moncader's answer. The image will be stored as image.jpg in root directory of your sd card.

plugmind
  • 7,926
  • 4
  • 34
  • 39
6

Save RelativeLayout or any view to image (.jpg)

String getSaveImageFilePath() {
    File mediaStorageDir = new File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), YOUR_FOLDER_NAME);
    // Create a storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d(YOUR_FOLDER_NAME, "Failed to create directory");
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageName = "IMG_" + timeStamp + ".jpg";

    String selectedOutputPath = mediaStorageDir.getPath() + File.separator + imageName;
    Log.d(YOUR_FOLDER_NAME, "selected camera path " + selectedOutputPath);

    view.setDrawingCacheEnabled(true);
    view.buildDrawingCache();
    Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());

    int maxSize = 1080;

    int bWidth = bitmap.getWidth();
    int bHeight = bitmap.getHeight();

    if (bWidth > bHeight) {
        int imageHeight = (int) Math.abs(maxSize * ((float)bitmap.getWidth() / (float) bitmap.getHeight()));
        bitmap = Bitmap.createScaledBitmap(bitmap, maxSize, imageHeight, true);
    } else {
        int imageWidth = (int) Math.abs(maxSize * ((float)bitmap.getWidth() / (float) bitmap.getHeight()));
        bitmap = Bitmap.createScaledBitmap(bitmap, imageWidth, maxSize, true);
    }
    view.setDrawingCacheEnabled(false);
    view.destroyDrawingCache();

    OutputStream fOut = null;
    try {
        File file = new File(selectedOutputPath);
        fOut = new FileOutputStream(file);

        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        fOut.flush();
        fOut.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return selectedOutputPath;
}
Harikesh
  • 311
  • 4
  • 6