140 likes | 310 Views
camera. Make new project CameraFun Give permission to use camera write_external _storage Make two buttons id t akePictureButton id s howLastPicButton Add SurfaceView to layout Surface view is something we can draw on
E N D
Make new project • CameraFun • Give permission to • use camera • write_external _storage • Make two buttons • id takePictureButton • idshowLastPicButton • Add SurfaceView to layout • Surface view is something we can draw on • Graphics on a SurfaceView is discussed in the video GraphicWithCanvas • This will show the picture preview • Set layout height = fill_parent (or try 10dip) • Set layout width = fill_parent • Set layout weight = 1 • Id = @+id/surface_camera • SurfaceView changes when the phone’s orientation changes.
SurfaceView • To handle the surface and changes in the surface, we need our activity to implement SurfaceHolder.Callback. • public class CameraFunActivityextends Activity implements SurfaceHolder.Callback{ • See Graphics with Canvas notes for how to make surfaceView a class, not the activity • Our CameraFunActivityclass needs some objects • Camera mCamera; // to hold the camera object • //!! When importing package camera, make sure to get android.hardware.camera • private SurfaceViewmSurfaceView; // to hold the surface view • private SurfaceHoldermSurfaceHolder; // to hold the interface for the surfaceview • booleanpreviewRunning = false; • We’ll add some more later • In onCreate, add • mSurfaceView= (SurfaceView) findViewById(R.id.surface_camera); // get surface object • mSurfaceHolder = mSurfaceView.getHolder(); // get surface holder • mSurfaceHolder.addCallback(this); // this activity is the callback • // note, instead this, we could make a new class that implements SurfaceHolder.Callback • mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); • Implementing SurfaceHolder.CallBack requires three functions to be implemented • surfaceCreated • surfaceChanged • Called when orientation is changed and after surfaceCreated • surfaceDestroyed
surfaceCreated and surfaceDestroyed • public void surfaceCreated(SurfaceHolder holder) { • Log.e("CameraFun", "surfaceCreated"); • mCamera = Camera.open(); // this will not compile if the wrong camera package was imported (see previous slide) • } • public void surfaceDestroyed(SurfaceHolder holder) { • Log.e("CamerFun", "surfaceDestroyed"); • mCamera.stopPreview(); • mCamera.release(); • previewRunning = false; • }
surfaceChanged • public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { • // called when surface created and when orientation is changed • Log.d("CameraFun", "surfaceChanged"); • if (previewRunning) • mCamera.stopPreview(); • Log.e("CameraFun","view width"+width+" height"+height); • Camera.Parametersp = mCamera.getParameters(); // set the preview size • p.setPreviewSize(width, height); • mCamera.setParameters(p); • try { • mCamera.setPreviewDisplay(holder); • } catch (IOException e) { • e.printStackTrace(); • } • mCamera.startPreview(); • mPreviewRunning= true; • }
run • It crashes on most devices • Check log • Note that error when setting preview size • Note that preview size is odd. • Check web for more info on Camera.Parameters and Camera.Parameters.setPreviewSize • see getSupportedPreviewSizes
Improved surfaceChanged • In surfaceChanged, before setParameters, add • Log.e("MyCameraFun","width"+width+" h"+height); • List<Camera.Size> sizes = mCamera.getParameters().getSupportedPreviewSizes(); • Camera.SizesizeToSet = null; • for (Camera.Size t: sizes) • { • String str = "view"; • str += t.width; • str += "by" + t.height; • Log.e("CameraFun", str); • if (t.width<= width && t.height<= height && sizeToSet == null) • sizeToSet = t; • } • Log.e("CameraFun","w="+sizeToSet.width+" h="+sizeToSet.height); • change • p.setPreviewSize(width, height); • to • p.setPreviewSize(sizeToSet.width, sizeToSet.height); • // note that this sizetoSet might be null. In which case none of the supported sizes works. This condition should be handled • run
Rotation/orientation • Note that the orientation is messed up • Perhaps the image is correct in only one orientation. • Two fixes • Fix the orientation to be in portrait or landscape and set display orientation accordingly • In onCreate, add • setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); • In surfaceChanged, add • In version 2.2 and above: • mCamera.setDisplayOrientation(180); // or 90 or whatever value works • In 2.1 • Camera.Parameters parameters = mCamera.getParameters();parameters.set("orientation", "portrait");mCamera.setParameters(parameters); • Get the rotation and then set camera orientation accordingly • In surfaceChanged, add • Display display = getWindowManager().getDefaultDisplay(); • switch (display.getRotation()) { • case Surface.ROTATION_0: • Log.e("DEBUG INFO","rotation = 0"); • mCamera.setDisplayOrientation(180); // whatever value works • break; • case Surface.ROTATION_90: • Etc. etc.
Take picture • In onCreate add button click listener • When clicked call • mCamera.takePicture(null, null, pictureCallback); • The first null could be set to play a sound. But we will just use the default • pictureCallback is a Camera.PictureCallback object that we must make
PictureCallback • Camera.PictureCallbackpictureCallback = new Camera.PictureCallback() { • public void onPictureTaken(byte[] imageData, Camera c) { • if (imageData == null) { • Log.e("DEBUG INFO","image is null"); • } else { • File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); • File fileToSave = new File(path,"myPic.jpeg"); • Log.e("CameraFun","savingpic to: "+fileToSave); • Bitmap bitmap = BitmapFactory.decodeByteArray(imageData,0,imageData.length); • FileOutputStreamfos = new FileOutputStream(fileToSave); • bitmap.compress(CompressFormat.JPEG, 50, fos); // quality is 50, but could be between 0 and 100 • fos.close(); • } • } • mCamera.startPreview(); • }; • Notes: there are many bitmap functions. Check documentation • Need to something to handle throw • Run • Get pic from storage and view on your laptop
Show picture • Make new activity (see previous tutorial on making another activity) • In layout add • Add ImageView • In onCreate, add • // get file with picture • File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); • File fileToView = new File(path,"myPic.jpeg"); • Log.e("Still image source filename:", fileToView.getPath()); • // load file as bitmap • Bitmap bm = BitmapFactory.decodeFile(fileToView.getPath()); • // show bitmap • android.widget.ImageViewimageView = (android.widget.ImageView)findViewById(R.id.imageView); • imageView.setImageBitmap(bm);
Record video • Add android.permission.RECORD_AUDIO • Add member variable: MediaRecordermediaRecorder; • Add button for stopping the record • We’ll use the button for taking a picture to start recording • In the start recording button, replace • mCamera.takePicture(null, null, pictureCallback); • With • File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); • File fileToSave = new File(path,"myMov.mpeg"); • mCamera.unlock(); • mediaRecorder = new MediaRecorder(); • mediaRecorder.setCamera(mCamera); • mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); • mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); • mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); • mediaRecorder.setMaxDuration(-1); • mediaRecorder.setOutputFile(fileToSave.getPath()); // your file • mediaRecorder.setVideoFrameRate(10);//videoFramesPerSecond); • mediaRecorder.setVideoSize(320, 240); // or some other size • mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); • mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); • mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); • mediaRecorder.setMaxFileSize(100000000); // size in bytes • mediaRecorder.prepare(); • mediaRecorder.start();
In stop video button • mediaRecorder.stop(); • mCamera.lock();
Playing Video • in picviewer.xml (layout), • delete image view • Add VideoView • in ImageView • Comment out everything with showing the picture • Add • File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); • File fileToLoad = new File(path,"myMov.mpeg"); • VideoViewmVideoView = (VideoView) findViewById(R.id.videoView); • mVideoView.setVideoPath(fileToLoad.getPath()); • mVideoView.setMediaController(new MediaController(this)); • mVideoView.requestFocus(); • mVideoView.start(); • //mVideoView.stop() • //mVideoView.suspend();