Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Take picture with drawable/paint on face using vision api

What I am trying?

I am trying to take picture with drawable/paint on face but, i am not able to get both on same picture.

enter image description here

What I have tried?

I have tried using CameraSource.takePicture but i am just getting face without any drawable/paint on it.

mCameraSource.takePicture(shutterCallback, new CameraSource.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] bytes) {
                try {
                    String mainpath = getExternalStorageDirectory() + separator + "TestXyz" + separator + "images" + separator;
                    File basePath = new File(mainpath);
                    if (!basePath.exists())
                        Log.d("CAPTURE_BASE_PATH", basePath.mkdirs() ? "Success": "Failed");
                    String path = mainpath + "photo_" + getPhotoTime() + ".jpg";
                    File captureFile = new File(path);
                    captureFile.createNewFile();
                    if (!captureFile.exists())
                        Log.d("CAPTURE_FILE_PATH", captureFile.createNewFile() ? "Success": "Failed");
                    FileOutputStream stream = new FileOutputStream(captureFile);
                    stream.write(bytes);
                    stream.flush();
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

I also tried using :

mPreview.setDrawingCacheEnabled(true);
        Bitmap drawingCache = mPreview.getDrawingCache();
        try {
            String mainpath = getExternalStorageDirectory() + separator + "TestXyz" + separator + "images" + separator;
            File basePath = new File(mainpath);
            if (!basePath.exists())
                Log.d("CAPTURE_BASE_PATH", basePath.mkdirs() ? "Success": "Failed");
            String path = mainpath + "photo_" + getPhotoTime() + ".jpg";
            File captureFile = new File(path);
            captureFile.createNewFile();
            if (!captureFile.exists())
                Log.d("CAPTURE_FILE_PATH", captureFile.createNewFile() ? "Success": "Failed");
            FileOutputStream stream = new FileOutputStream(captureFile);
            drawingCache.compress(Bitmap.CompressFormat.PNG, 100, stream);
            stream.flush();
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

in this case i am only getting what i draw on face. Here, mPreview is the CameraSourcePreview.

Just added capture button and added above code in this google example.

like image 873
SANAT Avatar asked Jul 31 '17 05:07

SANAT


Video Answer


1 Answers

You are very close to achieve what you need :)

You have:

  1. An image from the Camera of the face (First code snippet)
  2. An image from the Canvas of the eyes overlay (Second code snippet)

What you need:

  • An image that has the face with the eyes overlay on top - A merged image.

How to merge?

To merge 2 images simply use a canvas, like so:

public Bitmap mergeBitmaps(Bitmap face, Bitmap overlay) {
    // Create a new image with target size
    int width = face.getWidth();
    int height = face.getHeight();
    Bitmap newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    Rect faceRect = new Rect(0,0,width,height);
    Rect overlayRect = new Rect(0,0,overlay.getWidth(),overlay.getHeight());

    // Draw face and then overlay (Make sure rects are as needed)
    Canvas canvas = new Canvas(newBitmap); 
    canvas.drawBitmap(face, faceRect, faceRect, null);
    canvas.drawBitmap(overlay, overlayRect, faceRect, null);
    return newBitmap
}

Then you can save the new image, as you are doing now.

Full code would look like:

mCameraSource.takePicture(shutterCallback, new 
CameraSource.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] bytes) {
            // Generate the Face Bitmap
            BitmapFactory.Options options = new BitmapFactory.Options();
            Bitmap face = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);

            // Generate the Eyes Overlay Bitmap
            mPreview.setDrawingCacheEnabled(true);
            Bitmap overlay = mPreview.getDrawingCache();

            // Generate the final merged image
            Bitmap result = mergeBitmaps(face, overlay);

            // Save result image to file
            try {
                String mainpath = getExternalStorageDirectory() + separator + "TestXyz" + separator + "images" + separator;
                File basePath = new File(mainpath);
                if (!basePath.exists())
                    Log.d("CAPTURE_BASE_PATH", basePath.mkdirs() ? "Success": "Failed");
                String path = mainpath + "photo_" + getPhotoTime() + ".jpg";
                File captureFile = new File(path);
                captureFile.createNewFile();
                if (!captureFile.exists())
                    Log.d("CAPTURE_FILE_PATH", captureFile.createNewFile() ? "Success": "Failed");
                FileOutputStream stream = new FileOutputStream(captureFile);
                result.compress(Bitmap.CompressFormat.PNG, 100, stream);
                stream.flush();
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

Note that the above is just an example code. You should probably move the merging and saving to a file to a background thread.

like image 126
Eyal Biran Avatar answered Oct 21 '22 15:10

Eyal Biran