国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android自定義照相機倒計時拍照

Android自定義照相機倒計時拍照

2021-04-19 15:15Smile-奮而斗之 Android

本文給大家介紹Android自定義照相機,并且實現倒計時拍照功能,對android自定義照相機相關知識感興趣的朋友一起學習吧

自定義拍照會用到SurfaceView控件顯示照片的預覽區域,以下是布局文件:

兩個TextView是用來顯示提示信息和倒計時的秒數的

相關教程:Android開發從相機或相冊獲取圖片裁剪

Android啟動相機拍照并返回圖片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<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="#266194"
 android:orientation="vertical"
 tools:context=".TestActivity" >
 <SurfaceView
 android:id="@+id/surfaceView"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_centerInParent="true" />
 <LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerInParent="true"
 android:orientation="vertical" >
 <TextView
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="請調整位置到此區域"
 android:textColor="#ff0000"
 android:textSize="32sp" />
 <TextView
 android:id="@+id/tv_time"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:paddingTop="10dp"
 android:gravity="center_horizontal"
 android:textColor="#266194"
 android:textSize="32sp" />
 </LinearLayout>
</RelativeLayout>

接下來是mainActivity中的具體實現以及詳細注釋:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package com.dhsr.pujiejia.ui;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import com.example.pujiejiaapp.R;
@SuppressLint({ "NewApi", "SdCardPath" })
public class CameraActivity extends Activity implements Runnable {
 // 預覽圖片范圍
 private SurfaceView surfaceView;
 private TextView tv_time;
 // 倒計時拍攝
 private int cameratime = 4;
 private Camera camera;
 private boolean preview = false;
 // 文件名字
 private String filename;
 // 文件名字的帶的時間戳
 private String timeString;
 // 格式化時間
 private SimpleDateFormat dateFormat;
 // 日期對象
 private Date date;
 // 控制線程
 boolean stopThread = false;
 private File file;
 String photo;
 private Handler mHandler = new Handler() {
 public void handleMessage(android.os.Message msg) {
 int what = msg.what;
 switch (what) {
 case 222:
 tv_time.setText("" + cameratime);
 if ("0".equals(tv_time.getText().toString())) {
  tv_time.setText("拍攝成功!");
  takePhoto();
 }
 break;
 }
 };
 };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_test);
 CameraActivity.this.setFinishOnTouchOutside(false);
 // 初始化數據
 findView();
 surfaceView.getHolder().addCallback(new SufaceListener());
 /* 下面設置Surface不維護自己的緩沖區,而是等待屏幕的渲染引擎將內容推送到用戶面前 */
 surfaceView.getHolder()
 .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 surfaceView.getHolder().setFixedSize(200, 200); // 設置分辨率
 }
 @Override
 protected void onStart() {
 // TODO Auto-generated method stub
 super.onStart();
 // 開啟線程
 new Thread(this).start();
 }
 private final class SufaceListener implements SurfaceHolder.Callback {
 /**
 * surface改變
 */
 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
 int height) {
 }
 /**
 * surface創建
 */
 @Override
 public void surfaceCreated(SurfaceHolder holder) {
 try {
 for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
  CameraInfo info = new CameraInfo();
  Camera.getCameraInfo(i, info);
  // 調用系統的前置攝像頭
  if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
  camera = Camera.open(i);
  }
 }
 Camera.Parameters parameters = camera.getParameters();
 /* 每秒從攝像頭捕獲5幀畫面, */
 parameters.setPreviewFrameRate(5);
 /* 設置照片的輸出格式:jpg */
 parameters.setPictureFormat(PixelFormat.JPEG);
 /* 照片質量 */
 parameters.set("jpeg-quality", 85);
 WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
 camera.setParameters(parameters);
 camera.setPreviewDisplay(surfaceView.getHolder());// 通過SurfaceView顯示取景畫面
 camera.startPreview();
 preview = true;
 } catch (Exception e) {
 }
 }
 /**
 * surface銷毀
 */
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
 if (camera != null) {
 if (preview)
  camera.stopPreview();
 camera.release();
 camera = null;
 }
 }
 }
 /**
 * 拍攝照片
 */
 private void takePhoto() {
 // 執行拍照效果
 camera.takePicture(null, null, new Camera.PictureCallback() {
 @Override
 public void onPictureTaken(byte[] data, Camera camera) {
 try {
  Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
  data.length);
  timeString = formatDate();
  //保存到data/data目錄自定義文件夾下
  filename = "/data/data/com.example.pujiejiaapp/images/"
  + timeString + ".jpg";
  File file = new File(filename);
  boolean createNewFile = file.createNewFile()
  System.out.println("創建文件夾成功沒有" + createNewFile);
  System.out.println(file);
  FileOutputStream outStream = new FileOutputStream(file);
  bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);
  outStream.flush();
  outStream.close();
  // 重新瀏覽
  camera.stopPreview();
  camera.startPreview();
  preview = true;
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
 }
 }
 });
 }
 @Override
 public void run() {
 while (!stopThread) {
 try {
 //按秒數倒計時
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 cameratime--;
 mHandler.sendEmptyMessage(222);
 if (cameratime <= 0) {
 break;
 }
 }
 }
 // 初始化數據
 private void findView() {
 surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);
 tv_time = (TextView) findViewById(R.id.tv_time);
 }
 // 格式化系統的時間
 public String formatDate() {
 date = new Date(System.currentTimeMillis());
 // 日期格式
 dateFormat = new SimpleDateFormat("'IMG'_yyyyMMddHHmmss");
 return dateFormat.format(date);
 }
 @Override
 protected void onDestroy() {
 // TODO Auto-generated method stub
 // 線程已關閉
 super.onDestroy();
 stopThread = true;
 }
}

