mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-19 16:19:33 +01:00
Blur faces rotation and crop and zoom support.
This commit is contained in:
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.scribbles;
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.RectF;
|
||||
@@ -19,14 +20,14 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.TooltipPopup;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.imageeditor.ColorableRenderer;
|
||||
import org.thoughtcrime.securesms.imageeditor.ImageEditorView;
|
||||
import org.thoughtcrime.securesms.imageeditor.Renderer;
|
||||
import org.thoughtcrime.securesms.imageeditor.model.EditorElement;
|
||||
import org.thoughtcrime.securesms.imageeditor.model.EditorModel;
|
||||
import org.thoughtcrime.securesms.imageeditor.renderers.MultiLineTextRenderer;
|
||||
import org.thoughtcrime.securesms.imageeditor.renderers.FaceBlurRenderer;
|
||||
import org.thoughtcrime.securesms.imageeditor.renderers.MultiLineTextRenderer;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mediasend.MediaSendPageFragment;
|
||||
@@ -344,30 +345,51 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
|
||||
@Override
|
||||
public void onBlurFacesToggled(boolean enabled) {
|
||||
if (!enabled) {
|
||||
imageEditorView.getModel().clearFaceRenderers();
|
||||
EditorModel model = imageEditorView.getModel();
|
||||
EditorElement mainImage = model.getMainImage();
|
||||
if (mainImage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cachedFaceDetection != null && cachedFaceDetection.first().equals(getUri())) {
|
||||
renderFaceBlurs(cachedFaceDetection.second());
|
||||
if (!enabled) {
|
||||
model.clearFaceRenderers();
|
||||
return;
|
||||
} else if (cachedFaceDetection != null && !cachedFaceDetection.first().equals(getUri())) {
|
||||
cachedFaceDetection = null;
|
||||
}
|
||||
|
||||
Matrix inverseCropPosition = model.getInverseCropPosition();
|
||||
|
||||
if (cachedFaceDetection != null) {
|
||||
if (cachedFaceDetection.first().equals(getUri()) && cachedFaceDetection.second().position.equals(inverseCropPosition)) {
|
||||
renderFaceBlurs(cachedFaceDetection.second());
|
||||
return;
|
||||
} else {
|
||||
cachedFaceDetection = null;
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog progress = SimpleProgressDialog.show(requireContext());
|
||||
mainImage.getFlags().setChildrenVisible(false);
|
||||
|
||||
SimpleTask.run(() -> {
|
||||
Bitmap bitmap = ((UriGlideRenderer) imageEditorView.getModel().getMainImage().getRenderer()).getBitmap();
|
||||
SimpleTask.run(getLifecycle(), () -> {
|
||||
if (mainImage.getRenderer() != null) {
|
||||
Bitmap bitmap = ((UriGlideRenderer) mainImage.getRenderer()).getBitmap();
|
||||
if (bitmap != null) {
|
||||
FaceDetector detector = new FirebaseFaceDetector();
|
||||
|
||||
if (bitmap != null) {
|
||||
FaceDetector detector = new FirebaseFaceDetector();
|
||||
return new FaceDetectionResult(detector.detect(bitmap), new Point(bitmap.getWidth(), bitmap.getHeight()));
|
||||
} else {
|
||||
return new FaceDetectionResult(Collections.emptyList(), new Point(0, 0));
|
||||
Point size = model.getOutputSizeMaxWidth(1000);
|
||||
Bitmap render = model.render(ApplicationDependencies.getApplication(), size);
|
||||
try {
|
||||
return new FaceDetectionResult(detector.detect(render), new Point(render.getWidth(), render.getHeight()), inverseCropPosition);
|
||||
} finally {
|
||||
render.recycle();
|
||||
mainImage.getFlags().reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new FaceDetectionResult(Collections.emptyList(), new Point(0, 0), new Matrix());
|
||||
}, result -> {
|
||||
mainImage.getFlags().reset();
|
||||
renderFaceBlurs(result);
|
||||
progress.dismiss();
|
||||
});
|
||||
@@ -469,7 +491,9 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
|
||||
for (RectF face : faces) {
|
||||
FaceBlurRenderer faceBlurRenderer = new FaceBlurRenderer(face, size);
|
||||
imageEditorView.getModel().addElementWithoutPushUndo(new EditorElement(faceBlurRenderer, EditorModel.Z_MASK));
|
||||
EditorElement element = new EditorElement(faceBlurRenderer, EditorModel.Z_MASK);
|
||||
element.getLocalMatrix().set(result.position);
|
||||
imageEditorView.getModel().addElementWithoutPushUndo(element);
|
||||
}
|
||||
|
||||
imageEditorView.invalidate();
|
||||
@@ -534,10 +558,12 @@ public final class ImageEditorFragment extends Fragment implements ImageEditorHu
|
||||
private static class FaceDetectionResult {
|
||||
private final List<RectF> rects;
|
||||
private final Point imageSize;
|
||||
private final Matrix position;
|
||||
|
||||
private FaceDetectionResult(@NonNull List<RectF> rects, @NonNull Point imageSize) {
|
||||
private FaceDetectionResult(@NonNull List<RectF> rects, @NonNull Point imageSize, @NonNull Matrix position) {
|
||||
this.rects = rects;
|
||||
this.imageSize = imageSize;
|
||||
this.position = new Matrix(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user