├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ └── layout
│ │ │ │ ├── activity_main.xml
│ │ │ │ └── activity_customer_camera.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── fizzer
│ │ │ │ └── doraemon
│ │ │ │ └── customercamera
│ │ │ │ ├── Logger.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── CameraFrameView.java
│ │ │ │ ├── CustomerCameraActivity.java
│ │ │ │ └── CameraSurfaceView.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── fizzer
│ │ │ └── doraemon
│ │ │ └── customercamera
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── fizzer
│ │ └── doraemon
│ │ └── customercamera
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── test.gif
├── .idea
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── modules.xml
├── runConfigurations.xml
├── compiler.xml
├── gradle.xml
└── misc.xml
├── .gitignore
├── .github
└── workflows
│ └── android.yml
├── README.md
└── gradle.properties
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/test.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fizzzzer/Android_Fizzer_CustomerCamera/HEAD/test.gif
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CustomerCamera
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fizzzzer/Android_Fizzer_CustomerCamera/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fizzzzer/Android_Fizzer_CustomerCamera/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fizzzzer/Android_Fizzer_CustomerCamera/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fizzzzer/Android_Fizzer_CustomerCamera/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fizzzzer/Android_Fizzer_CustomerCamera/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fizzer/doraemon/customercamera/Logger.java:
--------------------------------------------------------------------------------
1 | package com.fizzer.doraemon.customercamera;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Created by Fizzer on 2016/12/30.
7 | * Email: doraemonmqq@sina.com
8 | */
9 |
10 | public class Logger {
11 | public static void myLog(String msg){
12 | Log.e("Fizzer",msg);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v2
12 | - name: set up JDK 1.8
13 | uses: actions/setup-java@v1
14 | with:
15 | java-version: 1.8
16 | - name: Build with Gradle
17 | run: ./gradlew build
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android_Fizzer_CustomerCamera
2 |
3 | 这里是一个自定义的相机功能,可以根据自己的项目需求,更改相机拍照的界面view,效果图如下
4 | 
5 |
6 | ###使用
7 | 在`OnActivityResult`中可以接受拍照返回来的图片
8 | ```java
9 | String path = data.getStringExtra("data");
10 | ```
11 | 这里面的path就是拍照返回的图片路径,拿到这个图片路径,想干啥就可以干啥了
12 | 后面的就不在多说了,在代码中都可以看,如果有写的不好的地方,望斧正
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/fizzer/doraemon/customercamera/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.fizzer.doraemon.customercamera;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/Doraemon/Documents/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/fizzer/doraemon/customercamera/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.fizzer.doraemon.customercamera;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.fizzer.doraemon.customercamera", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.1"
6 | defaultConfig {
7 | applicationId "com.fizzer.doraemon.customercamera"
8 | minSdkVersion 22
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:25.0.1'
28 | testCompile 'junit:junit:4.12'
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_customer_camera.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
14 |
15 |
18 |
19 |
27 |
28 |
34 |
35 |
42 |
43 |
44 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fizzer/doraemon/customercamera/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.fizzer.doraemon.customercamera;
2 |
3 | import android.content.Intent;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Point;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.os.Bundle;
9 | import android.view.View;
10 | import android.view.WindowManager;
11 | import android.widget.ImageView;
12 |
13 | public class MainActivity extends AppCompatActivity {
14 |
15 | private ImageView mImageView;
16 | private int OPEN_CAMERA = 200;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_main);
22 |
23 | mImageView = (ImageView) findViewById(R.id.Image);
24 | }
25 |
26 | public void TakePhoto(View view) {
27 | Intent intent = new Intent(this, CustomerCameraActivity.class);
28 | startActivityForResult(intent, OPEN_CAMERA);
29 | }
30 |
31 | @Override
32 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
33 |
34 | if (CustomerCameraActivity.RESULT_OK != resultCode) {
35 | return;
36 | }
37 |
38 | if (OPEN_CAMERA == requestCode) {
39 | String path = data.getStringExtra("data");
40 | showImg(path, mImageView);
41 | }
42 | }
43 |
44 | /**
45 | * 展示图片
46 | *
47 | * @param path 图片路径
48 | * @param img 显示图片的控件
49 | */
50 | private void showImg(String path, ImageView img) {
51 | BitmapFactory.Options option = new BitmapFactory.Options();
52 | option.inJustDecodeBounds = true; //不去真的解析图片,只是获取宽高信息
53 | BitmapFactory.decodeFile(path, option);
54 |
55 | int width = option.outWidth;
56 | int height = option.outHeight;
57 | Logger.myLog("宽度=" + width + "高度=" + height);
58 |
59 | WindowManager wm = (WindowManager) this.getSystemService(WINDOW_SERVICE);
60 | Point outPoint = new Point();
61 | wm.getDefaultDisplay().getSize(outPoint);
62 | //计算缩放比
63 | int scale = 1;
64 | int scalex = width / 300;
65 | int scaley = height / 200;
66 | scale = scalex > scaley ? scalex : scaley;
67 | option.inSampleSize = scale;
68 | //开始真正的解析图片
69 | option.inJustDecodeBounds = false;
70 | Bitmap bitmap = BitmapFactory.decodeFile(path, option);
71 | Logger.myLog("缩放后的宽度=" + option.outWidth + "缩放后的高度=" + option.outHeight);
72 | img.setImageBitmap(bitmap);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
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 | 1.8
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fizzer/doraemon/customercamera/CameraFrameView.java:
--------------------------------------------------------------------------------
1 | package com.fizzer.doraemon.customercamera;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Point;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 | import android.view.WindowManager;
11 |
12 |
13 | /**
14 | * Created by Fizzer on 2016/12/28.
15 | * Email: doraemonmqq@sina.com
16 | */
17 |
18 | public class CameraFrameView extends View {
19 |
20 | private Context mContext;
21 | private Paint mPaint;
22 | //左上角的点 Left-Top Point
23 | private Point mLTPoint;
24 | //右上角的点 Right-Top Point
25 | private Point mRTPoint;
26 | //左下角的点 Left-Bottom Point
27 | private Point mLBPoint;
28 | //右下角的点 Right-Bottom Point
29 | private Point mRBPoint;
30 |
31 | private Point centerPoint;
32 |
33 | //画线的长度
34 | private int lineLength = 50;
35 |
36 | public CameraFrameView(Context context) {
37 | super(context);
38 | }
39 |
40 | public CameraFrameView(Context context, AttributeSet attrs) {
41 | super(context, attrs);
42 | init(context);
43 | }
44 |
45 | public CameraFrameView(Context context, AttributeSet attrs, int defStyleAttr) {
46 | super(context, attrs, defStyleAttr);
47 | }
48 |
49 | /**
50 | * 初始化
51 | */
52 | private void init(Context context) {
53 | mContext = context;
54 |
55 | mPaint = new Paint();
56 | mPaint.setStyle(Paint.Style.STROKE); //画笔类型
57 | mPaint.setColor(Color.parseColor("#ff0000")); //设置画笔颜色
58 | mPaint.setStrokeWidth(5); //设置画笔宽度
59 |
60 | Point screenPoint = getScreenPoint();
61 | //初始化左上角的点
62 | mLTPoint = new Point(screenPoint.x / 5, screenPoint.y / 6);
63 | //初始化右上角的点
64 | mRTPoint = new Point(screenPoint.x / 5 * 4, screenPoint.y / 6);
65 | //初始化左下角的点
66 | mLBPoint = new Point(screenPoint.x / 5, screenPoint.y / 6 * 4);
67 | //初始化右下角的点
68 | mRBPoint = new Point(screenPoint.x / 5 * 4, screenPoint.y / 6 * 4);
69 |
70 | //中间点
71 | centerPoint = new Point((mLTPoint.x + mRTPoint.x) / 2, (mLTPoint.y + mLBPoint.y) / 2);
72 | }
73 |
74 | @Override
75 | protected void onDraw(Canvas canvas) {
76 | drawArec(canvas);
77 | }
78 |
79 | private void drawArec(Canvas canvas) {
80 |
81 | //画左上角的折线
82 | canvas.drawLine(mLTPoint.x, mLTPoint.y, mLTPoint.x + lineLength, mLTPoint.y, mPaint);
83 | canvas.drawLine(mLTPoint.x, mLTPoint.y, mLTPoint.x, mLTPoint.y + lineLength, mPaint);
84 |
85 | //画右上角的折线
86 | canvas.drawLine(mRTPoint.x, mRTPoint.y, mRTPoint.x - lineLength, mRTPoint.y, mPaint);
87 | canvas.drawLine(mRTPoint.x, mRTPoint.y, mRTPoint.x, mRTPoint.y + lineLength, mPaint);
88 |
89 | //画左下角的折线
90 | canvas.drawLine(mLBPoint.x, mLBPoint.y, mLBPoint.x + lineLength, mLBPoint.y, mPaint);
91 | canvas.drawLine(mLBPoint.x, mLBPoint.y, mLBPoint.x, mLBPoint.y - lineLength, mPaint);
92 |
93 | //画右下角的折线
94 | canvas.drawLine(mRBPoint.x, mRBPoint.y, mRBPoint.x - lineLength, mRBPoint.y, mPaint);
95 | canvas.drawLine(mRBPoint.x, mRBPoint.y, mRBPoint.x, mRBPoint.y - lineLength, mPaint);
96 |
97 | canvas.drawLine(centerPoint.x - 25, centerPoint.y, centerPoint.x + 25, centerPoint.y, mPaint);
98 | canvas.drawLine(centerPoint.x, centerPoint.y - 25, centerPoint.x, centerPoint.y + 25, mPaint);
99 | }
100 |
101 | /**
102 | * 获取屏幕的大小
103 | *
104 | * @return 返回屏幕的右下角的点
105 | * 横坐标就是屏幕的宽,纵坐标就是屏幕的高
106 | */
107 | private Point getScreenPoint() {
108 | WindowManager wm = (WindowManager) getContext()
109 | .getSystemService(Context.WINDOW_SERVICE);
110 | Point point = new Point();
111 | wm.getDefaultDisplay().getSize(point);
112 |
113 | return point;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fizzer/doraemon/customercamera/CustomerCameraActivity.java:
--------------------------------------------------------------------------------
1 | package com.fizzer.doraemon.customercamera;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.hardware.Camera;
6 | import android.os.Bundle;
7 | import android.os.Environment;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.Toast;
11 |
12 | import java.io.BufferedOutputStream;
13 | import java.io.File;
14 | import java.io.FileOutputStream;
15 | import java.io.IOException;
16 |
17 | public class CustomerCameraActivity extends Activity implements View.OnClickListener {
18 |
19 | private CameraSurfaceView mView;
20 | private Button mTakePicture;
21 | private Button mTakeCancel;
22 | private Button mTakeOk;
23 | String filePath;
24 | private byte[] bitmapData;
25 |
26 | public static int RESULT_OK = 100;
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_customer_camera);
31 |
32 | mView = (CameraSurfaceView) findViewById(R.id.CameraView);
33 | mTakePicture = (Button) findViewById(R.id.btnTake);
34 | mTakeCancel = (Button) findViewById(R.id.takeCancel);
35 | mTakeOk = (Button) findViewById(R.id.takeOk);
36 |
37 | mTakePicture.setOnClickListener(this);
38 | mTakeCancel.setOnClickListener(this);
39 | mTakeOk.setOnClickListener(this);
40 | setTakeView();
41 | }
42 |
43 | public void Camera(View view){
44 | mView.takePicture(jpeg);
45 | }
46 |
47 | //创建jpeg图片回调数据对象
48 | private Camera.PictureCallback jpeg = new Camera.PictureCallback() {
49 |
50 | @Override
51 | public void onPictureTaken(byte[] data, Camera Camera) {
52 | //获取拍照的图像
53 | bitmapData = data;
54 | setAfterTakeView();
55 | }
56 | };
57 |
58 |
59 | /**
60 | * 保存图片
61 | */
62 | private void saveBitmap(byte[] data) {
63 | BufferedOutputStream bos = null;
64 | try {
65 | // 获得图片
66 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
67 |
68 | // String path = "/sdcard/Test";
69 | String path = Environment.getExternalStorageDirectory() + "/Fizzer";
70 | Logger.myLog(path);
71 | File tmpfile = new File(path);
72 | if(!tmpfile.exists()){
73 | tmpfile.mkdir();
74 | }
75 |
76 | filePath = path +"/"+System.currentTimeMillis() + ".jpg";//照片保存路径
77 | File file = new File(filePath);
78 | if (!file.exists()) {
79 | file.createNewFile();
80 | }
81 | bos = new BufferedOutputStream(new FileOutputStream(file));
82 | bos.write(data);
83 |
84 | } else {
85 | Toast.makeText(CustomerCameraActivity.this, "没有检测到内存卡", Toast.LENGTH_SHORT).show();
86 | }
87 | } catch (Exception e) {
88 | e.printStackTrace();
89 | } finally {
90 | try {
91 | bos.flush();//输出
92 | bos.close();//关闭
93 | } catch (IOException e) {
94 | e.printStackTrace();
95 | }
96 | }
97 | }
98 |
99 | /**
100 | * 设置拍照时的布局
101 | */
102 | private void setTakeView(){
103 | if(mTakePicture.getVisibility() == View.GONE){
104 | mTakePicture.setVisibility(View.VISIBLE);
105 | }
106 |
107 | if(mTakeCancel.getVisibility() == View.VISIBLE){
108 | mTakeCancel.setVisibility(View.GONE);
109 | }
110 |
111 | if(mTakeOk.getVisibility() == View.VISIBLE){
112 | mTakeOk.setVisibility(View.GONE);
113 | }
114 | }
115 |
116 | /**
117 | * 设置拍照结束的布局
118 | */
119 | private void setAfterTakeView(){
120 | if(mTakePicture.getVisibility() == View.VISIBLE){
121 | mTakePicture.setVisibility(View.GONE);
122 | }
123 |
124 | if(mTakeCancel.getVisibility() == View.GONE){
125 | mTakeCancel.setVisibility(View.VISIBLE);
126 | }
127 |
128 | if(mTakeOk.getVisibility() == View.GONE){
129 | mTakeOk.setVisibility(View.VISIBLE);
130 | }
131 | }
132 |
133 | @Override
134 | public void onClick(View v) {
135 |
136 | switch (v.getId()){
137 | case R.id.btnTake:
138 | mView.takePicture(jpeg); //拍照
139 | break;
140 | case R.id.takeCancel:
141 | mView.stopPreview();
142 | mView.startPreview();
143 | setTakeView(); //设置拍照时的布局
144 | break;
145 | case R.id.takeOk:
146 | saveBitmap(bitmapData); //保存图片
147 | Intent intent = new Intent();
148 | intent.putExtra("data",filePath);
149 | setResult(RESULT_OK,intent); //设置传递的数据
150 | this.finish();
151 | break;
152 | }
153 | }
154 |
155 | @Override
156 | protected void onPause() {
157 | super.onPause();
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/app/src/main/java/com/fizzer/doraemon/customercamera/CameraSurfaceView.java:
--------------------------------------------------------------------------------
1 | package com.fizzer.doraemon.customercamera;
2 |
3 | import android.content.Context;
4 | import android.hardware.Camera;
5 | import android.util.AttributeSet;
6 | import android.util.DisplayMetrics;
7 | import android.view.SurfaceHolder;
8 | import android.view.SurfaceView;
9 | import android.view.WindowManager;
10 | import android.widget.FrameLayout;
11 |
12 | import java.io.IOException;
13 | import java.util.List;
14 |
15 | /**
16 | * Created by Fizzer on 2016/12/27.
17 | * Email: doraemonmqq@sina.com
18 | * 自定义相机界面
19 | */
20 |
21 | public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback {
22 |
23 | private Context mContext;
24 | private SurfaceHolder mHolder;
25 | private Camera mCamera;
26 |
27 | private int mScreenWidth;
28 | private int mScreenHeight;
29 |
30 | public CameraSurfaceView(Context context) {
31 | super(context);
32 | }
33 |
34 | public CameraSurfaceView(Context context, AttributeSet attrs) {
35 | super(context, attrs);
36 | mContext = context;
37 | getScreenMetrix(mContext);
38 | initView();
39 | }
40 |
41 | public CameraSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
42 | super(context, attrs, defStyleAttr);
43 | mContext = context;
44 | getScreenMetrix(mContext);
45 | initView();
46 | }
47 |
48 | /**
49 | * 获取屏幕参数
50 | *
51 | * @param context context
52 | */
53 | private void getScreenMetrix(Context context) {
54 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
55 | DisplayMetrics outMetrics = new DisplayMetrics();
56 | wm.getDefaultDisplay().getMetrics(outMetrics);
57 | mScreenWidth = outMetrics.widthPixels;
58 | mScreenHeight = outMetrics.heightPixels;
59 | }
60 |
61 | /**
62 | * 初始化
63 | */
64 | private void initView() {
65 | mHolder = getHolder();
66 | mHolder.addCallback(this);
67 | mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
68 |
69 | }
70 |
71 | @Override
72 | public void surfaceCreated(SurfaceHolder holder) {
73 |
74 | if (mCamera == null) {
75 | mCamera = Camera.open();
76 | try {
77 | mCamera.setPreviewDisplay(mHolder);
78 | } catch (IOException e) {
79 | e.printStackTrace();
80 | }
81 | }
82 |
83 | }
84 |
85 | @Override
86 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
87 | setCameraParams(mCamera, mScreenWidth, mScreenHeight);
88 | mCamera.startPreview();
89 |
90 | }
91 |
92 | @Override
93 | public void surfaceDestroyed(SurfaceHolder holder) {
94 |
95 | mCamera.stopPreview(); //停止预览
96 | mCamera.release(); //释放相机资源
97 | mCamera = null;
98 | mHolder = null;
99 | }
100 |
101 | @Override
102 | public void onAutoFocus(boolean success, Camera camera) {
103 |
104 | Logger.myLog("自动对焦");
105 | if (success) {
106 | Logger.myLog("自动对焦成功");
107 | }
108 | }
109 |
110 |
111 | /**
112 | * 设置参数
113 | */
114 | private void setCameraParams(Camera camera, int width, int height) {
115 |
116 | Camera.Parameters parameters = camera.getParameters();
117 |
118 | //获取支持的pictureSize列表
119 | List pictureSizeList = parameters.getSupportedPictureSizes();
120 |
121 | // for(Camera.Size size : pictureSizeList){
122 | // Logger.myLog("size width=" + size.width + ">>size height=" + size.height);
123 | // }
124 |
125 | //从列表中选择合适的分辨率
126 | Camera.Size picSize = getProperSize(pictureSizeList, height / width);
127 |
128 | if (picSize == null) {
129 | picSize = parameters.getPictureSize();
130 | }
131 |
132 | //根据选出的picSize重新设置surfaceView的大小
133 | parameters.setPictureSize(picSize.width, picSize.height);
134 | // this.setLayoutParams(new FrameLayout.LayoutParams(picSize.width, picSize.height));
135 |
136 | Logger.myLog("选出来的宽=" + picSize.width + "选出来的高=" + picSize.height);
137 | // 获取摄像头支持的PreviewSize列表
138 | List previewSizeList = parameters.getSupportedPreviewSizes();
139 |
140 | Camera.Size preSize = getProperSize(previewSizeList, ((float) height) / width);
141 | if (null != preSize) {
142 | parameters.setPreviewSize(preSize.width, preSize.height);
143 | }
144 |
145 | parameters.setJpegQuality(100); // 设置照片质量
146 | if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
147 | parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 连续对焦模式
148 | }
149 |
150 | mCamera.cancelAutoFocus();//自动对焦。
151 | mCamera.setDisplayOrientation(90);// 设置PreviewDisplay的方向,效果就是将捕获的画面旋转多少度显示
152 | mCamera.setParameters(parameters);
153 |
154 | }
155 |
156 | /**
157 | * 选择合适的分辨率
158 | *
159 | * @return Camera.Size
160 | * 这里的 w 对应屏幕的height
161 | * h 对应屏幕的width
162 | */
163 | private Camera.Size getProperSize(List sizeList, float screenRatio) {
164 |
165 | Camera.Size result = null;
166 |
167 | for (Camera.Size size : sizeList) {
168 | float currentRatio = size.width / size.height;
169 | if (currentRatio - screenRatio == 0) {
170 | result = size;
171 | break;
172 | }
173 | }
174 |
175 | if (result == null) {
176 | for (Camera.Size size : sizeList) {
177 | float currentRation = size.width / size.height;
178 | if (currentRation == 4 / 3) { //默认的宽高比是4:3
179 | result = size;
180 | break;
181 | }
182 | }
183 | }
184 |
185 |
186 | return result;
187 | }
188 |
189 |
190 | /**
191 | * 停止预览
192 | */
193 | public void stopPreview() {
194 | mCamera.stopPreview();
195 | }
196 |
197 | /**
198 | * 开启预览
199 | */
200 | public void startPreview() {
201 | mCamera.startPreview();
202 | }
203 |
204 | public void takePicture(Camera.PictureCallback jpeg) {
205 | //设置参数,并拍照
206 | setCameraParams(mCamera, mScreenWidth, mScreenHeight);
207 | // 当调用camera.takePiture方法后,camera关闭了预览,这时需要调用startPreview()来重新开启预览
208 | mCamera.takePicture(null, null, jpeg);
209 |
210 | }
211 |
212 | }
213 |
--------------------------------------------------------------------------------