Android development Note (32) uses camera photos and android notes
In Android, two methods are generally used to take photos with a Camera. One is to call the built-in Camera of the system, and the other is to write a Camera interface by yourself.
Add the following permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/>
1. Call the System Camera
The main steps for calling the built-in Camera system are as follows:
(1) construct the path name of the Image Storage
(2) Start Camera Activity with Intent
(3) write the captured image to a file
(4) display the image in MainActivity
First, create the image name:
File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); if(!filePath.exists()){ filePath.mkdirs(); } fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); try{ if(!fileName.exists()){ fileName.createNewFile(); } }catch (Exception e){ e.printStackTrace(); }
Then, start the Camera Activity:
// Intent is used to start the built-in Camera Intent intent = new Intent (MediaStore. ACTION_IMAGE_CAPTURE); // write the video results of the System Camera to the file intent. putExtra (MediaStore. EXTRA_OUTPUT, Uri. fromFile (fileName); // start the Activity corresponding to intent and return the default message startActivityForResult (intent, Activity. DEFAULT_KEYS_DIALER );
Finally, the image is displayed in MainActivity. At this time, we can obtain the message returned by Camera by reloading the onActivityResult () method.
@ Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {if (requestCode = Activity. DEFAULT_KEYS_DIALER) {// MainActivity receives the message returned by Camera, and then displays the written image in ImageView. setImageURI (Uri. fromFile (fileName ));}}
Complete code:
Import android. app. activity; import android. content. intent; import android.net. uri; import android. OS. bundle; import android. OS. environment; import android. provider. mediaStore; import android. util. log; import android. view. view; import android. widget. button; import android. widget. imageView; import java. io. file; public class MainActivity extends Activity {private File fileName = null; private Button button; pr Ivate ImageView imageView; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); button = (Button) findViewById (R. id. button); imageView = (ImageView) findViewById (R. id. imageView); button. setOnClickListener (new View. onClickListener () {@ Override public void onClick (View v) {File filePath = new File (Environment. getEx TernalStorageDirectory (), "myCamera"); if (! FilePath. exists () {filePath. mkdirs ();} fileName = new File (filePath, System. currentTimeMillis () + ". jpg"); try {if (! FileName. exists () {fileName. createNewFile () ;}} catch (Exception e) {e. printStackTrace ();} // intent is used to start the built-in Camera Intent intent = new Intent (MediaStore. ACTION_IMAGE_CAPTURE); // write the video results of the System Camera to the file intent. putExtra (MediaStore. EXTRA_OUTPUT, Uri. fromFile (fileName); // start the Activity corresponding to intent and return the default message startActivityForResult (intent, Activity. DEFAULT_KEYS_DIALER) ;}}) ;}@ Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {if (requestCode = Activity. DEFAULT_KEYS_DIALER) {// MainActivity receives the message returned by Camera, and then displays the written image in ImageView. setImageURI (Uri. fromFile (fileName ));}}}
2. Write your own camera interface
I wrote my own camera interface and used SurfaceView to display the camera screen. Then, a Button is used to save the current screen.
Similarly, we need to add the camera and SDCard permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/>
First, initialize this SurfaceView and add a corresponding Callback for this SurfaceView:
Private SurfaceView surfaceView; private SurfaceHolder. callback callback; surfaceView = (SurfaceView) findViewById (R. id. surfaceView); callback = new SurfaceHolder. callback () {@ Override public void surfaceCreated (SurfaceHolder holder) {startCamera (); // used to start the camera} @ Override public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {}@ Override public void surfaceDestroyed (SurfaceHolder holder) {stopCamera (); // used to close the camera}; surfaceView. getHolder (). addCallback (callback); // bind Callback to SurfaceView
When starting the camera, first enable the camera connection, and then output its image to SurfaceView. Then, start the camera preview to display the camera image on SurfaceView, the image here is 90 degrees different from the actual image, so we need to rotate the image 90 degrees before it can be consistent with the shooting object direction.
When you disable the camera, you only need to stop previewing and then release the camera resources.
public void startCamera(){ camera = Camera.open(); try { camera.setPreviewDisplay(surfaceView.getHolder()); camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } public void stopCamera(){ camera.stopPreview(); camera.release(); camera = null; }
Finally, save the captured image to SDCard. click the Button to take the image and call the Camera. takePicture () method. The prototype is as follows:
/** * Equivalent to takePicture(shutter, raw, null, jpeg). * * @see #takePicture(ShutterCallback, PictureCallback, PictureCallback, PictureCallback) */ public final void takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback jpeg) { takePicture(shutter, raw, null, jpeg); }
The shutter calls the ShutterCallback. onShutter () method instantly by pressing the shutter. Raw is the callback of an uncompressed image, that is, the PictureCallback. onPictureTaken () method is called when processing the original image data. Jpeg is the callback for processing JPEG images. This method is called when image data is saved in jpg format. PictureCallback. onPIctureTaken (). Here we call this method to store JPG images on SDCard.
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { camera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { try { File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); if(!filePath.exists()) { filePath.mkdirs(); } File fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); fileName.createNewFile(); FileOutputStream fos = new FileOutputStream(fileName); fos.write(data); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } }); } });
In this way, we can use SurfaceView to preview the camera image and click the Button to save the current preview to the SDCard.
The complete code is as follows:
import android.app.Activity;import android.hardware.Camera;import android.os.Bundle;import android.os.Environment;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.Button;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;public class MainActivity extends Activity { private Camera camera; private Button button; private SurfaceView surfaceView; private SurfaceHolder.Callback callback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button)findViewById(R.id.button); surfaceView = (SurfaceView)findViewById(R.id.surfaceView); callback = new SurfaceHolder.Callback(){ @Override public void surfaceCreated(SurfaceHolder holder) { startCamera(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { stopCamera(); } }; surfaceView.getHolder().addCallback(callback); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { camera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { try { File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); if(!filePath.exists()) { filePath.mkdirs(); } File fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); fileName.createNewFile(); FileOutputStream fos = new FileOutputStream(fileName); fos.write(data); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } }); } }); } public void startCamera(){ camera = Camera.open(); try { camera.setPreviewDisplay(surfaceView.getHolder()); camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } public void stopCamera(){ camera.stopPreview(); camera.release(); camera = null; } }