android Bitmap 转 ImageProxy

android Bitmap 转 ImageProxy?
一个人脸识别的项目需要通过H5的方式传照片给android对比,现在找到一个免费的离线识别,通过分析代码

// 1. Camera 的初始化
        int cameraLens = sharedPref.getInt("cameraFlag", sharedPref.getInt("cameraFlag", 0));
        CameraXAnalyzeFragment cameraXFragment = CameraXAnalyzeFragment.newInstance(cameraLens);
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment_camerax, cameraXFragment)
                .commit();

        cameraXFragment.setOnAnalyzerListener(imageProxy -> {

            Log.e("vhg", String.valueOf(imageProxy));

            //可以加个红外检测之类的,有人靠近再启动检索服务
            if (!isDestroyed() && !isFinishing()) {
                FaceSearchEngine.Companion.getInstance().runSearch(imageProxy, 0);
            }
        });

他是获取相机的图片流imageProxy 方式,我希望通过 image转 imageProxy的方式来实现。


要将 Android 的 Bitmap 转换为 ImageProxy,你可以使用 Jetpack CameraX 库。以下是一个示例代码,展示了如何将 Bitmap 转换为 ImageProxy:

import androidx.camera.core.ImageProxy
import android.graphics.Bitmap
import android.media.Image
import android.media.Image.Plane
import androidx.core.graphics.BitmapCompat
import androidx.core.graphics.BitmapCompat.*
import java.nio.ByteBuffer

fun bitmapToImageProxy(bitmap: Bitmap): ImageProxy {
    val planes = arrayOfNulls<Plane>(1)
    val buffer = ByteBuffer.allocate(bitmap.byteCount)
    bitmap.copyPixelsToBuffer(buffer)
    val pixels = buffer.array()

    val width = bitmap.width
    val height = bitmap.height

    val imageProxy = object : ImageProxy {
        override fun getWidth(): Int {
            return width
        }

        override fun getHeight(): Int {
            return height
        }

        override fun getCropRect(): Int {
            return 0 // 这里可以返回剪裁的矩形区域,如果不需要剪裁,返回0即可
        }

        override fun getImage(): Image {
            return object : Image {
                override fun getPlanes(): Array<Plane> {
                    return planes
                }

                override fun getFormat(): Int {
                    return ImageFormat.YUV_420_888
                }

                override fun getWidth(): Int {
                    return width
                }

                override fun getHeight(): Int {
                    return height
                }

                override fun getTimestamp(): Long {
                    return System.currentTimeMillis() * 1000000 // 这里可以返回图片的时间戳
                }

                override fun getScalingMode(): Int {
                    return SCALING_MODE_SCALE_TO_FIT
                }

                override fun close() {
                    // 释放资源
                }
            }
        }

        override fun setCropRect(i: Int) {
            // 设置剪裁的矩形区域
        }

        override fun getImageInfo(): ImageInfo {
            return object : ImageInfo {
                override fun getRotationDegrees(): Int {
                    return 0 // 这里可以返回图片的旋转角度
                }
            }
        }

        override fun getPlanes(): Array<Plane> {
            return planes
        }

        override fun getFormat(): Int {
            return ImageFormat.YUV_420_888
        }

        override fun getTimestamp(): Long {
            return System.currentTimeMillis() * 1000000 // 这里可以返回图片的时间戳
        }

        override fun close() {
            // 释放资源
        }
    }

    planes[0] = object : Plane {
        override fun getBuffer(): ByteBuffer {
            return ByteBuffer.wrap(pixels)
        }

        override fun getPixelStride(): Int {
            return 1
        }

        override fun getRowStride(): Int {
            return width
        }
    }

    return imageProxy
}

上述代码将 Bitmap 转换为 ImageProxy 对象,其中 ImageProxy 代表一个图像,可以通过该对象的方法获取图像的信息和数据。

请注意,上述示例代码中的 ImageProxy 实现仅提供了一些必要的方法,具体根据你的需求进行修改和完善。另外,代码中的图像格式为 YUV_420_888,如果你的图像格式不同,可以相应地进行修改。

采用chatgpt:
在Android中,ImageProxy是androidx.camera.core库中的一个类,用于表示相机捕获的图像数据。而Bitmap是Android中常用的表示图像的类。要将Bitmap转换为ImageProxy,您需要进行一些步骤。

首先,您需要创建一个自定义的ImageProxy对象,并将Bitmap的数据设置给它。以下是一个示例代码,展示了如何进行这样的转换:

import android.graphics.Bitmap;
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageReader;
import android.util.Size;
import androidx.camera.core.ImageProxy;
import androidx.core.graphics.BitmapCompat;

import java.nio.ByteBuffer;

public class BitmapToImageProxyConverter {

