Home | History | Annotate | Download | only in simplecamera
      1 /*
      2  * Copyright 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 // Takes in an array, returns the size of the array
     17 
     18 package androidx.media.filterfw.samples.simplecamera;
     19 
     20 import android.graphics.Rect;
     21 import android.hardware.Camera;
     22 import android.hardware.Camera.Face;
     23 import android.util.Log;
     24 import androidx.media.filterfw.Filter;
     25 import androidx.media.filterfw.Frame;
     26 import androidx.media.filterfw.FrameImage2D;
     27 import androidx.media.filterfw.FrameType;
     28 import androidx.media.filterfw.FrameValues;
     29 import androidx.media.filterfw.MffContext;
     30 import androidx.media.filterfw.OutputPort;
     31 import androidx.media.filterfw.Signature;
     32 
     33 import java.nio.ByteBuffer;
     34 
     35 public class FaceSquareFilter extends Filter {
     36 
     37     private static final String TAG = "FaceSquareFilter";
     38     private static boolean mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE);
     39 
     40     private static int FACE_X_RANGE = 2000;
     41     private static int WIDTH_OFFSET = 1000;
     42     private static int HEIGHT_OFFSET = 1000;
     43 
     44     public FaceSquareFilter(MffContext context, String name) {
     45         super(context, name);
     46     }
     47 
     48     @Override
     49     public Signature getSignature() {
     50         FrameType imageType = FrameType.buffer2D(FrameType.ELEMENT_RGBA8888);
     51         FrameType facesType = FrameType.array(Camera.Face.class);
     52         return new Signature()
     53                 .addInputPort("image", Signature.PORT_REQUIRED, imageType)
     54                 .addInputPort("faces", Signature.PORT_REQUIRED, facesType)
     55                 .addOutputPort("image", Signature.PORT_REQUIRED, imageType)
     56                 .disallowOtherPorts();
     57     }
     58 
     59     /**
     60      * @see androidx.media.filterfw.Filter#onProcess()
     61      */
     62     @Override
     63     protected void onProcess() {
     64         // Get inputs
     65         FrameImage2D imageFrame = getConnectedInputPort("image").pullFrame().asFrameImage2D();
     66         FrameValues facesFrame = getConnectedInputPort("faces").pullFrame().asFrameValues();
     67         Face[] faces = (Face[]) facesFrame.getValues();
     68         int[] dims = imageFrame.getDimensions();
     69         ByteBuffer buffer = imageFrame.lockBytes(Frame.MODE_WRITE);
     70         byte[] pixels = buffer.array();
     71 
     72         // For every face in faces, draw a white rect around the
     73         // face following the rect member of the Face
     74         drawBoxes(pixels, faces, dims);
     75 
     76         imageFrame.unlock();
     77 
     78         OutputPort outPort = getConnectedOutputPort("image");
     79         outPort.pushFrame(imageFrame);
     80     }
     81 
     82     public void drawBoxes(byte[] pixels, Face[] faces, int[] dims) {
     83         for(int i = 0; i < faces.length; i++) {
     84             Rect tempRect = faces[i].rect;
     85             int top = (tempRect.top+HEIGHT_OFFSET)*dims[1]/FACE_X_RANGE;
     86             int bottom = (tempRect.bottom+HEIGHT_OFFSET)*dims[1]/FACE_X_RANGE;
     87             int left = (tempRect.left+WIDTH_OFFSET)*dims[0]/FACE_X_RANGE;
     88             int right = (tempRect.right+WIDTH_OFFSET)*dims[0]/FACE_X_RANGE;
     89 
     90             if (top < 0) {
     91                 top = 0;
     92             } else if (top > dims[1]) {
     93                 top = dims[1];
     94             }
     95             if (left < 0) {
     96                 left = 0;
     97             } else if (left > dims[0]) {
     98                 left = dims[0];
     99             }
    100             if (bottom > dims[1]) {
    101                 bottom = dims[1];
    102             } else if (bottom < 0) {
    103                 bottom = 0;
    104             }
    105             if (right > dims[0]) {
    106                 right = dims[0];
    107             } else if (right < 0) {
    108                 right = 0;
    109             }
    110 
    111             for (int j = 0; j < (bottom - top); j++) {
    112                 // Left edge
    113                 if (left > 0 && top > 0) {
    114                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + left) +
    115                            ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    116                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + left) +
    117                            ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    118                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + left) +
    119                            ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    120                 }
    121 
    122                 // Right edge
    123                 if (right > 0 && top > 0) {
    124                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + right) +
    125                            ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    126                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + right) +
    127                            ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    128                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + right) +
    129                            ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    130                 }
    131 
    132             }
    133             for (int k = 0; k < (right - left); k++) {
    134                 // Top edge
    135                 if (top < dims[1]) {
    136                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * top + left + k) +
    137                            ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    138                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * top + left + k) +
    139                            ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    140                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * top + left + k) +
    141                            ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    142 
    143                 }
    144                 // Bottom edge
    145                 if (bottom < dims[1]) {
    146                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * bottom + left + k) +
    147                            ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    148                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * bottom + left + k) +
    149                            ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    150                     pixels[ImageConstants.PIX_CHANNELS * (dims[0] * bottom + left + k) +
    151                            ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
    152                 }
    153 
    154 
    155             }
    156 
    157         }
    158     }
    159 }
    160