Android实例讲解自定义Camera拍照和预览以及前后置摄像头切换

本博文将通过实例实现自定义Camera的功效。具体功能如下:

1.实现自定义Camera拍照;

2.实现前后置摄像头的切换;

3.实现Camera拍照后图片缩小显示以及正常预览;

4.实现Camera拍照后图片保存;

在具体实现代码之前,我们先来了解一下Android api对实现自定义Camera的介绍。

根据api的介绍,对于Camera应用可以简单总结以下几个步骤。

1.检查Camera是否存在,并在AndroidManifest.xml中赋予相关的权限;

2.创建一个继承于SurfaceView并实现SurfaceHolder接口的Camera Preview类;

3.在2的基础上新建一个Camera Preview布局文件;

4.设置一个拍照的监听事件,例如单击按钮事件等;

5.实现拍照,并保存拍照后的图片到设备;

6.释放Camera,以方便其他应用可以使用。

下面将通过具体代码实现我们给出的三个功能。

一.相关的xml文件

1.AndroidManifest.xml相关配置以及相关权限,实现步骤一当中的权限配置

 

01. <?xml version="1.0" encoding="utf-8"?>
02. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
03. package="com.example.camerasurfacedemo"
04. android:versionCode="1"
05. android:versionName="1.0" >
06.  
07. <uses-sdk
08. android:minSdkVersion="11"
09. android:targetSdkVersion="19" />
10.  
11. <uses-permission android:name="android.permission.CAMERA" />
12. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
13.  
14. <uses-feature android:name="android.hardware.camera" />
15.  
16. <application
17. android:allowBackup="true"
18. android:icon="@drawable/ic_launcher"
19. android:label="@string/app_name"
20. android:theme="@style/AppTheme" >
21. <activity
22. android:name="com.example.camerasurfacedemo.MainActivity"
23. android:label="@string/app_name" >
24. <intent-filter>
25. <action android:name="android.intent.action.MAIN" />
26.  
27. <category android:name="android.intent.category.LAUNCHER" />
28. </intent-filter>
29. </activity>
30.  
31. <activity android:name="com.example.camerasurfacedemo.CameraActivity"
32. ></activity>
33. <activity android:name="com.example.camerasurfacedemo.PreviewActivity"
34. ></activity>
35. </application>
36.  
37. </manifest>

2.activity_main.xml主函数入口,进入自定义Camera界面入口,实现拍照后图片缩小显示功能

 

 

01. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03. android:layout_width="match_parent"
04. android:layout_height="match_parent"
05. android:gravity="center_horizontal"
06. android:orientation="vertical" >
07. "
08.  
09. <Button
10. android:id="@+id/id_go_camera_btn"
11. android:layout_width="match_parent"
12. android:layout_height="wrap_content"
13. android:gravity="center"
14. android:text="进入拍照界面" />
15.  
16. <ImageView
17. android:id="@+id/id_show_camera_iv"
18. android:layout_width="150dp"
19. android:layout_height="200dp"
20. android:gravity="center" />
21.  
22. <TextView
23. android:layout_width="match_parent"
24. android:layout_height="match_parent"
25. android:gravity="center"
26. android:text="拍照图片显示区域"
27. android:textColor="#FF0000"
28. android:textSize="20sp" />
29.  
30. </LinearLayout>

3.activity_camera.xml自定义Camera preview布局,实现步骤2,该界面实现前后置摄像头切换以及自定义拍照等

 

 

01. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
03. android:layout_width="match_parent"
04. android:layout_height="match_parent"
05. >
06. <LinearLayout
07. android:id="@+id/id_process_btns_ll"
08. android:layout_width="match_parent"
09. android:layout_height="wrap_content"
10. android:orientation="horizontal"
11. android:layout_alignParentTop="true"
12. >
13. <Button
14. android:id="@+id/id_switch_camera_btn"
15. android:layout_width="wrap_content"
16. android:layout_height="wrap_content"
17. android:layout_weight="1"
18. android:gravity="center"
19. android:text="切换前后摄像头"
20. />
21. <Button
22. android:id="@+id/id_capture_btn"
23. android:layout_width="wrap_content"
24. android:layout_height="wrap_content"
25. android:layout_weight="1"
26. android:gravity="center"
27. android:text="拍照"
28. />
29. </LinearLayout>
30. <SurfaceView
31. android:id="@+id/id_area_sv"
32. android:layout_width="match_parent"
33. android:layout_height="match_parent"
34. android:layout_below="@id/id_process_btns_ll"
35. android:text="拍照区域" />
36.  
37. </RelativeLayout>
4.activity_preview.xml实现拍照后图片放大预览

 

 

01. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03. android:layout_width="match_parent"
04. android:layout_height="match_parent"
05. android:background="#000000"
06. android:orientation="vertical" >
07.  
08. <TextView
09. android:layout_width="match_parent"
10. android:layout_height="wrap_content"
11. android:gravity="center"
12. android:text="拍照图片预览"
13. android:textColor="#FF0000"
14. android:textSize="20sp"
15. />
16.  
17. <ImageView
18. android:id="@+id/id_preview_camera_iv"
19. android:layout_width="wrap_content"
20. android:layout_height="wrap_content"
21. android:gravity="center" />
22.  
23. </LinearLayout>

二.java代码实现

 

1.帮助类HelpUtil.java

 

