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来设置好大小,再进行布置,再进行绘制建造。

浙公网安备 33010602011771号