1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/* 2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright 2013 The Android Open Source Project 3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); 5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License. 6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at 7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0 9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software 11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS, 12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and 14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License. 15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks// Takes in an array, returns the size of the array 17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw.samples.simplecamera; 19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.graphics.Rect; 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.hardware.Camera; 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.hardware.Camera.Face; 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.util.Log; 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.Filter; 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.Frame; 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.FrameImage2D; 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.FrameType; 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.FrameValues; 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.MffContext; 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.OutputPort; 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.Signature; 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.nio.ByteBuffer; 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic class FaceSquareFilter extends Filter { 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final String TAG = "FaceSquareFilter"; 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static boolean mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int FACE_X_RANGE = 2000; 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int WIDTH_OFFSET = 1000; 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int HEIGHT_OFFSET = 1000; 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public FaceSquareFilter(MffContext context, String name) { 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks super(context, name); 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public Signature getSignature() { 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameType imageType = FrameType.buffer2D(FrameType.ELEMENT_RGBA8888); 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameType facesType = FrameType.array(Camera.Face.class); 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return new Signature() 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks .addInputPort("image", Signature.PORT_REQUIRED, imageType) 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks .addInputPort("faces", Signature.PORT_REQUIRED, facesType) 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks .addOutputPort("image", Signature.PORT_REQUIRED, imageType) 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks .disallowOtherPorts(); 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * @see androidx.media.filterfw.Filter#onProcess() 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks protected void onProcess() { 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Get inputs 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameImage2D imageFrame = getConnectedInputPort("image").pullFrame().asFrameImage2D(); 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks FrameValues facesFrame = getConnectedInputPort("faces").pullFrame().asFrameValues(); 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Face[] faces = (Face[]) facesFrame.getValues(); 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] dims = imageFrame.getDimensions(); 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ByteBuffer buffer = imageFrame.lockBytes(Frame.MODE_WRITE); 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks byte[] pixels = buffer.array(); 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // For every face in faces, draw a white rect around the 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // face following the rect member of the Face 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks drawBoxes(pixels, faces, dims); 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks imageFrame.unlock(); 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks OutputPort outPort = getConnectedOutputPort("image"); 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks outPort.pushFrame(imageFrame); 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void drawBoxes(byte[] pixels, Face[] faces, int[] dims) { 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for(int i = 0; i < faces.length; i++) { 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Rect tempRect = faces[i].rect; 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int top = (tempRect.top+HEIGHT_OFFSET)*dims[1]/FACE_X_RANGE; 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int bottom = (tempRect.bottom+HEIGHT_OFFSET)*dims[1]/FACE_X_RANGE; 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int left = (tempRect.left+WIDTH_OFFSET)*dims[0]/FACE_X_RANGE; 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int right = (tempRect.right+WIDTH_OFFSET)*dims[0]/FACE_X_RANGE; 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (top < 0) { 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks top = 0; 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (top > dims[1]) { 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks top = dims[1]; 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (left < 0) { 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks left = 0; 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (left > dims[0]) { 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks left = dims[0]; 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (bottom > dims[1]) { 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks bottom = dims[1]; 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (bottom < 0) { 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks bottom = 0; 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (right > dims[0]) { 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks right = dims[0]; 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (right < 0) { 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks right = 0; 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (int j = 0; j < (bottom - top); j++) { 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Left edge 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (left > 0 && top > 0) { 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + left) + 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE; 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + left) + 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE; 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + left) + 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE; 120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Right edge 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (right > 0 && top > 0) { 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + right) + 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE; 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + right) + 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE; 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * (top + j) + right) + 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE; 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks for (int k = 0; k < (right - left); k++) { 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Top edge 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (top < dims[1]) { 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * top + left + k) + 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE; 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * top + left + k) + 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE; 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * top + left + k) + 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE; 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Bottom edge 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (bottom < dims[1]) { 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * bottom + left + k) + 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE; 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * bottom + left + k) + 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE; 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks pixels[ImageConstants.PIX_CHANNELS * (dims[0] * bottom + left + k) + 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE; 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 160