01. package com.example.camerasurfacedemo;
02.  
03. import java.io.FileInputStream;
04. import java.io.FileNotFoundException;
05. import java.io.IOException;
06. import java.text.SimpleDateFormat;
07. import java.util.Date;
08.  
09. import android.annotation.SuppressLint;
10. import android.content.ContentResolver;
11. import android.graphics.Bitmap;
12. import android.graphics.BitmapFactory;
13. import android.graphics.Matrix;
14. import android.net.Uri;
15.  
16. public class HelpUtil {
17. /**
18. * 根据图片路径获取本地图片的Bitmap
19. *
20. * @param url
21. * @return
22. */
23. public static Bitmap getBitmapByUrl(String url) {
24. FileInputStream fis = null;
25. Bitmap bitmap = null;
26. try {
27. fis = new FileInputStream(url);
28. bitmap = BitmapFactory.decodeStream(fis);
29.  
30. catch (FileNotFoundException e) {
31. // TODO Auto-generated catch block
32. e.printStackTrace();
33. bitmap = null;
34. finally {
35. if (fis != null) {
36. try {
37. fis.close();
38. catch (IOException e) {
39. // TODO Auto-generated catch block
40. e.printStackTrace();
41. }
42. fis = null;
43. }
44. }
45.  
46. return bitmap;
47. }
48.  
49. /**
50. * bitmap旋转90度
51. *
52. * @param bitmap
53. * @return
54. */
55. public static Bitmap createRotateBitmap(Bitmap bitmap) {
56. if (bitmap != null) {
57. Matrix m = new Matrix();
58. try {
59. m.setRotate(90, bitmap.getWidth() / 2, bitmap.getHeight() / 2);// 90就是我们需要选择的90度
60. Bitmap bmp2 = Bitmap.createBitmap(bitmap, 00,
61. bitmap.getWidth(), bitmap.getHeight(), m, true);
62. bitmap.recycle();
63. bitmap = bmp2;
64. catch (Exception ex) {
65. System.out.print("创建图片失败!" + ex);
66. }
67. }
68. return bitmap;
69. }
70.  
71. public static Bitmap getBitmapByUri(Uri uri,ContentResolver cr){
72. Bitmap bitmap = null;
73. try {
74. bitmap = BitmapFactory.decodeStream(cr
75. .openInputStream(uri));
76. catch (FileNotFoundException e) {
77. // TODO Auto-generated catch block
78. e.printStackTrace();
79. bitmap = null;
80. }
81. return bitmap;
82. }
83.  
84. /**
85. * 获取格式化日期字符串
86. * @param date
87. * @return
88. */
89. @SuppressLint("SimpleDateFormat")
90. public static String getDateFormatString(Date date) {
91. if (date == null)
92. date = new Date();
93. String formatStr = new String();
94. SimpleDateFormat matter = new SimpleDateFormat("yyyyMMdd_HHmmss");
95. formatStr = matter.format(date);
96. return formatStr;
97. }
98. }

2.主函数类MainActivity.java

 

 

01. package com.example.camerasurfacedemo;
02.  
03. import android.app.Activity;
04. import android.content.Intent;
05. import android.net.Uri;
06. import android.os.Bundle;
07. import android.text.TextUtils;
08. import android.view.View;
09. import android.view.View.OnClickListener;
10. import android.widget.Button;
11. import android.widget.ImageView;
12.  
13. public class MainActivity extends Activity {
14.  
15. private Button goCameraBtn;
16. private ImageView showCameraIv;
17. private static final int CAMERA_CODE = 1;
18. @Override
19. protected void onCreate(Bundle savedInstanceState) {
20. super.onCreate(savedInstanceState);
21. setContentView(R.layout.activity_main);
22.  
23. goCameraBtn = (Button)this.findViewById(R.id.id_go_camera_btn);
24. goCameraBtn.setOnClickListener(new OnClickListener(){
25.  
26. @Override
27. public void onClick(View v) {
28. processGoCamera();
29. }
30.  
31. });
32.  
33. showCameraIv = (ImageView)this.findViewById(R.id.id_show_camera_iv);
34. showCameraIv.setOnClickListener(new OnClickListener(){
35.  
36. @Override
37. public void onClick(View v) {
38. processShowCamera(v);
39. }
40.  
41. });
42. }
43.  
44. /**
45. * 处理进入camera事件
46. */
47. private void processGoCamera(){
48. Intent intent = new Intent();
49. intent.setClass(this, CameraActivity.class);
50. startActivityForResult(intent,CAMERA_CODE);
51. }
52.  
53. /**
54. * 处理图片跳转进入预览界面
55. */
56. private void processShowCamera(View v){
57. Intent intent = new Intent();
58. intent.setClass(this, PreviewActivity.class);
59. /**
60. * 将图片url传给PreviewActivity
61. */
62. intent.putExtra("cameraUrl", v.getContentDescription().toString());
63. startActivity(intent);
64. }
65.  
66. @Override
67. public void onActivityResult(int requestCode,int resultCode,Intent data){
68. super.onActivityResult(requestCode, resultCode, data);
69.  
70. if(RESULT_OK == resultCode){
71. if(CAMERA_CODE == requestCode){
72. /**
73. * 获取activity返回的url
74. */
75. Uri uri = data.getData();
76. String url = uri.toString().substring(uri.toString().indexOf("///")+2);
77. if(url != null && !TextUtils.isEmpty(url)){
78. showCameraIv.setContentDescription(url);
79. showCameraIv.setImageBitmap(HelpUtil.getBitmapByUrl(url));
80. }
81. }
82. }
83.  
84. }
85.  
86. }

 

注意:这里通过startActivityForResult(intent,CAMERA_CODE)跳转和 onActivityResult(int requestCode,int resultCode,Intent data)返回拍照后的图片路径信息

3.自定义Camera preview类CameraActivity.java

 

001. package com.example.camerasurfacedemo;
002.  
003. import java.io.File;
004. import java.io.FileNotFoundException;
005. import java.io.FileOutputStream;
006. import java.io.IOException;
007. import java.util.Date;
008.  
009. import android.annotation.SuppressLint;
010. import android.app.Activity;
011. import android.content.Context;
012. import android.content.Intent;
013. import android.content.pm.PackageManager;
014. import android.graphics.ImageFormat;
015. import android.hardware.Camera;
016. import android.hardware.Camera.CameraInfo;
017. import android.hardware.Camera.Parameters;
018. import android.hardware.Camera.PictureCallback;
019. import android.net.Uri;
020. import android.os.Bundle;
021. import android.os.Environment;
022. import android.util.Log;
023. import android.view.SurfaceHolder;
024. import android.view.SurfaceView;
025. import android.view.View;
026. import android.view.View.OnClickListener;
027. import android.view.Window;
028. import android.widget.Button;
029.  
030. public class CameraActivity extends Activity implements OnClickListener,
031. SurfaceHolder.Callback {
032.  
033. private static final String TAG = CameraActivity.class.getSimpleName();
034. private static final int MEDIA_TYPE_IMAGE = 1;
035. private Button switchCameraBtn, captureBtn;
036. private SurfaceView surfaceSv;
037.  
038. private SurfaceHolder mHolder;
039. private Camera mCamera;
040. // 0表示后置,1表示前置
041. private int cameraPosition = 1;
042.  
043. @Override
044. protected void onCreate(Bundle savedInstanceState) {
045. super.onCreate(savedInstanceState);
046. // 不显示标题
047. this.requestWindowFeature(Window.FEATURE_NO_TITLE);
048. setContentView(R.layout.activity_camera);
049.  
050. findById();
051. initData();
052. }
053.  
054. /**
055. * 初始化view
056. */
057. private void findById() {
058. switchCameraBtn = (Button) this.findViewById(R.id.id_switch_camera_btn);
059. captureBtn = (Button) this.findViewById(R.id.id_capture_btn);
060. surfaceSv = (SurfaceView) this.findViewById(R.id.id_area_sv);
061.  
062. switchCameraBtn.setOnClickListener(this);
063. captureBtn.setOnClickListener(this);
064. }
065.  
066. /**
067. * 初始化相关data
068. */
069. private void initData() {
070. // 获得句柄
071. mHolder = surfaceSv.getHolder();
072. // 添加回调
073. mHolder.addCallback(this);
074. }
075.  
076. @Override
077. public void onStart() {
078. super.onStart();
079. if (this.checkCameraHardware(this) && (mCamera == null)) {
080. // 打开camera
081. mCamera = getCamera();
082. if (mHolder != null) {
083. setStartPreview(mCamera,mHolder);
084. }
085. }
086. }
087.  
088. private Camera getCamera() {
089. Camera camera = null;
090. try {
091. camera = Camera.open();
092. catch (Exception e) {
093. // Camera is not available (in use or does not exist)
094. camera = null;
095. Log.e(TAG, "Camera is not available (in use or does not exist)");
096. }
097. return camera;
098. }
099.  
100. @Override
101. public void onPause() {
102. super.onPause();
103. /**
104. * 记得释放camera,方便其他应用调用
105. */
106. releaseCamera();
107. }
108.  
109. @Override
110. public void onDestroy() {
111. super.onDestroy();
112. }
113.  
114. /**
115. * 释放mCamera
116. */
117. private void releaseCamera() {
118. if (mCamera != null) {
119. mCamera.setPreviewCallback(null);
120. mCamera.stopPreview();// 停掉原来摄像头的预览
121. mCamera.release();
122. mCamera = null;
123. }
124. }
125.  
126. @Override
127. public void onClick(View v) {
128. switch (v.getId()) {
129. case R.id.id_switch_camera_btn:
130. // 切换前后摄像头
131. int cameraCount = 0;
132. CameraInfo cameraInfo = new CameraInfo();
133. cameraCount = Camera.getNumberOfCameras();// 得到摄像头的个数
134.  
135. for (int i = 0; i < cameraCount; i++) {
136. Camera.getCameraInfo(i, cameraInfo);// 得到每一个摄像头的信息
137. if (cameraPosition == 1) {
138. // 现在是后置,变更为前置
139. if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
140. /**
141. * 记得释放camera,方便其他应用调用
142. */
143. releaseCamera();
144. // 打开当前选中的摄像头
145. mCamera = Camera.open(i);
146. // 通过surfaceview显示取景画面
147. setStartPreview(mCamera,mHolder);
148. cameraPosition = 0;
149. break;
150. }
151. else {
152. // 现在是前置, 变更为后置
153. if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
154. /**
155. * 记得释放camera,方便其他应用调用
156. */
157. releaseCamera();
158. mCamera = Camera.open(i);
159. setStartPreview(mCamera,mHolder);
160. cameraPosition = 1;
161. break;
162. }
163. }
164.  
165. }
166. break;
167. case R.id.id_capture_btn:
168. // 拍照,设置相关参数
169. Camera.Parameters params = mCamera.getParameters();
170. params.setPictureFormat(ImageFormat.JPEG);
171. params.setPreviewSize(800400);
172. // 自动对焦
173. params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
174. mCamera.setParameters(params);
175. mCamera.takePicture(nullnull, picture);
176. break;
177. }
178. }
179.  
180. @Override
181. public void surfaceCreated(SurfaceHolder holder) {
182.  
183. setStartPreview(mCamera,mHolder);
184. }
185.  
186. @Override
187. public void surfaceChanged(SurfaceHolder holder, int format, int width,
188. int height) {
189. // If your preview can change or rotate, take care of those events here.
190. // Make sure to stop the preview before resizing or reformatting it.
191.  
192. if (mHolder.getSurface() == null) {
193. // preview surface does not exist
194. return;
195. }
196.  
197. // stop preview before making changes
198. try {
199. mCamera.stopPreview();
200. catch (Exception e) {
201. // ignore: tried to stop a non-existent preview
202. }
203.  
204. // set preview size and make any resize, rotate or
205. // reformatting changes here
206.  
207. // start preview with new settings
208. setStartPreview(mCamera,mHolder);
209. }
210.  
211. @Override
212. public void surfaceDestroyed(SurfaceHolder holder) {
213. // 当surfaceview关闭时,关闭预览并释放资源
214. /**
215. * 记得释放camera,方便其他应用调用
216. */
217. releaseCamera();
218. holder = null;
219. surfaceSv = null;
220. }
221.  
222. /**
223. * 创建png图片回调数据对象
224. */
225. PictureCallback picture = new PictureCallback() {
226. @Override
227. public void onPictureTaken(byte[] data, Camera camera) {
228. File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
229. if (pictureFile == null) {
230. Log.d(TAG,
231. "Error creating media file, check storage permissions: ");
232. return;
233. }
234. try {
235. FileOutputStream fos = new FileOutputStream(pictureFile);
236. fos.write(data);
237. fos.close();
238. returnResult(pictureFile);
239. catch (FileNotFoundException e) {
240. Log.d(TAG, "File not found: " + e.getMessage());
241. catch (IOException e) {
242. Log.d(TAG, "Error accessing file: " + e.getMessage());
243. }
244. }
245. };
246.  
247. /**
248. * Create a File for saving an image or video
249. */
250. private static File getOutputMediaFile(int type) {
251. // To be safe, you should check that the SDCard is mounted
252. // using Environment.getExternalStorageState() before doing this.
253.  
254. File mediaStorageDir = new File(
255. Environment
256. .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
257. "MyCameraApp");
258. // This location works best if you want the created images to be shared
259. // between applications and persist after your app has been uninstalled.
260.  
261. // Create the storage directory if it does not exist
262. if (!mediaStorageDir.exists()) {
263. if (!mediaStorageDir.mkdirs()) {
264. Log.d("MyCameraApp""failed to create directory");
265. return null;
266. }
267. }
268.  
269. // Create a media file name
270. String timeStamp = HelpUtil.getDateFormatString(new Date());
271. File mediaFile;
272. if (type == MEDIA_TYPE_IMAGE) {
273. mediaFile = new File(mediaStorageDir.getPath() + File.separator
274. "IMG_" + timeStamp + ".png");
275. else {
276. return null;
277. }
278. return mediaFile;
279. }
280.  
281. /** Check if this device has a camera */
282. private boolean checkCameraHardware(Context context) {
283. if (context.getPackageManager().hasSystemFeature(
284. PackageManager.FEATURE_CAMERA)) {
285. // this device has a camera
286. return true;
287. else {
288. // no camera on this device
289. return false;
290. }
291. }
292.  
293. /**
294. * activity返回式返回拍照图片路径
295. * @param mediaFile
296. */
297. private void returnResult(File mediaFile) {
298. Intent intent = new Intent();
299. intent.setData(Uri.fromFile(mediaFile));
300. this.setResult(RESULT_OK, intent);
301. this.finish();
302. }
303.  
304. /**
305. * 设置camera显示取景画面,并预览
306. * @param camera
307. */
308. private void setStartPreview(Camera camera,SurfaceHolder holder){
309. try {
310. camera.setPreviewDisplay(holder);
311. camera.startPreview();
312. catch (IOException e) {
313. Log.d(TAG, "Error starting camera preview: " + e.getMessage());
314. }
315. }
316. }

注意:

 

1.检查Camera是否存在

 

01. /** Check if this device has a camera */
02. private boolean checkCameraHardware(Context context) {
03. if (context.getPackageManager().hasSystemFeature(
04. PackageManager.FEATURE_CAMERA)) {
05. // this device has a camera
06. return true;
07. else {
08. // no camera on this device
09. return false;
10. }
11. }

2.创建png格式的回调接口

 

 

01. /**
02. * 创建png图片回调数据对象
03. */
04. PictureCallback picture = new PictureCallback() {
05. @Override
06. public void onPictureTaken(byte[] data, Camera camera) {
07. File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
08. if (pictureFile == null) {
09. Log.d(TAG,
10. "Error creating media file, check storage permissions: ");
11. return;
12. }
13. try {
14. FileOutputStream fos = new FileOutputStream(pictureFile);
15. fos.write(data);
16. fos.close();
17. returnResult(pictureFile);
18. catch (FileNotFoundException e) {
19. Log.d(TAG, "File not found: " + e.getMessage());
20. catch (IOException e) {
21. Log.d(TAG, "Error accessing file: " + e.getMessage());
22. }
23. }
24. };

3.生成图片文件并保存

 

 

01. /**
02. * Create a File for saving an image or video
03. */
04. private static File getOutputMediaFile(int type) {
05. // To be safe, you should check that the SDCard is mounted
06. // using Environment.getExternalStorageState() before doing this.
07.  
08. File mediaStorageDir = new File(
09. Environment
10. .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
11. "MyCameraApp");
12. // This location works best if you want the created images to be shared
13. // between applications and persist after your app has been uninstalled.
14.  
15. // Create the storage directory if it does not exist
16. if (!mediaStorageDir.exists()) {
17. if (!mediaStorageDir.mkdirs()) {
18. Log.d("MyCameraApp""failed to create directory");
19. return null;
20. }
21. }
22.  
23. // Create a media file name
24. String timeStamp = HelpUtil.getDateFormatString(new Date());
25. File mediaFile;
26. if (type == MEDIA_TYPE_IMAGE) {
27. mediaFile = new File(mediaStorageDir.getPath() + File.separator
28. "IMG_" + timeStamp + ".png");
29. else {
30. return null;
31. }
32. return mediaFile;
33. }

4.Camera一定要release

 

 

01. /**
02. * 释放mCamera
03. */
04. private void releaseCamera() {
05. if (mCamera != null) {
06. mCamera.setPreviewCallback(null);
07. mCamera.stopPreview();// 停掉原来摄像头的预览
08. mCamera.release();
09. mCamera = null;
10. }
11. }

5.Activity结果返回

 

 

01. /**
02. * activity返回式返回拍照图片路径
03. * @param mediaFile
04. */
05. private void returnResult(File mediaFile) {
06. Intent intent = new Intent();
07. intent.setData(Uri.fromFile(mediaFile));
08. this.setResult(RESULT_OK, intent);
09. this.finish();
10. }

4.图片正常预览PreviewActivity.java

 

 

01. package com.example.camerasurfacedemo;
02.  
03. import android.app.Activity;
04. import android.content.Intent;
05. import android.os.Bundle;
06. import android.text.TextUtils;
07. import android.view.Window;
08. import android.widget.ImageView;
09. import android.widget.Toast;
10.  
11. public class PreviewActivity extends Activity {
12.  
13. private ImageView previewCameraIv;
14. @Override
15. protected void onCreate(Bundle savedInstanceState) {
16. super.onCreate(savedInstanceState);
17. this.requestWindowFeature(Window.FEATURE_NO_TITLE);
18. setContentView(R.layout.activity_preview);
19.  
20.  
21. previewCameraIv = (ImageView)this.findViewById(R.id.id_preview_camera_iv);
22.  
23. Intent intent = this.getIntent();
24. String cameraUrl = intent.getStringExtra("cameraUrl").toString();
25. if(cameraUrl != null && !TextUtils.isEmpty(cameraUrl)){
26. previewCameraIv.setImageBitmap(HelpUtil.getBitmapByUrl(cameraUrl));
27. }else{
28. Toast.makeText(this"图片路径错误", Toast.LENGTH_SHORT).show();
29. }
30. }
31.  
32.  
33. }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问题。首先,让我们来看一下如何实现自定义Camera和前后摄像头切换。 1. 自定义Camera 首先,在AndroidManifest.xml文件中添加以下权限: ``` <uses-feature android:name="android.hardware.camera" /> <uses-permission android:name="android.permission.CAMERA" /> ``` 然后,在你的Activity中,创建一个Preview类,继承SurfaceView,并实现SurfaceHolder.Callback接口。 ``` public class Preview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; public Preview(Context context, Camera camera) { super(context); mCamera = camera; mHolder = getHolder(); mHolder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { Log.d("Preview", "Error setting camera preview: " + e.getMessage()); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (mHolder.getSurface() == null) { return; } try { mCamera.stopPreview(); } catch (Exception e) { Log.d("Preview", "Error stopping camera preview: " + e.getMessage()); } try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception e) { Log.d("Preview", "Error starting camera preview: " + e.getMessage()); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { mCamera.stopPreview(); mHolder.removeCallback(this); } } ``` 然后,在你的Activity中,创建一个Camera对象,并将其设给Preview类。 ``` public class CameraActivity extends Activity { private Camera mCamera; private Preview mPreview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mCamera = getCameraInstance(); mPreview = new Preview(this, mCamera); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(mPreview); } public static Camera getCameraInstance() { Camera c = null; try { c = Camera.open(); } catch (Exception e) { Log.d("CameraActivity", "Error opening camera: " + e.getMessage()); } return c; } } ``` 2. 前后摄像头切换 为了实现前后摄像头切换,你需要先判断设备是否支持前摄像头。如果支持,你可以通过Camera.getNumberOfCameras()方法来获取设备上可用的摄像头数量。然后,你可以通过Camera.open()方法打开指定的摄像头。 ``` public void switchCamera() { if (Camera.getNumberOfCameras() > 1) { mCamera.stopPreview(); mCamera.release(); mCamera = null; if (currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) { currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT; } else { currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK; } mCamera = Camera.open(currentCameraId); mPreview.setCamera(mCamera); try { mCamera.setPreviewDisplay(mHolder); } catch (IOException e) { Log.d("CameraActivity", "Error setting camera preview: " + e.getMessage()); } mCamera.startPreview(); } } ``` 3. 图片缩小放大预览 为了实现图片的缩小和放大预览,你可以使用Matrix类来对Bitmap进行缩放操作。 ``` public void zoom(float scale) { Matrix matrix = new Matrix(); matrix.postScale(scale, scale); Bitmap scaledBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true); mImageView.setImageBitmap(scaledBitmap); } ``` 这样,你就可以实现自定义Camera和前后摄像头切换以及图片缩小放大预览了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值