java-Android 相机

相机

 

Androidmanifest 中需要加入

<uses-permission android:name="android.permission.CAMERA"/>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <SurfaceView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/surfaceview"/>


    <ImageButton
        android:src="@drawable/img1"
        android:id="@+id/take_photo"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"/>
    <ImageButton
        android:src="@drawable/img2"
        android:id="@+id/show_photo"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>

Mainactivity

package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private Camera camera = null;
    private boolean isPreview = false;  //设置是否为预览状态
    private SurfaceView surfaceView = null;
    private ImageButton takephoto = null;
    private ImageButton showphoto = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);  //mainactivty的布局方式采用的是activity_main.xml
        if (!android.os.Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            //判断是否拥有外部存储
            Toast.makeText(this,"没有sd卡",Toast.LENGTH_SHORT).show();
        }
        Permission pm = new Permission();
        pm.cheackpermission(this);  //动态获取权限
        surfaceView = findViewById(R.id.surfaceview);  //获取浮动预览窗口
        takephoto = findViewById(R.id.take_photo); //获取拍照按钮
        showphoto = findViewById(R.id.show_photo); //获取预览按钮
        Display display = getWindowManager().getDefaultDisplay();
        int width = display.getWidth();
        int height = display.getHeight();

        final SurfaceHolder surfaceHolder = surfaceView.getHolder(); //获取surfaceHolder
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //设置surfaceview自己不维护缓冲

        showphoto.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                if(!isPreview){ //如果当前并不是预览状态,则可以打开摄像头并修改ispreview
                    camera = Camera.open();
                    isPreview = true;
                }
                try {
                    camera.setPreviewDisplay(surfaceHolder);  //设置用于显示预览的Surfaceview
                    Camera.Parameters parameters = camera.getParameters(); //获取摄像头参数
//                    //到这,获取预览支持的分辨率种类列表
                    List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
                    int pre_max_sum = 0;
                    int[] pre_default_size = new int[2];
                    for (int xp = 0;xp < supportedPreviewSizes.size();xp++){  //找出支持的最高的
                        // 预览分辨率并且将长宽放进来pre_default_size里面
//                        System.out.println("支持的分辨率" + supportedPreviewSizes.get(xp).width
//                        + " " + supportedPreviewSizes.get(xp).height);
                        int now_sum = supportedPreviewSizes.get(xp).width + supportedPreviewSizes.get(xp).height;
                        if (now_sum > pre_max_sum){
                            pre_max_sum = now_sum;
                            pre_default_size[0] = supportedPreviewSizes.get(xp).width;
                            pre_default_size[1] = supportedPreviewSizes.get(xp).height;
                        }
                    }
                    List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
                    int pic_max_sum = 0;
                    int[] pic_default_size = new int[2];
                    for (int xp = 0;xp < supportedPictureSizes.size();xp++){//找出支持的最高的
                        // 图片分辨率并且将长宽放进来pic_default_size里面
//                        System.out.println("支持的图片的分辨率" + supportedPictureSizes.get(xp).width
//                                + " " + supportedPictureSizes.get(xp).height);
                        int now_sum = supportedPictureSizes.get(xp).width + supportedPictureSizes.get(xp).height;
                        if (now_sum > pic_max_sum) {
                            pic_max_sum = now_sum;
                            pic_default_size[0] = supportedPictureSizes.get(xp).width;
                            pic_default_size[1] = supportedPictureSizes.get(xp).height;
                        }
                    }
                    //到这,获取预览支持的图片分辨率种类列表
//                    List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
//                    System.out.println("新的尺寸"+new_scale);
                    parameters.setPictureFormat(PixelFormat.JPEG); //设置显示图片的格式为jpg
                    parameters.set("jpeg-quality",60);  //设置图片的质量
                    parameters.setPreviewSize(pre_default_size[0],pre_default_size[1]);
                    parameters.setPictureSize(pic_default_size[0], pic_default_size[1]);
                    camera.setParameters(parameters); //将参数设置传到相机
                    camera.setDisplayOrientation(90);
                    camera.startPreview();
//                    camera.autoFocus(null); //设置自动对焦
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        final Camera.PictureCallback jpeg = new Camera.PictureCallback(){
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
                //获取位图,不裁剪,从0到完整的长度,就是原图
                camera.stopPreview(); //停止预览
                isPreview = false; //设置为非预览状态
                File filepath = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                        + File.separator + "Zqhfile");
                if (filepath.exists() == false){
                    filepath.mkdirs();  //创建自己的filepath文件夹
                }
                File filename = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                        + File.separator + "Zqhfile" + File.separator + "img.jpg");
                if (filename.exists() == false){
                    try {
                        filename.createNewFile();  //创建图片文件
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try{
                    FileOutputStream fileOutputStream = new FileOutputStream(filename);
                    bitmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream);
                    //将位图写入文件
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }catch (Exception erro ){
                    System.out.println(erro);
                }
                Toast.makeText(MainActivity.this,"照片保存完成",
                        Toast.LENGTH_SHORT).show();
            }
        };

        takephoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (camera!=null) {
                    //预览状态已经打开,camera不为空值才能进行拍照
                    camera.takePicture(null,null,jpeg); //前两个用于回调,
                    // 在当前activity用null,第三个是Camera.PictureCallback的类
                }
            }
        });
    }
}

