ImageReader保存图片转 opencvmat

目录

[ImageReader 直接保存图片,没成功,格式是yuv420,需要转换](#ImageReader 直接保存图片,没成功,格式是yuv420,需要转换)

转opencv

nv21保存图片,测试ok

[rgb888 data保存图片:](#rgb888 data保存图片:)


ImageReader 直接保存图片,没成功,格式是yuv420,需要转换

java 复制代码
// 创建一个ImageReader对象
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);

reader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader reader) {
        Image image = null;
        try {
            image = reader.acquireLatestImage();
            if (image != null) {
                ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                byte[] bytes = new byte[buffer.capacity()];
                buffer.get(bytes);
                saveImage(bytes);
            }
        } finally {
            if (image != null) {
                image.close();
            }
        }
    }
}, handler);

// 保存图片
private void saveImage(byte[] bytes) {
    File file = new File(Environment.getExternalStorageDirectory() + "/picture.jpg");
    FileOutputStream output = null;
    try {
        output = new FileOutputStream(file);
        output.write(bytes);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (null != output) {
            try {
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

转opencv

java 复制代码
Image image = imageReader.acquireLatestImage();
Plane[] planes = image.getPlanes();
ByteBuffer bufferY = planes[0].getBuffer();
ByteBuffer bufferU = planes[1].getBuffer();
ByteBuffer bufferV = planes[2].getBuffer();
byte[] bytesY = new byte[bufferY.remaining()];
byte[] bytesU = new byte[bufferU.remaining()];
byte[] bytesV = new byte[bufferV.remaining()];
bufferY.get(bytesY);
bufferU.get(bytesU);
bufferV.get(bytesV);

c++部分:

cpp 复制代码
cv::Mat imgY(height, width, CV_8UC1, bytesY);
cv::Mat imgU(height, width, CV_8UC1, bytesU);
cv::Mat imgV(height, width, CV_8UC1, bytesV);

c++部分:

cpp 复制代码
cv::Mat imgYUV;
cv::merge(std::vector<cv::Mat>{imgY, imgU, imgV}, imgYUV);
cv::Mat imgRGB;
cv::cvtColor(imgYUV, imgRGB, cv::COLOR_YUV2RGB);

nv21保存图片,测试ok

java 复制代码
     Yuv2Rgb.nativeNV21ToARGB8888(nv21, data, width[0], height[0]);
                        long t2 = System.currentTimeMillis();

                        // 假设你已经有了一个ARGB_8888格式的图像,存储在一个名为pixels的int数组中
                        int width = 1920;
                        int height = 1080;

                        String file_name="/storage/emulated/0/Android/data/com.sandstar.jupiter.terminal.algor/files/"+mCameraId+"/"+frameIdx+"_b.jpg";
                        YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, width, height, null);

                        try {
                        // 创建一个输出流来保存图片
                        FileOutputStream outStream = new FileOutputStream(file_name);

                        // 将YuvImage转换为JPEG,并保存到输出流中
                        yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, outStream);

                        // 关闭输出流
                        outStream.close();
                         } catch (IOException e) {
                            e.printStackTrace();
                        }

rgb888 data保存图片:

java 复制代码
Yuv2Rgb.nativeNV21ToARGB8888(nv21, data, width[0], height[0]); 

// Create a Bitmap from the ARGB8888 data
Bitmap bitmap = Bitmap.createBitmap(data, width[0], height[0], Bitmap.Config.ARGB_8888);

// Save the Bitmap as a JPEG file
FileOutputStream fos = null;
try {
    fos = new FileOutputStream("/path/to/your/file.jpg");
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (fos != null) {
            fos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
相关推荐
京师20万禁军教头1 分钟前
36面向对象(高级)-类变量(静态变量)和类方法(静态方法)
java
deviant-ART2 分钟前
HttpServletResponse 中 Header 与 OutputStream 的正确使用顺序(避坑指南)
java·后端·servlet
JAVA面经实录9175 分钟前
Spring AI 高频开发万能 Prompt 合集 + 生产级工具类
java·人工智能·spring·prompt
非科班Java出身GISer9 分钟前
ArcGIS Maps SDK for JavaScript 5.0 组件化开发指南
javascript·arcgis·components·arcgis js 组件化·arcgis js5.0·arcgis js5.0初始化
张风捷特烈9 分钟前
状态管理大乱斗#05 | Riverpod 源码评析 (中) - 上层建筑
android·前端·flutter
土豆125011 分钟前
Rust 生命周期开发实战:从"编译不过"到"一次过编"的实用指南
前端·rust
JAVA面经实录91712 分钟前
如何选择适合项目的「限流 / 熔断 / 降级」方案
java·spring·kafka·sentinel·guava
小雅痞2 小时前
[Java][Leetcode middle] 167. 两数之和 II - 输入有序数组
java·算法·leetcode
CN-Dust2 小时前
【C++】输入cin例题专题
java·c++·算法