android实现自定义相机效果

楼主在进行android开发时用到了自定义摄像头拍照并将所拍摄的照片转化成二进制流输出这一功能(当然程序里也附带将图片存储在sd卡里的功能),花了好多天的时间查了很多资料最后终于把它给搞出来了。。。

来~~~直接上图~~~


首先先搞出界面布局来


布局定制出来是这样的:


这里的布局其实挺简单的,只有一个Framelayout和一个Button按钮

Framelayout用于显示相机,Button按钮添加OnClickListene用于获取图像。

然后我们再看活动是如何创建的:

上代码:


我们来看一下活动中代码的执行顺序:

onCreate方法里活动首先调用getCameraInstance里的方法getCamera()来获取一个相机对象

当然getCameraInstance类是自己创建的一个类,下面是它里面的代码:

这里的代码就比较简单了,定义一个camera c,初始化为null。然后尝试打开摄像头,注意这里的c.open(1)

参数为“1”的含义为打开前摄像头,如果想打开后摄像头为c.open(0)或者直接省略参数。如果打开成功则返回camera对象,失败则抛出异常。

~~~

再接着看活动,定义一个mCamera用于接收调用getCamera()返回的相机对象。

将得到的camera作为参数传递给相机预览对象,显示当前相机里的图像。

当然这个相机预览类也是自己写的:附代码


<textarea name="code" class="c++" readonly="readonly" style="width: 619px; height: 410px;">package myfinalcamera.caicai.com.myfinalcamera; import android.content.Context; import android.hardware.Camera; import android.util.Log; import android.view.SurfaceView; import android.view.SurfaceHolder; import java.io.IOException; /** * Created by caicai on 2017/5/5. */ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback,Camera.AutoFocusCallback { private Camera mCamera; private SurfaceHolder mHolder; private static final String TAG=&quot;CameraPreview&quot;; private static final String TAGDRAW=&quot;Draw&quot;; public CameraPreview(Context context,Camera camera) { super(context); mCamera=camera; mHolder=getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override public void surfaceCreated(SurfaceHolder holder) { try { mCamera.setPreviewDisplay(holder); mCamera.setDisplayOrientation(90); /* 设置一下preview的大小 */ Camera.Parameters parameters=mCamera.getParameters(); parameters.setPreviewSize(640,480); parameters.setPictureSize(640,480); parameters.setJpegQuality(100); mCamera.setParameters(parameters); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if(mHolder.getSurface()==null){ return; } try { mCamera.stopPreview(); }catch (Exception e){ } try { mCamera.setPreviewDisplay(mHolder); mCamera.setDisplayOrientation(90); Camera.Parameters parameters=mCamera.getParameters(); parameters.setPreviewSize(320,240); parameters.setPictureSize(320,240); parameters.setJpegQuality(100); mCamera.setParameters(parameters); mCamera.startPreview(); }catch (Exception e){ Log.d(TAG, &quot;Errorstarting camera preview: &quot; + e.getMessage()); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { mCamera.stopPreview();//停止预览 mCamera.release();//释放相机资源 mCamera = null; holder = null; } @Override public void onAutoFocus(boolean success, Camera Camera) { if (success) { Log.i(TAG, &quot;onAutoFocus success=&quot;+success); } } } </textarea>

CameraPreview继承自SurfaceView实现了SurfaceHolder.Callback和Camera.AutoFocusCallback接口。SurfaceView允许其他线程(非UI线程)多次绘制图形,即可在其界面上显示当前相机捕获的图像。

~~~

接着活动继续往下讲:

获得mpreview相机预览对象后,定义一个FrameLayout布局对象preview指向布局里的camera_preview,preview调用addView将相机预览视图添加到FramLayout布局里。这样就可以再布局里的camera_preview里显示了。

~~~

camera_preview里已经能显示了,再就是实现点击按钮实现拍照功能了

定义一个Buttou对象captureButton指向布局文件的button_capture_button按钮,为capture_button添加点击事件,当点击按钮时调用takePicture(save.shutter,save.row,save.jpeg)方法,第一个参数为快门,第二个参数为原数据,第三个参数为jpeg格式的数据,前两个我们可以不管直接在save类里实例化一个CameraCallback对象和PictureCallback对象里面的代码不需要改动,需要改的是第三个参数,因为要涉及到照片的存储和生成二进制流输出。这里又涉及到一个自定义类。


下面只看第三个参数调用的代码,这里定义了一个Bitmap对象bm和缓冲输出流对象bom,接着用bm接收拍照生成的data数据。定义图片的存储路径和名称,调用自己写的生成图片保存路径和名称的方法:


返回图片存储路径后,将数据以jpeg的形式存储到指定路径中去。在存储结束后我还用Log.i(TAG,new String(data));在控制台输出了一下照片的字符串类型数据。代码的最后就是清空缓冲区关闭缓冲输出流对象等。

最后别忘了在AndroidManifest.xml里将添加权限,在模拟器或真机上运行时,也要允许程序在相应的模拟器或真机上有相应的权限。


猜你喜欢

转载自blog.csdn.net/caicai1hao/article/details/71740155