8

I have been working on a camera app and everything is working with taking and saving the picture. But I would like to have the Imageview I show when taking the picture to be saved in the actual picture when it is taken. Is that possible?

Right now I have been trying to have the imageView in the same Layout as where I draw the camera preview.

<FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    >

    <ImageView
        android:layout_width="50pt"
        android:layout_height="50pt"
        android:layout_gravity="center"
        android:src="@android:drawable/star_big_on"
        />

</FrameLayout>

I thought that maybe if it was drawn on the same view as the camera is then it would also saw that image together with the picture.

Does anyone know if this is possible or do I have to take another approach? If so, links to other solutions on how to do this would be appreciated :)

Thanks!

Edit: I have been following this camera tutorial http://developer.android.com/guide/topics/media/camera.html#manifest If anyone is wondering how I save the picture etc

Edit2: For clarification, I want the star in this example to be shown in the taken picture after you take it. So if I take a picture of a wall, I want the star to be shown on that wall when you look at the picture in the gallery afterwards, just as it is when taking the picture!

Morti
  • 175
  • 1
  • 7
  • You mean before storing the picture, you want to show the user in an `ImageView`, the same picture which was taken using camera? – Sash_KP Sep 09 '14 at 11:31
  • No I want the image that is shown with the imageView to be saved with the picture. So if I have a star in the center, I want that star to be shown in the picture! – Morti Sep 09 '14 at 11:46
  • 1
    Okay i get it now and upvoted your question.Good question.I am gonna answer it.Just give me a moment. – Sash_KP Sep 09 '14 at 11:56
  • Please check my answer and lemme know if it is what you want. – Sash_KP Sep 09 '14 at 12:34

3 Answers3

5

What you exactly want is a LayerDrawable -

A Drawable that manages an array of other Drawables. These are drawn in array order, so the element with the largest index will be drawn on top.

You have two choices to use LayerDrawable.You can either define it in a separate drawable xml and then simply set the image in your ImageView, or you can configure a LayerDrawable dynamically in your code.However as you want this to happen dynamically you would require the programmatic approach mentioned below.

Programmatically using code

You need to convert your Bitmap(which you must have gotten after capturing a picture) into a Drawable.For that use BitmapDrawable like this :

Resources r = getResources();
Drawable d = new BitmapDrawable(r,yourBitmap);//converting bitmap to drawable    
Drawable[] layers = new Drawable[2];
layers[0] = d;
layers[1] = r.getDrawable(R.drawable.star_big_on);
LayerDrawable layerDrawable = new LayerDrawable(layers);
imageView.setImageDrawable(layerDrawable);

Now you have your ImageView having two images(1.your captured image and 2.star_big_on) set on it.

Edit

As you want the newly created image(with 2 images added to it) to be stored in the gallery, you would do something like this in order to store your image :

int width = layerDrawable.getIntrinsicWidth();
int height = layerDrawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); 
layerDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
layerDrawable.draw(canvas);
//and then the following line will store it in the gallery
MediaStore.Images.Media.insertImage(getContentResolver(), bitmap , "yourTitle" , "yourDescription");

Now by doing like above your image will be added to the end of the gallery.If you want it to be stored in the start of gallery, refer this code.

And if you want the original image which was stored in the gallery just after you clicked a photo, to be deleted from the gallery, you can refer this SO question.In this question you will see something like file.getPath(), which is nothing but the path of the required image to be deleted.So if you want to get the path of the captured image, refer this SO question.Hopefully now you have every idea with you to achieve what you exactly want.

Note : In case you want to know how you use LayerDrawable via XML

Using XML

Create a new Drawable XML file, let's call it mylayer.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:drawable="@drawable/yourcapturedimage" />
   <item android:drawable="@drawable/star_big_on" />
</layer-list>

Now in your Activity set the image using that Drawable:

imageView.setImageDrawable(getResources().getDrawable(R.layout.mylayer));
Community
  • 1
  • 1
Sash_KP
  • 5,551
  • 2
  • 25
  • 34
  • This is almost what I am looking for. But I dont want to show the final picture in the ImageView. The picture is already shown in the gallery when I take it. I want the picture in the imageView to be **included** in the picture when I take it. – Morti Sep 09 '14 at 12:55
  • Please see my edited answer.Hopefully this will solve your problem now. – Sash_KP Sep 09 '14 at 14:01
0

I would do it this way. Works for me:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == REQUEST_IMAGE_CAPTURE) {
            if (resultCode == getActivity().RESULT_OK) {
                // successfully captured the image
                // display it in image view
                previewCapturedImage();
            } else if (resultCode == getActivity().RESULT_CANCELED) {
                // user cancelled Image capture
                Toast.makeText(getActivity().getApplicationContext(), "User cancelled image capture", Toast.LENGTH_SHORT).show();

            } else {
                // failed to capture image
                Toast.makeText(getActivity().getApplicationContext(),"Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void previewCapturedImage() {
        try {

            // bitmap factory
            BitmapFactory.Options options = new BitmapFactory.Options();

            // downsizing image as it throws OutOfMemory Exception for larger
            // images
            options.inSampleSize = 8;

            final Bitmap bitmap = BitmapFactory.decodeFile(imageUri.getPath(),options);
            toto.setImageBitmap(bitmap);
            shareCapturedImage();
        } catch (NullPointerException e) {
            e.printStackTrace();
            cam.release();
        }
    }

    private void shareCapturedImage() {
        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("image/*");
        share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(mediaFile));
        startActivity(Intent.createChooser(share,"Share with:"));
    }

Don't forget to declare the ImageView in the onCreate method too as follows:

ImageView img = (ImageView) rootView.findViewById(R.id.img);

The xml would similar to this:

<ImageView
    android:id="@+id/img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true" />

Hope this helps :)

Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79
0

Maybe Overlay approach can help you. after capturing your image convert it to bit map then send your capturing image and the image you want to save to this method:

private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
    Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(),   bmp1.getConfig());
    Canvas canvas = new Canvas(bmOverlay);
    canvas.drawBitmap(bmp1, new Matrix(), null);
    canvas.drawBitmap(bmp2, new Matrix(), null);
    return bmOverlay;
} 

Hope to solve your problem.