What is this: I was working on the CameraPreview application and noticed there were no capturing tool to save the image into a PNG or JPG. It is quite simple to enable it but requires a bit of understanding.
Difficulty: 2.5 of 5
Desctription: First off, we create a new project within Eclipse. I named it CameraPreview so I can just copy/paste the cameraPreview application found here.
If you run the application, you should see a square changing color with a black and white background:
Let analyse how the camera application is built:
The CameraPreview does not do much. It is our main class but nothing in there is of any interest.
The Preview class is where everything happens. It will contain the canvas which we will draw onto and then to the screen. The constructor and most methods are used to handle the extra thread that we will use to keep refreshing the output of the camera. For instance we will set the size of the screen (and camera output) in the constructor, ensure that the PreviewThread will be killed when the activity goes onPause and reborn when it hits onResume.
The surfaceView is just a handler on which we will be able to paint the output of the camera.
Lets look at the meat of the application: PreviewThread.
The run method will do several things:
1. Set some options to the camera device and open it:
Using java Syntax Highlighting
- CameraDevice.CaptureParams param = new CameraDevice.CaptureParams();
- param.type = 1; // preview
- param.srcWidth = 1280;
- param.srcHeight = 960;
- param.leftPixel = 0;
- param.topPixel = 0;
- param.outputWidth = 320;
- param.outputHeight = 240;
- param.dataFormat = 2; // RGB_565
- camera.setCaptureParams(param);
Parsed in 0.031 seconds, using GeSHi 1.0.8.4
2. Hold the surface handler and lock onto it:
Using java Syntax Highlighting
- SurfaceHolder holder = mHolder;
- while (!mDone) {
- Canvas canvas = holder.lockCanvas();
Parsed in 0.030 seconds, using GeSHi 1.0.8.4
3. Print onto the canvas the camera output:
Using java Syntax Highlighting
- camera.capture(canvas);
Parsed in 0.033 seconds, using GeSHi 1.0.8.4
4. Post it to the UI and unlock the canvas (which actually does not make much difference because it will loop undifinitely with the while loop):
Using java Syntax Highlighting
- holder.unlockCanvasAndPost(canvas);
Parsed in 0.034 seconds, using GeSHi 1.0.8.4
It is important to understand how the preview is done before continuing in the capturing part. as you can see we lock onto a canvas that is being updated by the camera. The camera can be open only once.
2. The capturing part:
We will do our capturing in the CameraPreview class.
First off we create a key listener:
Using java Syntax Highlighting
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- mPreview.pause();
- takePicture();
- mPreview.resume();
- return true;
- }
- return false;
- }
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
I used the center button to be the one that will take the picture. First I pause the Preview class. The onPause will kill the the thread which is looping as explained above and close the connection to the camera device. This will release the device for any other method to use. The takePicture is the method used to take the picture - I will explain it next. The resume will call the onResume so we can have the preview continuing after the picture was taken.
Lets take a look at the takePicture method:
Using java Syntax Highlighting
- private int i = 0;
- void takePicture(){
- CameraDevice camera = CameraDevice.open();
- if (camera != null) {
- Log.i("MyLog", "inside the camera");
- CameraDevice.CaptureParams param = new CameraDevice.CaptureParams();
- param.type = 1; // preview
- param.srcWidth = 1280;
- param.srcHeight = 960;
- param.leftPixel = 0;
- param.topPixel = 0;
- param.outputWidth = 320;
- param.outputHeight = 240;
- param.dataFormat = 2; // RGB_565
- camera.setCaptureParams(param);
- Bitmap myPic = Bitmap.createBitmap(320, 240, false);
- Canvas canvas = new Canvas(myPic);
- try {
- FileOutputStream stream = super.openFileOutput("picture" + i++ + ".png", MODE_PRIVATE);
- camera.capture(canvas);
- myPic.compress(CompressFormat.PNG, 100, stream);
- stream.flush();
- stream.close();
- }catch(Exception e) { Log.e("MyLog", e.toString()); }
- // Make sure to release the CameraDevice
- if (camera != null)
- camera.close();
- }
- }
Parsed in 0.039 seconds, using GeSHi 1.0.8.4
We do the following:
1. Open the camera device and set the options as in the PreviewThread class
2. Now I create a new Bitmap with the same dimension as the output of the camera device:
Using java Syntax Highlighting
- param.outputWidth = 320;
- param.outputHeight = 240;
- ...
- Bitmap myPic = Bitmap.createBitmap(320, 240, false);
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
3. I also create a canvas that will print into the Bitmap (instead of the screen)
Using java Syntax Highlighting
- Canvas canvas = new Canvas(myPic);
Parsed in 0.035 seconds, using GeSHi 1.0.8.4
4. Now I open a file using Context.openFileOutput
NOTE: As you can see I use a dynamic name. I noticed that overiding the file with the same name will not work. It will recreate a new file but it seems that you can not open the png afterwards. It might be a bug, need time to investigate a bit further. Now each time you take a picture it will be named picture1.png, picture2.png and so forth. Furthermore, you might want to wait a bit and refreshing the ddms view before saving...
5. I capture the image onto the canvas (onto the bitmap) and then save it by compressing it onto the outputStream:
Using java Syntax Highlighting
- camera.capture(canvas);
- myPic.compress(CompressFormat.PNG, 100, stream);
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
Nothing much to explain here. It is quite straightforward to understand. You have 2 formats: PNG and JPG. The second value is the quality 100 being best and 0 worth. FInally stream is the ouptut stream that were given in 4.
Next I will create a quick viewer. However, you can check the files from:
Open Perspective -> DDMS -> under "data -> data -> <package name> -> files -> picture0.png...". You can save it onto disk with the small disk drive icon on the top right. and check how marvelous the picture is.
Hope it helps somebody.
Comments are welcomed.
./Carl

This site is very very use full to me .

, I tried to solve, but i can't