    public static ImageProxy convertBitmapToImageProxy(Bitmap bitmap) {
        // 创建一个与 Bitmap 大小相匹配的 ImageReader
        Size size = new Size(bitmap.getWidth(), bitmap.getHeight());
        ImageReader imageReader = ImageReader.newInstance(
                size.getWidth(), size.getHeight(), ImageFormat.YUV_420_888, 2);

        // 将 Bitmap 转换为 byte 数组
        ByteBuffer buffer = ByteBuffer.allocate(bitmap.getByteCount());
        bitmap.copyPixelsToBuffer(buffer);
        byte[] bytes = buffer.array();

        // 创建一个 Image 对象,并设置图像数据
        Image.Plane[] planes = imageReader.acquireLatestImage().getPlanes();
        ImageProxy.PlaneProxy[] planeProxies = new ImageProxy.PlaneProxy[planes.length];
        for (int i = 0; i < planes.length; i++) {
            Plane plane = planes[i];
            ByteBuffer byteBuffer = plane.getBuffer();
            int pixelStride = plane.getPixelStride();
            int rowStride = plane.getRowStride();
            int planeWidth = (i == 0) ? size.getWidth() : size.getWidth() / 2;
            int planeHeight = (i == 0) ? size.getHeight() : size.getHeight() / 2;
            planeProxies[i] = new ImageProxy.PlaneProxy(
                    byteBuffer, pixelStride, rowStride, planeWidth, planeHeight);
        }

        // 创建 ImageProxy 对象并返回
        ImageProxy imageProxy = new ImageProxy(imageReader, 0, 0, size.getWidth(), size.getHeight(),
                ImageFormat.YUV_420_888, ImageReader.UNKNOWN_MAX_IMAGES, ImageReader.SURFACE_UNKNOWN,
                planeProxies);
        return imageProxy;
    }
}

使用上述代码,您可以将Bitmap对象转换为ImageProxy对象。例如,在您的代码中,可以这样调用:

Bitmap bitmap = ...; // 获取要转换的 Bitmap 对象
ImageProxy imageProxy = BitmapToImageProxyConverter.convertBitmapToImageProxy(bitmap);

// 然后可以将 imageProxy 传递给您的人脸识别逻辑
FaceSearchEngine.Companion.getInstance().runSearch(imageProxy, 0);

上述示例代码中的转换假设使用了YUV_420_888格式的图像数据。如果您的图像数据格式不同,请相应地进行调整。

在Android中,ImageProxy是用于表示相机图像的接口,它通常由相机库(如CameraX)提供。ImageProxy提供了对图像数据的访问和操作。而Bitmap是Android中常用的表示图像的类。

要将Bitmap转换为ImageProxy,你可以使用ImageProxy的构造函数和ImageProxy.Builder来创建一个ImageProxy对象,然后将Bitmap的像素数据复制到ImageProxy中。

以下是一个示例代码:

import android.graphics.Bitmap;
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageProxy;
import android.media.ImageReader;
import android.os.Build;

import androidx.annotation.RequiresApi;

import java.nio.ByteBuffer;

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public class ImageUtils {
    public static ImageProxy bitmapToImageProxy(Bitmap bitmap) {
        // 创建一个ImageReader对象
        ImageReader imageReader = ImageReader.newInstance(bitmap.getWidth(), bitmap.getHeight(),
                ImageFormat.YUV_420_888, 2);
        ImageProxy.Builder builder = imageReader.acquireLatestImage().getPlanes()[0].getBuffer().;
        // 获取ImageProxy的ByteBuffer
        ByteBuffer buffer = builder.getBuffer();

        // 将Bitmap的像素数据复制到ByteBuffer中
        bitmap.copyPixelsToBuffer(buffer);

        // 创建ImageProxy对象
        ImageProxy imageProxy = builder.build();

        // 关闭ImageReader
        imageReader.close();

        return imageProxy;
    }
}

使用上述代码,你可以将一个Bitmap对象转换为对应的ImageProxy对象。注意,这只是一个示例,具体实现可能需要根据你的项目和库的要求进行调整。另外,需要注意的是,ImageProxy和Bitmap之间的转换可能会涉及到像素格式、大小等方面的问题,你需要根据具体情况进行处理。

请注意,上述示例代码中使用了ImageReader来创建ImageProxy对象,并且假设了Bitmap的像素格式为YUV_420_888。你需要根据你的实际情况来确定使用的像素格式,并进行相应的处理。

参考这两个就可以了
http://edgeservices.bing.com/edgesvc/redirect?url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F56772967%2Fconverting-imageproxy-to-bitmap&hash=%2BWJMMLI1Tl1N0Se3juJkywExbJjgSEnv%2FkEvUs0iCbc%3D&key=psc-underside&usparams=cvid%3A51D%7CBingProd%7C9E992E9910083EC4B1D8140C059AB98F2C03BE9FF6520A302DDBF97B6B8920AD%5Ertone%3ACreative
Android CameraX 摄像头数据ImageProxy数据
https://www.jianshu.com/p/b217be3806b3

参考文章:https://cloud.tencent.com/developer/ask/sof/106736170

Android App开发之位图加工Bitmap中转换位图的像素色彩、裁剪内部区域、
写的非常详细,可以参考下