I want to implement my own face detection/recognition android app. When camera finds some face, a rectangle is displayed on camera preview (in real time). App has method for taking photos too. However, I dont want to save whole picture, only the area within the rectangle - the human face. When I give the rectangle coordinates to Bitmap.createBitmap method to crop my picture, correctness of cropped photo depends on the place on display, where the rectangle was shown. When a detected face appears in the middle of preview, createBitmap crops it circa fine, but not if it shows on left or right side of the display. Seems like the coordinates I send to Bitmap.createBitmap are conversed but I cannot find the ratio. Any solutions?
Here is my onPictureTaken method:
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
RectF faceRect = mPreview.getFaceRect();
float x = faceRect.left;
float y = faceRect.top;
float w = faceRect.right - faceRect.left;
float h = faceRect.bottom - faceRect.top;
int intX = (int) x;
int intY = (int) y;
int intW = (int) w;
int intH = (int) h;
Bitmap croppedPicture = Bitmap.createBitmap(picture, intX, intY, intW, intH);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
croppedPicture.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArrayFromPicture = stream.toByteArray();
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(byteArrayFromPicture);
//fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
and here is some example of cropped picture, I do not have enough reputation to post more links:
(sorry about making picture of picture, I was lazy to implement saving the rectangle together with photo)
The solution was very simple - because of using frontal camera the captured image was always reflected, added two if-clauses:
Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
RectF faceRect = mPreview.getFaceRect();
Camera.Parameters parameters = mCamera.getParameters();
int picWidth = parameters.getPictureSize().width;
int intX = 0;
int intY = (int) faceRect.top;
int intW = (int) (faceRect.right - faceRect.left);
int intH = (int) (faceRect.bottom - faceRect.top);
if(faceRect.left > picWidth / 2) {
intX = (int) (faceRect.right - (faceRect.right - picWidth / 2) * 2);
}
else if(faceRect.left <= picWidth / 2) {
intX = (int) (picWidth - faceRect.right);
}
Bitmap croppedPicture = Bitmap.createBitmap(picture, intX, intY, intW, intH);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
croppedPicture.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArrayFromPicture = stream.toByteArray();