0

My goal is to add an overlay on the camera preview that will find book edges. For that, I override the onPreviewFrame where I do the following:

public void onPreviewFrame(byte[] data, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        int width = parameters.getPreviewSize().width;
        int height = parameters.getPreviewSize().height;
        Mat mat = new Mat((int) (height*1.5), width, CvType.CV_8UC1);
        mat.put(0,0,data);
        byte[] bytes = new byte[(int) (height*width*1.5)];
        mat.get(0,0,bytes);

        if (!test) {        //to only do once
            File pictureFile = getOutputMediaFile();
            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(bytes);
                fos.close();
                Uri picUri = Uri.fromFile(pictureFile);
                updateGallery(picUri);
                test = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

For now I simply want to take one of the previews and save it after the conversion to mat.

After spending countless hours getting the above to look right, the saved picture cannot be seen on my testing phone (LG Leon). I can't seem to find the issue. Am I mixing the height/width because I'm taking pictures in portrait mode? I tried switching them and still doesn't work. Where is the problem?

Dimebag
  • 833
  • 2
  • 9
  • 29

2 Answers2

0

The fastest method I managed to find is described HERE in my recently asked question. You can find the method to extract the image in the answer I wrote in my question below. The thing is that the image you get through onPreviewFrame() is NV21. After receiving this image it may be that you need to convert it to RGB (depends on what do you want to achieve; this is also done in the answer I gave you previously).

Community
  • 1
  • 1
Dainius Šaltenis
  • 1,644
  • 16
  • 29
  • Funny enough, one of my end goals is the same as yours: to display rectangles around text in real time. I'll try using your answer and see where it goes. thanks! – Dimebag Apr 28 '16 at 07:29
0

Seems quite inefficient but it works for me (for now):

//get the camera parameters
Camera.Parameters parameters = camera.getParameters();
int width = parameters.getPreviewSize().width;
int height = parameters.getPreviewSize().height;

//convert the byte[] to Bitmap through YuvImage; 
//make sure the previewFormat is NV21 (I set it so somewhere before)
YuvImage yuv = new YuvImage(data, parameters.getPreviewFormat(), width, height, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuv.compressToJpeg(new Rect(0, 0, width, height), 70, out);
Bitmap bmp = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());

//convert Bitmap to Mat; note the bitmap config ARGB_8888 conversion that 
//allows you to use other image processing methods and still save at the end
Mat orig = new Mat();
bmp = bmp.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(bmp, orig);

//here you do whatever you want with the Mat

//Mat to Bitmap to OutputStream to byte[] to File
Utils.matToBitmap(orig, bmp);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 70, stream);
byte[] bytes = stream.toByteArray();
File pictureFile = getOutputMediaFile();
try {
    FileOutputStream fos = new FileOutputStream(pictureFile);
    fos.write(bytes);
    fos.close();
} catch (IOException e) {
    e.printStackTrace();
}
Dimebag
  • 833
  • 2
  • 9
  • 29