whycxzp
2024-07-19 f282ccfb392a5b5a019cd4c4133cf3310e142a63
更新
1个文件已修改
1个文件已添加
214 ■■■■ 已修改文件
app/src/main/java/com/whyc/util/BitmapUtil.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/whyc/widget/Camera2TextureView2.java 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/whyc/util/BitmapUtil.java
New file
@@ -0,0 +1,118 @@
package com.whyc.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.Locale;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
//import android.support.media.ExifInterface;
import android.media.ExifInterface;
import android.os.Environment;
public class BitmapUtil {
    // 把位图对象保存为指定路径的图片文件
    public static void saveBitmap(String path, Bitmap bitmap, String format, int quality) {
        Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;
        if (format.toUpperCase(Locale.getDefault()).equals("PNG")) {
            compressFormat = Bitmap.CompressFormat.PNG;
        }
        try {
            // 根据指定文件路径构建缓存输出流对象
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path));
            // 把位图数据压缩到缓存输出流中
            bitmap.compress(compressFormat, quality, bos);
            // 完成缓存输出流的写入动作
            bos.flush();
            // 关闭缓存输出流
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 把位图数据保存到指定路径的图片文件
    public static void saveBitmap(String path, ByteBuffer buffer,
                                  int sample_size, String format, int quality) {
        try {
            byte[] buff = new byte[buffer.remaining()];
            buffer.get(buff);
            BitmapFactory.Options ontain = new BitmapFactory.Options();
            ontain.inSampleSize = sample_size;
            Bitmap bitmap = BitmapFactory.decodeByteArray(buff, 0, buff.length, ontain);
            saveBitmap(path, bitmap, format, quality);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 从指定路径的图片文件中读取位图数据
    public static Bitmap openBitmap(String path) {
        Bitmap bitmap = null;
        try {
            // 根据指定文件路径构建缓存输入流对象
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
            // 从缓存输入流中解码位图数据
            bitmap = BitmapFactory.decodeStream(bis);
            // 关闭缓存输入流
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 返回图片文件中的位图数据
        return bitmap;
    }
    // 获得旋转角度之后的位图对象
    public static Bitmap getRotateBitmap(Bitmap b, float rotateDegree) {
        // 创建操作图片用的矩阵对象
        Matrix matrix = new Matrix();
        // 执行图片的旋转动作
        matrix.postRotate(rotateDegree);
        // 创建并返回旋转后的位图对象
        return Bitmap.createBitmap(b, 0, 0, b.getWidth(),
                b.getHeight(), matrix, false);
    }
    // 获得图片的缓存路径
    public static String getCachePath(Context context) {
        return context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/";
    }
    // 按照新的宽高缩放位图对象
    public static Bitmap zoomImage(Bitmap origImage, double newWidth, double newHeight) {
        // 获取原始位图的宽度
        float width = origImage.getWidth();
        // 获取原始位图的高度
        float height = origImage.getHeight();
        // 创建操作图片用的矩阵对象
        Matrix matrix = new Matrix();
        // 计算宽度的缩放率
        float scaleWidth = ((float) newWidth) / width;
        // 计算高度的缩放率
        float scaleHeight = ((float) newHeight) / height;
        // 执行图片的缩放动作
        matrix.postScale(scaleWidth, scaleHeight);
        // 创建并返回缩放后的位图对象
        return Bitmap.createBitmap(origImage, 0, 0, (int) width, (int) height, matrix, true);
    }
    // 将图片的旋转角度置为0,此方法可以解决某些机型拍照后,图像出现了旋转情况
    public static void setPictureDegreeZero(String path) {
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            // 修正图片的旋转角度,设置其不旋转。这里也可以设置其旋转的角度,可以传值过去,
            // 例如旋转90度,传值ExifInterface.ORIENTATION_ROTATE_90,需要将这个值转换为String类型的
            exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, "no");
            exifInterface.saveAttributes();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
app/src/main/java/com/whyc/widget/Camera2TextureView2.java
@@ -4,13 +4,16 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaRecorder;
@@ -23,16 +26,13 @@
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Range;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.whyc.util.HttpRequestUtil;
import com.whyc.util.tool.HttpReqData;
import com.whyc.util.tool.HttpRespData;
import java.io.File;
import java.io.FileOutputStream;
@@ -64,6 +64,7 @@
    private Handler mainHandler = new Handler(Looper.getMainLooper());
    private HandlerThread mThreadHandler;
    ScheduledExecutorService executorService;
    ScheduledExecutorService scheduledExecutorService;
    //主页面的视图
    private LinearLayout llUpText;
@@ -74,6 +75,7 @@
    private int imageWeight = 1920;
    private int imageHeight = 1080;
    Range<Integer> rangeMin;
    public Camera2TextureView2(Context context) {
        super(context,null);
@@ -81,7 +83,7 @@
    public Camera2TextureView2(Context context, AttributeSet attrs) {
        super(context, attrs);
        executorService = Executors.newScheduledThreadPool(2);
        executorService = Executors.newScheduledThreadPool(4);
        /*String url = "http://192.168.10.79:8919/fg/server/timestamp";
        executorService.execute(()-> {
                HttpReqData httpReqData = new HttpReqData(url);
@@ -127,6 +129,10 @@
        CameraManager cm = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
        try {
            String cameraId = cm.getCameraIdList()[0];
            CameraCharacteristics cameraCharacteristics = cm.getCameraCharacteristics(cameraId);
            StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            Range<Integer>[] availableFpsRanges = cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
            rangeMin = availableFpsRanges[0];
            cm.openCamera(cameraId,mDeviceStateCallback,null);
        }catch (Exception e){
            e.printStackTrace();
@@ -184,7 +190,10 @@
            captureBuilder.addTarget(previewSurface);
            /*设置预览的界面*/
            //设置自动对焦模式
            //设置帧率
            captureBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
                    rangeMin);
            /*//设置自动对焦模式
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_AUTO);
            // 设置自动曝光模式
@@ -192,7 +201,7 @@
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            // 开始对焦
            captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_START);
                    CameraMetadata.CONTROL_AF_TRIGGER_START);*/
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,  90);
            mCaptureSession.setRepeatingRequest(captureBuilder.build(), null, mHandler);
@@ -240,7 +249,7 @@
    }
    public void createRecorderSession(){
        //关闭预览,启动录像相关
        //关闭预览请求,启动录像相关
        try {
            mCaptureSession.stopRepeating();
        }catch (Exception e){
@@ -256,6 +265,7 @@
        initRecorder();
        try{
            mMediaRecorder.prepare();
            mMediaRecorder.start();
        }catch (Exception e){
            e.printStackTrace();
        }
@@ -270,19 +280,17 @@
                        recordRequest = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
                        recordRequest.addTarget(previewSurface);
//                        recordRequest.addTarget(mImageReader.getSurface());
                        recordRequest.addTarget(mMediaRecorder.getSurface());
                        mCaptureSession.setRepeatingRequest(recordRequest.build(), null, mHandler); // 开始录制视频
                        mMediaRecorder.start();
                        //camera2 捕捉视频快照,1秒钟1次的定时任务
                        CaptureRequest.Builder snapshotBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
                        snapshotBuilder.addTarget(surfaceForStream);
                        executorService.scheduleAtFixedRate(() -> {
                        scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
                        scheduledExecutorService.scheduleAtFixedRate(() -> {
                            try {
                                session.capture(snapshotBuilder.build(), null, mHandler);
                                session.capture(snapshotBuilder.build(), null, null);
                            }catch (Exception e){
                                e.printStackTrace();
                            }
@@ -334,32 +342,33 @@
            Image image = reader.acquireNextImage();
            image.close();
        }*/
        // 获取到拍照的图像数据
        Image image = reader.acquireNextImage();
        //这里只是演示test
        llUpText.setVisibility(View.VISIBLE);
        tvDevice.setText("这是测试的动态赋值");
        // 获取图片的字节数组
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        // 保存图片到相册
        saveImageToGallery(data);
        // 释放图像资源
        image.close();
            // 获取到拍照的图像数据
            Image image = reader.acquireNextImage();
            //这里只是演示test
            llUpText.setVisibility(View.VISIBLE);
            tvDevice.setText("这是测试的动态赋值");
            // 保存图片到相册
            executorService.execute(() -> {
                saveImageToGallery(image);
            });
    };
    private void saveImageToGallery(byte[] data) {
    private void saveImageToGallery(Image image) {
        // 定义图片的保存路径和文件名
        String fileName = "IMG_" + System.currentTimeMillis() + ".jpg";
        String filePath = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath()  + "/yc_test"+ File.separator + fileName;
        // 获取图片的字节数组
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        // 创建文件输出流
        try {
            FileOutputStream fos = new FileOutputStream(filePath);
            fos.write(data);
            fos.close();
            image.close();
            // 通知图库更新
            MediaScannerConnection.scanFile(mContext, new String[]{filePath}, null, null);
@@ -376,32 +385,29 @@
    }
    public void stopRecording() {
       //这里只是演示test
        llUpText.setVisibility(View.GONE);
        //停止画面图片监听
        mImageReader.close();
        // 停止录制视频
        try {
            executorService.shutdownNow();
            // 停止录制视频,关闭录像请求
            mMediaRecorder.stop();
            //关闭定时视频快照
            scheduledExecutorService.shutdownNow();
            mCaptureSession.stopRepeating();
            //停止画面图片监听
            mImageReader.close();
           //这里只是演示test
            llUpText.setVisibility(View.GONE);
            //启动预览
            createPreviewSession();
        } catch (IllegalStateException e) {
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//            mMediaRecorder.reset();
            mMediaRecorder.reset();
//            mMediaRecorder.release();
//            mMediaRecorder = null;
            //图库更新
            addToGallery(recorderPath);
            isRecording = false;
        }
        isRecording = false;
        // 关闭相机预览会话
        //        if (captureSession != null) {
        //            captureSession.close();
        //            captureSession = null;
        //        }
        //图库更新
        addToGallery(recorderPath);
    }
    private void addToGallery(String videoFilePath) {