Escolar Documentos
Profissional Documentos
Cultura Documentos
It is CameraDevice class in Android. Various parameters can be passed to the CameraDevice to customize how the picture is taken. The output should be projected on some sort of View Class, which is provided by SurfaceView, an extension of the View class. Saving the file to the file system uses an OutputStream to create the required files in the system. JPG and PNG are allowed. The image quality needs to be assigned at the time though.
Contents
1 Starting out 2 Understanding the code 3 Modifications o 3.1 Runnable methods o 3.2 Listening to KeyStrokes
Starting out
Create a new Project in Eclipse titled "MyCamera". Follow the instructions at Creating a project in Eclipse for Android. Select the MyCamera.java file and copy the text of into it. Another method: look into the Graphics section of your android_installation_directory/samples for the same file. Change the class name from CameraPreview to MyCamera. Remember to change the package name to org.hfoss.MyCamera Test 1: You should be able to see the moving box in front of the checkered background.
Open up the eclipse outline view from Window>Show View>Outline. You should be able to see that
there are two classes defined here. MyCamera and Preview; Preview being the subclass of MyCamera here.
Expand Preview. You should be able to see PreviewThread class here. Take a look at the following method.
public void run() { // We first open the CameraDevice and configure it. CameraDevice camera = CameraDevice.open(); if (camera != null) { 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); } // This is our main acquisition thread's loop, we go until // asked to quit. SurfaceHolder holder = mHolder; while (!mDone) { // Lock the surface, this returns a Canvas that can // be used to render into. Canvas canvas = holder.lockCanvas(); // Capture directly into the Surface if (camera != null) { camera.capture(canvas); } // And finally unlock and post the surface. holder.unlockCanvasAndPost(canvas); } // Make sure to release the CameraDevice if (camera != null) camera.close(); }
The CameraDevice class is used to open the camera driver, set image parameters and to capture a preview frame or full resolution image (Currently 1280*1024 pixels). Calling the open() static class will return a CameraDevice object. For more detailed information, see CameraDevice Documentation The following code in Preview installs a SurfaceHolder.Callback to notify for any changes in the surface. {
mHolder = getHolder(); mHolder.addCallback(this);
} In line 156:161 in the code, you'd find this code(Hint: use Ctrl+L in eclipse) which gets a Canvas object from the SurfaceHolder and captures the image from the camera. Then the camera device is closed and the surface is posted.
Modifications
To save a file, we need to make a new Canvas. Unlike the SurfaceView one, it wont be displayed on the screen but it will point to a Bitmap object that will be saved to the device. Copy the following code to the file:
private void takePicture() { if (camera != null) { camera.setCaptureParams(param); Bitmap myPic = Bitmap.createBitmap(param.outputWidth, param.outputHeight, false); Canvas canvas = new Canvas(myPic); camera.capture(canvas);
try { OutputStream outStream = this.openFileOutput("pic" + count + ".png", Context.MODE_WORLD_READABLE); myPic.compress(Bitmap.CompressFormat.PNG, 100, outStream); outStream.close(); } catch (IOException e) { Log.e(TAG, e.toString()); } camera.close(); } else { Log.e(TAG, "Failed to open camera device"); return; } } Here, we take the same approach that the thread takes in displaying the picture but instead of displaying it to a screen object we are saving it into a Bitmap and then to a file using the OutputStream.
A7, Stephanos Tower, Eachamukku, Kakkanadu,Kochi
Runnable methods
Whenever we design a dynamic application like this, especially something that deals with hardware(I/O) and we want our application be robust during the transaction, we run these objects as threads. Android provides the Runnable class for this where a Runnable Object is declared with the threads that need to be run. Hence, we declare a mTakePicture object with the following actions, first we want to pause the preview, take the picture and resume. final Runnable mTakePicture = new Runnable() { public void run() {
mPreview.pause(); takePicture(); mPreview.resume(); } };
Listening to KeyStrokes
We need to have some way to Listen for user interactivity. For this, we need to add a onKeyDown method. Right Click anywhere in eclipse editor and select Source>Override/Implement methods ... Type onKeyDown, until public boolean onKeyDown(int, KeyEvent). Click the checkbox and click the ok button, the new overriden method should be added there. We detect key events in android by comparing the key Codes supplied to the onKeyDown method. The code goes like this: switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER: mPreview.post(mTakePicture); break; case KeyEvent.KEYCODE_BACK: finish(); break;
} return false; Here mPreview.post() method adds the Runnable object in the queue of the activity to be run. It runs the Runnable function declared in the earlier step which saves the files to the file system. Test2: To check if your file is saved. To check if your file is actually saved, open the DDMS perspective in eclipse. Click the button beside [Java] button at the top right (tooltip: Open Perspective), below the menu bar. If you don't see DDMS there, select Other and select DDMS from the dialog box to use the DDMS perspective. You can also use Window>Open Perspective to accomplish the same task. Now, check if your file Explorer view is open, with data, system and tmp folders showing. That's the view of the root folder. Now, go to data/data/org.hfoss.camera/files to get your file. To see the file, select the "pull file from the device icon" at the top right of the file Explorer view and save it to your desired location.
Introduction
A simple guide for integrating the Camera Hardware inside your Android App.
During this callback, you get an idea of how big your preview screen is going to be. Based on that, assign the proper size to the Camera.
When the preview screen is removed from view, this callback is used to perform cleanup. In this phase, make sure the preview is stopped and the Camera hardware is released
You must supply a Callback to process the information that the camera sends back to your App
private class HandlePictureStorage implements PictureCallback { @Override public void onPictureTaken(byte[] picture, Camera camera) { //The picture can be stored or do something else with the data //in this callback such sharing with friends, upload to a Cloud component etc //This is invoked when picture is taken and the data needs to be processed System.out.println("Picture successfully taken: "+picture);
String fileName = "shareme.jpg"; String mime = "image/jpeg"; MainActivity.this.shareme = new CloudPhoto(); MainActivity.this.shareme.setFullName(fileName); MainActivity.this.shareme.setMimeType(mime); MainActivity.this.shareme.setPhoto(picture); } }
Inside this callback, you can do whatever you need with the picture. You can store it on your local file system, in a sqlite database, or in this case, send it to a remote service located in the cloud.
You can do this in the AndroidManifest.xml by adding the above mentioned line
/** * * @author openmobster@gmail.com */ public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private Camera camera; public CameraSurfaceView(Context context) { super(context); //Initiate the Surface Holder properly this.holder = this.getHolder(); this.holder.addCallback(this); this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override public void surfaceCreated(SurfaceHolder holder) { try { //Open the Camera in preview mode this.camera = Camera.open(); this.camera.setPreviewDisplay(this.holder); } catch(IOException ioe)
{ ioe.printStackTrace(System.out); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // Now that the size is known, set up the camera parameters and begin // the preview. Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(width, height); camera.setParameters(parameters); camera.startPreview(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when replaced with a new screen //Always make sure to release the Camera instance camera.stopPreview(); camera.release(); camera = null; } public Camera getCamera() { return this.camera; } }