Android studio 既想拍照又想拿到Bitmap
!!安卓千万不要用YUV,不要想着去YUV转RGB,转出来会有乱码
package com.nio.rpcsample;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraManager;
import android.util.Base64;
import android.util.Log;
import android.media.Image;
import java.nio.ByteBuffer;
// 其他 import 保持不变import androidx.annotation.NonNull;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.ImageProxy;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;import com.google.common.util.concurrent.ListenableFuture;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;import java.util.List;
import java.util.ArrayList;
import androidx.camera.core.CameraInfo;
import androidx.camera.camera2.interop.Camera2CameraInfo;public class TakePicture {private final Context context;private final Executor executor;private ImageCapture imageCapture;private CameraManager cameraManager;public TakePicture(Context context, Executor executor) {this.context = context;this.executor = executor;}public void initCamera(String cameraId) {ListenableFuture<ProcessCameraProvider> cameraProviderFuture =ProcessCameraProvider.getInstance(context);cameraProviderFuture.addListener(() -> {try {ProcessCameraProvider cameraProvider = cameraProviderFuture.get();cameraProvider.unbindAll();CameraSelector selector = new CameraSelector.Builder().addCameraFilter(cameras -> {List<CameraInfo> matched = new ArrayList<>();for (CameraInfo info : cameras) {String id = Camera2CameraInfo.from(info).getCameraId();Log.e("CameraInfo", id);if (id.equals(cameraId)) matched.add(info);}return matched;}).build();// 这个接口千万不要设置YUV888,就采用默认的JPEG格式,这样即直接落盘,不需要做数据转换,又可以直接采用imageproxy直接使用(避免重复IO)imageCapture = new ImageCapture.Builder().setTargetResolution(new android.util.Size(2816, 568)).build(); //// 这里只绑定拍照用例cameraProvider.bindToLifecycle((androidx.lifecycle.LifecycleOwner) context,selector,imageCapture);} catch (ExecutionException | InterruptedException e) {e.printStackTrace();}}, ContextCompat.getMainExecutor(context));}public void takePicture(int index, String batch, OnImageProcessedListener listener) {if (imageCapture == null) {Log.e("takePicture", "Camera not initialized");return;}imageCapture.takePicture(executor, new ImageCapture.OnImageCapturedCallback() {@Overridepublic void onCaptureSuccess(@NonNull ImageProxy image) {// 1️⃣ 获取 JPEG byte[]Image img = image.getImage();if (img != null && img.getFormat() == ImageFormat.JPEG) {ByteBuffer buffer = img.getPlanes()[0].getBuffer();byte[] bytes = new byte[buffer.remaining()];buffer.get(bytes);// 2️⃣ BitmapBitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);// 3️⃣ 保存文件File photoFile = new File(context.getCacheDir(),"huang_" + System.currentTimeMillis() + ".jpg");try (FileOutputStream fos = new FileOutputStream(photoFile)) {fos.write(bytes);fos.flush();} catch (IOException e) {Log.e("TakePicture", "Failed to save bitmap", e);}}image.close();}@Overridepublic void onError(@NonNull ImageCaptureException exception) {Log.e("TakePicture", "Image capture failed", exception);}});}
}