permission

package com.example.myapplication;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.ArrayList;
import java.util.List;

public class Permission {
    //高版本的安卓系统不仅需要在manifest中写权限
    // 程序中也需要动态申请权限,这是要申请的权限
    private String[] permission = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE,  //外部存储写权限
            Manifest.permission.READ_EXTERNAL_STORAGE,   //外部存储读权限
            Manifest.permission.CAMERA //相机使用权限
    };
    private List<String> need_permission = new ArrayList();
    private int REQUEST_CODE = 1000;

    public void cheackpermission(Activity activity){
        //在当前安卓系统版本大于6的时候才需要进行动态权限的申请
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            for (int i = 0;i<permission.length;i++){
                //逐条查询permission里面的权限看看是否都有,如果没有的话
                if (ContextCompat.checkSelfPermission(activity,permission[i]) !=
                        PackageManager.PERMISSION_GRANTED){
                    need_permission.add(permission[i]);
                }
            }
            //如果need_permission的大小大于0,说明需要有需要进行权限申请的,进行权限的申请
            if (need_permission.size() > 0){
                requestPermission(activity);
            }
        }
    }

    public void requestPermission(Activity activity){
        ActivityCompat.requestPermissions(activity,
                //将需要进行动态权限获取的need_permission列表变为字符串数组
                need_permission.toArray(new String[need_permission.size()]),REQUEST_CODE);
    }
}

 

Handle(主要用于监测线程的执行)

当线程执行的过程中,可以发送handle消息来通知主线程线程的完成进度

分支线程

class Detact_th extends Thread{
    String file_path;
    String file_name;
    Handler handler;
    AI_result ai_result;
    Detact_th(String file_path,String file_name,Handler handler,AI_result ai_result){
        this.file_path = file_path;
        this.file_name = file_name;
        this.handler = handler;
        this.ai_result = ai_result;
    }
    @Override
    public void run() {
        Tar_detact tar_detact = new Tar_detact(file_path,file_name);
        String result = tar_detact.run();
        ai_result.tar_detact_result = result;
//        System.out.println("最终结果为" + result);
        handler.sendEmptyMessage(0x15); //当此线程执行完毕的时候使用handle通知主线程当前线程已经执行完毕了
    }
}

handle部分的代码

class_pred.setEnabled(false);   //一开始将class_pred和tar_detact两个按钮给禁用,当Detach_th线程执行完毕之后,再重新启用这两个按钮
                tar_detact.setEnabled(false);
                Handler handler = new Handler(){   //定义handler
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        super.handleMessage(msg);
                        if (msg.what == 0x15){  //设置此handler的触发回传码,当线程执行完毕,handle回传的
                            //码与这里设置的相同的时候,将会执行以下的内容
                            System.out.println(ai_result.tar_detact_result);
                            pred_show.setText("检测结果为" + ai_result.tar_detact_result);
                            newadd_view = new Myview(Zqh_ai.this,sc_width,sc_height
                                    ,ai_result.tar_detact_result);
                            linearLayout.addView(newadd_view);
                            class_pred.setEnabled(true);
                            tar_detact.setEnabled(true);
                        }
                    }
                };

 

 

paint画笔

Paint pen = new Paint();
        pen.setARGB(200,255,123,233); //设置颜色(透明度,rgb)
//        pen.setColor(Color.BLUE); //可以通过color类别的常量来
//        pen.setAntiAlias(true);  //设置是否进行抗锯齿
//        pen.setDither(true); //抖动处理
//        pen.setShadowLayer((float) 0.2,3,3,Color.RED);  //设置阴影,阴影的角
        // 度,阴影在x轴和y轴上的偏移距离,颜色
//        pen.setStyle(Paint.Style.FILL); //设置填充风格,还有Paint.Style.FILL_AND_STROKE
//        pen.setTextAlign(Paint.Align.CENTER);  //设置文字的对齐方式,居中,还是左右
//        pen.setTextSize((float) 0.5);  //设置文字的大小
//        pen.setFakeBoldText(true);  //设置文字是否是粗体

 

自定义控件

onMeauser一定要在onLayout之前,再到onDraw。使用onMeasure来设置好大小,再进行布置,再进行绘制建造。

posted @ 2021-06-04 16:10  克莱比-Kirby  阅读(158)  评论(0)    收藏  举报