Monday, November 24, 2008

Camera Capture

Source code can be downloaded below.

Before creating the Image Capture application, the SDCard must be configured first in order to be able to save in the Picture Gallery of the emulator.

Creating the SDCARD

1. See the emulator -help-sdcard to see where the default sdcard.img is located. Create if necessary.



2. Type mksdcard in the command line to know the required switches in the command-line.


3. Make SD Card.


4. For my SD Card, I just went to the default folder on step#1 and created the default SD-Card.
-cd to the default sd directory
-mksdcard 16M sdcard.img

*Note: the minumum SD required by the emulator is 8Megabytes, I just used 16M to make sure. Also, the higher the size of the SD, the longer it takes to create. So, when you create a 4GB SD, the command line might seem unresponsive.


I've been trying to figure out how to capture images in android and storing it in the picture gallery for 2 weeks now.

I just discovered, that there is nothing wrong with the code, but there's something wrong with the emulator.

For one thing, I keep on getting this image, even when using the built in Camera Application on the main menu. But, I think it is normal. Is it?


The problem I am having is that when I capture an image in the application, the File Explorer (sdcard/dcim/Camera) does save the image file. But when I check the gallery, it does not seem to exist. I then try to push an image to the emulator's file system (sdcard/dcim/Camera), but still the Picture Gallery does not reflect. Below, is a screenshot of what (sdcard/dcim/Camera) contains and what shows in the emulator's picture gallery.



When I restarted the emulator, the Picture Gallery reflected the content's of the file system. Is this a bug or did I just missed a step?


Anyways, here's the code I compiled from various sources using Google Android SDK 1R1.

http://www.anddev.org/viewtopic.php?p=704#704
http://www.anddev.org/viewtopic.php?p=645#645

I also used another site but I forgot the link. So if you see your code here, just drop me a message and I'll link you up as reference. I think the file I downloaded was CameraTestApi.zip but was based on an older SDK. I apologize for the author of the code that I based my revised Image Capture application.


Here the code for the Image Capture Application.

1. Create two classes.
ImageCapture.java


public class ImageCapture extends Activity implements SurfaceHolder.Callback
{
private Camera camera;
private boolean isPreviewRunning = false;
private SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmssSS");

private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Uri target = Media.EXTERNAL_CONTENT_URI;

public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
Log.e(getClass().getSimpleName(), "onCreate");
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.main);
surfaceView = (SurfaceView)findViewById(R.id.surface);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public boolean onCreateOptionsMenu(android.view.Menu menu) {
MenuItem item = menu.add(0, 0, 0, "goto gallery");
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Intent intent = new Intent(Intent.ACTION_VIEW, target);
startActivity(intent);
return true;
}
});
return true;
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
}

Camera.PictureCallback mPictureCallbackRaw = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera c) {
Log.e(getClass().getSimpleName(), "PICTURE CALLBACK RAW: " + data);
camera.startPreview();
}
};

Camera.PictureCallback mPictureCallbackJpeg= new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera c) {
Log.e(getClass().getSimpleName(), "PICTURE CALLBACK JPEG: data.length = " + data);
}
};

Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
public void onShutter() {
Log.e(getClass().getSimpleName(), "SHUTTER CALLBACK");
}
};


public boolean onKeyDown(int keyCode, KeyEvent event)
{
ImageCaptureCallback iccb = null;
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
try {
String filename = timeStampFormat.format(new Date());
ContentValues values = new ContentValues();
values.put(Media.TITLE, filename);
values.put(Media.DESCRIPTION, "Image capture by camera");
Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
//String filename = timeStampFormat.format(new Date());
iccb = new ImageCaptureCallback( getContentResolver().openOutputStream(uri));
} catch(Exception ex ){
ex.printStackTrace();
Log.e(getClass().getSimpleName(), ex.getMessage(), ex);
}
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
return super.onKeyDown(keyCode, event);
}

if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
camera.takePicture(mShutterCallback, mPictureCallbackRaw, iccb);
return true;
}

return false;
}

protected void onResume()
{
Log.e(getClass().getSimpleName(), "onResume");
super.onResume();
}

protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
}

protected void onStop()
{
Log.e(getClass().getSimpleName(), "onStop");
super.onStop();
}

public void surfaceCreated(SurfaceHolder holder)
{
Log.e(getClass().getSimpleName(), "surfaceCreated");
camera = Camera.open();
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
Log.e(getClass().getSimpleName(), "surfaceChanged");
if (isPreviewRunning) {
camera.stopPreview();
}
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(w, h);
camera.setParameters(p);
camera.setPreviewDisplay(holder);
camera.startPreview();
isPreviewRunning = true;
}

public void surfaceDestroyed(SurfaceHolder holder)
{
Log.e(getClass().getSimpleName(), "surfaceDestroyed");
camera.stopPreview();
isPreviewRunning = false;
camera.release();
}
}


ImageCaptureCallback.java


public class ImageCaptureCallback implements PictureCallback {

private OutputStream filoutputStream;
public ImageCaptureCallback(OutputStream filoutputStream) {
this.filoutputStream = filoutputStream;
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
Log.v(getClass().getSimpleName(), "onPictureTaken=" + data + " length = " + data.length);
filoutputStream.write(data);
filoutputStream.flush();
filoutputStream.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}


2. Create the main.xml as shown below









3. Add a camera permission to the ApplicationManifest




Source Code

Email

java.padawan@androidph.com