Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/shapedetection/ShapeDetectionImpl.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/shapedetection/ShapeDetectionImpl.java b/content/public/android/java/src/org/chromium/content/browser/shapedetection/ShapeDetectionImpl.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ab0a8a2ca949b9b26deb71f3c9a5c3fa505bb01c |
| --- /dev/null |
| +++ b/content/public/android/java/src/org/chromium/content/browser/shapedetection/ShapeDetectionImpl.java |
| @@ -0,0 +1,97 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.content.browser.shapedetection; |
| + |
| +import android.content.Context; |
| +import android.graphics.Bitmap; |
| +import android.graphics.PointF; |
| +import android.media.FaceDetector; |
| +import android.media.FaceDetector.Face; |
| + |
| +import org.chromium.blink.mojom.FaceDetectionResult; |
| +import org.chromium.blink.mojom.ShapeDetection; |
| +import org.chromium.gfx.mojom.RectF; |
| +import org.chromium.mojo.system.MojoException; |
| +import org.chromium.mojo.system.SharedBufferHandle; |
| +import org.chromium.mojo.system.SharedBufferHandle.MapFlags; |
| +import org.chromium.services.shell.InterfaceFactory; |
| + |
| +import java.nio.ByteBuffer; |
| + |
| +/** |
| + * Android implementation of the shapedetection service defined in |
| + * third_party/WebKit/public/platform/modules/shapedetection/shapedetection.mojom |
| + * |
| + * TEST= |
| + * https://rawgit.com/Nadia-mint/chrome-demos/shapedetection/shapedetection.html |
|
mcasas
2016/10/11 02:51:18
This line should go in the CL description (below
t
xianglu
2016/10/11 20:25:50
Done.
|
| + */ |
| + |
| +public class ShapeDetectionImpl implements ShapeDetection { |
| + private static final String TAG = "ShapeDetectionImpl"; |
| + private static final int MAX_FACES = 10; |
| + |
| + public ShapeDetectionImpl(Context context) {} |
| + |
| + @Override |
| + public void detectFace( |
| + SharedBufferHandle frameData, int width, int height, DetectFaceResponse callback) { |
| + int numBytes = width * height * 4; |
|
mcasas
2016/10/11 02:51:18
nit: make this final, also in l.53, l. 58, 59, 61
xianglu
2016/10/11 20:25:50
Done.
|
| + ByteBuffer imageBuffer = frameData.map(0, numBytes, MapFlags.none()); |
| + |
| + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); |
| + bitmap.copyPixelsFromBuffer(imageBuffer); |
| + |
| + // Convert ARGB_8888 bitmap to array-backed RGB_565 bitmap. |
| + int[] pixels = new int[width * height]; |
| + bitmap.getPixels(pixels, 0, width, 0, 0, width, height); |
| + Bitmap bitmap2 = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.RGB_565); |
|
mcasas
2016/10/11 02:51:18
Ok, IIUC here we do two copies:
|imageBuffer| -->
xianglu
2016/10/11 20:25:50
I tried bitmap.setConfig(), but it seems FaceDetec
|
| + |
| + FaceDetector detector = new FaceDetector(width, height, MAX_FACES); |
| + Face[] detectedFaces = new Face[MAX_FACES]; |
| + int numberOfFaces = detector.findFaces(bitmap2, detectedFaces); |
| + |
| + FaceDetectionResult faceDetectionResult = new FaceDetectionResult(); |
| + faceDetectionResult.boundingBoxes = new RectF[numberOfFaces]; |
| + for (int i = 0; i < numberOfFaces; i++) { |
| + Face face = detectedFaces[i]; |
| + PointF midPoint = new PointF(); |
| + face.getMidPoint(midPoint); |
| + float eyesDistance = face.eyesDistance(); |
| + |
| + RectF boundingBox = new RectF(); |
| + boundingBox.x = midPoint.x - eyesDistance; |
| + boundingBox.y = midPoint.y - eyesDistance; |
| + boundingBox.width = 2 * eyesDistance; |
| + boundingBox.height = 2 * eyesDistance; |
| + |
| + faceDetectionResult.boundingBoxes[i] = boundingBox; |
|
mcasas
2016/10/11 02:51:18
Please add a TODO(xianglu) here with something
lik
xianglu
2016/10/11 20:25:50
Done.
|
| + } |
| + |
| + callback.call(faceDetectionResult); |
| + } |
| + |
| + @Override |
| + public void close() {} |
| + |
| + @Override |
| + public void onConnectionError(MojoException e) { |
| + close(); |
| + } |
| + |
| + /** |
| + * A factory method for registry in InterfaceRegistrarImpl.java. |
| + */ |
| + public static class Factory implements InterfaceFactory<ShapeDetection> { |
| + private Context mContext; |
| + public Factory(Context context) { |
| + mContext = context; |
| + } |
| + |
| + @Override |
| + public ShapeDetection createImpl() { |
| + return new ShapeDetectionImpl(mContext); |
|
mcasas
2016/10/11 02:51:18
I think we don't really need |context| here nor
in
xianglu
2016/10/11 20:25:50
Done.
|
| + } |
| + } |
| +} |