Hey everyone! I'm brand new to Android and have been working on a very basic app that just takes a picture with an image overlay and saves it. So far I have figured out how to get the camera preview, take a picture, and do an image overlay on the camera preview. I'm at the point where I want to save the camera image and the overlay as one image. The problem I'm running into is that it's saving just the overlay on a black background. So the image from the camera isn't showing up in the saved image, even though it's there. Here's my code. Any help would really be appreciated.

package com.commonsware.android.skeleton;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.hardware.Camera;
import android.hardware.Camera.*;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

// ----------------------------------------------------------------------

public class SimpleBulbActivity extends Activity {
    private Preview mPreview;
    private static final String TAG = "CameraDemo";
    RelativeLayout preview;
    Camera mCamera;

	protected void onCreate(Bundle savedInstanceState) {

        // Hide the window title.
        // create a File object for the parent directory
		File imageDirectory = new File(Environment.getExternalStorageDirectory() + "/SimpleBulb/");
		// Check if the directory exists
		if(!imageDirectory.exists()) {
			// have the object build the directory structure, if needed.
    protected void onResume() {
        //Setup the FrameLayout with the Camera Preview Screen
        mPreview = new Preview(this);
        preview = (RelativeLayout)findViewById(R.id.preview); 
    public void snap(View view) {
    	mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
    ShutterCallback shutterCallback = new ShutterCallback() {
  	  public void onShutter() {
  		  Log.d(TAG, "onShutter'd");
  	PictureCallback rawCallback = new PictureCallback() {
  	  public void onPictureTaken(byte[] _data, Camera _camera) {
  		  Log.d(TAG, "onPictureTaken - raw");
  	PictureCallback jpegCallback = new PictureCallback() {
  	  public void onPictureTaken(byte[] data, Camera _camera) {
  		  FileOutputStream outStream = null;
			try {
				// write to local sandbox file system
				// outStream =
				// CameraDemo.this.openFileOutput(String.format("%d.jpg",
				// System.currentTimeMillis()), 0);
				// Or write to sdcard
				/*outStream = new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
						"/SimpleBulb/%d.jpeg", System.currentTimeMillis()));
				sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
				FrameLayout view = (FrameLayout)findViewById(R.id.image);
				Bitmap b = view.getDrawingCache();
				b.compress(CompressFormat.PNG, 95, new FileOutputStream(Environment.getExternalStorageDirectory() + String.format(
						"/SimpleBulb/%d.png", System.currentTimeMillis())));
				Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
			} catch (FileNotFoundException e) {
			} catch (IOException e) {
			} finally {
			Log.d(TAG, "onPictureTaken - jpeg");
 // ----------------------------------------------------------------------

    class Preview extends SurfaceView implements SurfaceHolder.Callback {
        SurfaceHolder mHolder;

        Preview(Context context) {

            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();

        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, acquire the camera and tell it where
            // to draw.
            mCamera = Camera.open();
            try {
               mCamera.setPreviewCallback(new PreviewCallback() {
   				public void onPreviewFrame(byte[] data, Camera arg1) {
   						Log.d(TAG, "onPreviewFrame - wrote bytes: "
   								+ data.length);
   		} catch (IOException e) {
                mCamera = null;

        public void surfaceDestroyed(SurfaceHolder holder) {
            // Surface will be destroyed when we return, so stop the preview.
            // Because the CameraDevice object is not a shared resource, it's very
            // important to release it when the activity is paused.
            mCamera = null;

        private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
            final double ASPECT_TOLERANCE = 0.05;
            double targetRatio = (double) w / h;
            if (sizes == null) return null;

            Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;

            int targetHeight = h;

            // Try to find an size match aspect ratio and size
            for (Size size : sizes) {
                double ratio = (double) size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);

            // Cannot find the one match the aspect ratio, ignore the requirement
            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
            return optimalSize;

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // Now that the size is known, set up the camera parameters and begin
            // the preview.
            Camera.Parameters parameters = mCamera.getParameters();

            List<Size> sizes = parameters.getSupportedPreviewSizes();
            Size optimalSize = getOptimalPreviewSize(sizes, w, h);
            Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

            if(display.getRotation() == Surface.ROTATION_0)
            	parameters.setPreviewSize(optimalSize.height, optimalSize.width);                           

            if(display.getRotation() == Surface.ROTATION_90)
            	parameters.setPreviewSize(optimalSize.width, optimalSize.height);                         

            if(display.getRotation() == Surface.ROTATION_180)
            	parameters.setPreviewSize(optimalSize.width, optimalSize.height);               

            if(display.getRotation() == Surface.ROTATION_270)
            	parameters.setPreviewSize(optimalSize.width, optimalSize.height);




Here's my layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent" android:id="@+id/layout">

	<FrameLayout android:id="@+id/image" android:layout_weight="1" android:layout_width="fill_parent"
		<RelativeLayout android:id="@+id/preview"
			android:layout_weight="1" android:layout_width="fill_parent"
		<RelativeLayout android:id="@+id/bulb_pic" android:layout_width="match_parent" android:layout_height="112dip">
			<ImageView android:id="@+id/bulb" android:src="@drawable/litbulb"
						   android:layout_height="112dip" />

	<Button android:layout_width="match_parent"
		android:layout_height="wrap_content" android:id="@+id/buttonClick"
		android:text="Snap!" android:layout_gravity="center" android:onClick="snap"></Button>


Recommended Answers

All 7 Replies

Haha 9 views (almost all from me) in 9 hours. These forums are officially DEAD!

Haha 9 views (almost all from me) in 9 hours. These forums are officially DEAD!

Christmas period, everyone slows down. Secondly may happen that people are interested in what you are asking, but may not necessary know answer to this...

Christmas period, everyone slows down. Secondly may happen that people are interested in what you are asking, but may not necessary know answer to this...

damn agreed with peter

I figured it out guys! The basic process was to save the camera's image, place it back in the view, and then save the overlay image as one. If anyone needs code or clarification, send me a PM and I can send you some code.

commented: Hi Baudday, i don´t know how to save the overlay and the captured image as one image. can you please help me...maybe you can send me some code. Thanks K. +0

Hi Baudday,
i don´t know how to save the overlay and the captured image as one image.
can you please help me...maybe you can send me some code.

Hi Baudday I am also working on similar project could send me some code please

Darwin_1: You might want to check the timestamp on the thread; Baudday hasn't been active on Daniweb in three years.

Also, it is generally considered bad form to ask for code without showing your own work first. To quote the Daniweb forum rules in this regard:

Do provide evidence of having done some work yourself if posting questions from school or work assignments

(You might also consider the rules Do not hijack old forum threads by posting a new question as a reply to an old one and Do post in full-sentence English as well, in this case.)

While this is aimed primarily at preventing cheating by students, it applies to anyone who fails to demonstrate that they have made a good-faith effort to work out their problems before coming here. While you may in fact have done so, we have no way of knowing this without some token of your previous work being offered. It doesn't have to be code - an explanation of what you have already done will suffice - but that is the surest way to convince us you are serious about solving the problem and not just lookiong for someone to do your work for you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.