pythonjavaandroidimage-processingandroid-camerax

Android ImageProxy to byteArray and send over socket


I'm trying to convert ImageProxy to byteArray to send it over socket to a python server. I'm using Camerax and this is my ImageAnalysis:

mageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                        .setTargetResolution(new Size(720, 640))
                        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
//                        .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888) // uncomment if it solves the problem easier
                        .build();
 
                 imageAnalysis.setAnalyzer(executor, image -> {

                    byte[] imageBytes = imageProxyToByteArray(image);
                    if (imageBytes != null && imageBytes.length > 0) {
                        try (Socket socket = new Socket("192.168.143.234", 65432)) {
                            OutputStream outputStream = socket.getOutputStream();
                            outputStream.write("<start>".getBytes());
                            outputStream.write(imageBytes);
                            outputStream.write("<end>".getBytes());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    image.close();
                });

and

private byte[] imageProxyToByteArray(ImageProxy image) {
        ImageProxy.PlaneProxy[] planes = image.getPlanes();
        ByteBuffer yBuffer = planes[0].getBuffer();
        ByteBuffer uBuffer = planes[1].getBuffer();
        ByteBuffer vBuffer = planes[2].getBuffer();

        int ySize = yBuffer.remaining();
        int uSize = uBuffer.remaining();
        int vSize = vBuffer.remaining();

        byte[] nv21 = new byte[ySize + uSize + vSize];

        yBuffer.get(nv21, 0, ySize);
        vBuffer.get(nv21, ySize, vSize);
        uBuffer.get(nv21, ySize + vSize, uSize);

        YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, image.getWidth(), image.getHeight(), null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 100, out);
        return out.toByteArray();
    }

I used the above codes in java for android device and this is python code:

img_array = ... #comes from socket and im sure it is started with <start> and end with <end> 
img_array = np.frombuffer(img_array, dtype=np.uint8)
image = cv2.imdecode(img_array, cv2.IMREAD_UNCHANGED)
cv2.imwrite('received_image.jpg', image)

but the result is not a valid image:not a valid image

please help me to solve this problem:(


Solution

  • try this one:

     public byte[] imageProxyToByteArray(ImageProxy imageProxy) {
        Bitmap bitmap = imageProxy.toBitmap();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
        return outputStream.toByteArray();
    }
    

    replace this function with your function.