基于Android TextureView与SurfaceTexture实现相机Camera拍照预览与保存照片
写一个简单的例子,实现一个常见的开发功能:拍照功能。
技术路线:通过TextureView的通道获取SurfaceTexture作为相机的预览,然后通过Camera的take方法把相机抓取的byte字节数据转换为Bitmap,然后存放到手机的存储器上,至此,一个最简单的拍照功能完成。
注意,本例如果运行在Android高版本(6.0+,7.0+或更高),需要多写运行时权限申请代码。本例出于功能演示,不再冗余的写这部分代码。只给出最骨干的关键代码逻辑。
布局文件activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_blue_light" tools:context="zhangphil.view.MainActivity"> <zhangphil.view.MyTextureView android:id="@+id/textureView" android:layout_width="300dp" android:layout_height="200dp" android:layout_centerInParent="true" /> <Button android:id="@+id/capture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="拍摄" /> </RelativeLayout>
MyTextureView.java:
package zhangphil.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.os.Environment; import android.util.AttributeSet; import android.util.Log; import android.view.TextureView; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; /** * Created by Phil on 2017/9/13. */ public class MyTextureView extends TextureView { public Camera mCamera; public MyTextureView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { mCamera = Camera.open(); this.setSurfaceTextureListener(new SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { try { mCamera.setPreviewTexture(surfaceTexture); mCamera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { mCamera.stopPreview(); mCamera.release(); mCamera = null; return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { } }); } public void take() { if(mCamera!=null) mCamera.takePicture(null, null, mPictureCallback); } Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { mCamera.stopPreview(); new FileSaver(data).save(); } }; private class FileSaver implements Runnable { private byte[] buffer; public FileSaver(byte[] buffer) { this.buffer = buffer; } public void save() { new Thread(this).start(); } @Override public void run() { try { File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "zhangphil.png"); file.createNewFile(); FileOutputStream os = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(os); Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length); bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos); bos.flush(); bos.close(); os.close(); Log.d("照片已保存", file.getAbsolutePath()); mCamera.startPreview(); } catch (Exception e) { e.printStackTrace(); } } } }
MainActivity.java:
package zhangphil.view; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class MainActivity extends AppCompatActivity { private MyTextureView textureView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textureView = (MyTextureView) findViewById(R.id.textureView); findViewById(R.id.capture).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { textureView.take(); } }); } }
权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/>
代码运行结果:
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/3125.html