核心代碼詳解:

1.創建SurfaceView時,surfaceCreated()方法中

?
1
2
3
4
5
6
7
8
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
  CameraInfo info = new CameraInfo();
  Camera.getCameraInfo(i, info);
  // 調用系統的前置攝像頭
  if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
  camera = Camera.open(i);
  }
 }

此部分代碼為打開相機時默認打開前置攝像頭CameraInfo.CAMERA_FACING_BACK為默認打開后置攝像頭,CameraInfo.CAMERA_FACING_FRONT前置攝像頭

2.照片拍攝takePhoto()方法中:

?
1
2
3
4
5
6
7
8
9
10
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
  data.length);
  timeString = formatDate();
  filename = "/data/data/com.example.pujiejiaapp/images/"
  + timeString + ".jpg";
  photo = timeString + ".jpg";
  File file = new File(filename);
  boolean createNewFile = file.createNewFile();
  FileOutputStream outStream = new FileOutputStream(file);
  bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);

此部分代碼為將拍攝到的圖片保存為以bitmap格式保存在指定的目錄下

3.開子線程用于倒計時拍攝

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void run() {
 while (!stopThread) {
 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 cameratime--;
 mHandler.sendEmptyMessage(222);
 if (cameratime <= 0) {
 break;
 }
 }
 }

希望大家理解核心代碼的詳細注釋,歡迎提供意見,希望能給大家帶來幫助,謝謝!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲 中文 欧美 日韩 在线观看 | 婷婷综合色| 欧美成人精品一区二区三区 | 成人免费黄色毛片 | 亚洲久草 | 亚洲欧美在线播放 | 国产精品久久免费观看spa | 国产精品毛片在线 | 日韩电影一区二区三区 | 欧美视频网站 | 国内自拍偷拍视频 | 午夜精品久久久久 | 亚洲精品成人悠悠色影视 | 成人午夜精品久久久久久久网站 | 精品护士一区二区三区 | 91精品福利少妇午夜100集 | 亚洲一区二区中文字幕 | 欧美久久久久久久久久久久久久 | 91九色在线 | 精品影院 | 国产精品视频一二三区 | 亚洲精品在线观看网站 | 国产在线观看免费 | 美女视频一区二区三区 | 亚洲一区精品在线 | 中文字幕在线免费看 | 亚洲欧美在线观看 | 日韩视频在线一区二区 | 99久久久无码国产精品 | 成人欧美一区二区三区视频xxx | 精品久久久久久久久久久 | 精品成人影院 | 在线观看免费视频黄 | 久久久久一区二区三区 | 日韩在线精品视频 | 国产小视频在线播放 | 99手机在线视频 | 久久免费精品视频 | 麻豆.蜜桃.91.天美入口 | 一级黄色毛片免费观看 | www国产网站 |