react-native-vision-camera icon indicating copy to clipboard operation
react-native-vision-camera copied to clipboard

Is there a simple way to save Frame to local file❓

Open moonofmars opened this issue 3 years ago • 2 comments

Question

In frameProcessor , is there a way to save Frame to local file❓

What I tried

No response

VisionCamera Version

2.14.1

Additional information

moonofmars avatar Aug 16 '22 09:08 moonofmars

only in JS or some community-plugin

moonofmars avatar Aug 16 '22 09:08 moonofmars

Same question. It would be very useful

Easy47 avatar Aug 22 '22 18:08 Easy47

I made a frame processor plugin for saving frame in local file. I can give you the source code if you want

Easy47 avatar Oct 26 '22 09:10 Easy47

I made a frame processor plugin for saving frame in local file. I can give you the source code if you want

would love to see it

TobyChow avatar Dec 20 '22 19:12 TobyChow

package com.mrousavy.camera.example;

import androidx.camera.core.ImageProxy;
import com.facebook.react.bridge.WritableNativeArray;
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.util.Log;
import androidx.camera.core.ImageProxy.PlaneProxy;
import com.facebook.react.bridge.WritableNativeMap;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.jetbrains.annotations.NotNull;

public class SaveFrameProcessorPlugin extends FrameProcessorPlugin {
  @Override
  public Object callback(ImageProxy image, Object[] params) {
      try {
        // Get path of image to load
        String path = params[0].toString();

        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 byteArrayOut = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 75, byteArrayOut);

        byte[] imageBytes = byteArrayOut.toByteArray();
        Bitmap bm = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);

        File file = new File(path);
        FileOutputStream out = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();
        System.out.println("Correctly saved");

        return image;

    } catch (Exception e) {
        System.out.println("CRASHED");
        e.printStackTrace();
    }
    return null;
  }

  public SaveFrameProcessorPlugin() {
    super("save_frame");
  }
}

Easy47 avatar Dec 20 '22 19:12 Easy47

Closing as this is a stale issue - this might have been fixed with the full rewrite in VisionCamera V3 (🥳) - if not, please create a new issue.

mrousavy avatar Sep 30 '23 09:09 mrousavy

And yea @Easy47's plugin looks good to me 👍

mrousavy avatar Sep 30 '23 09:09 mrousavy