use of org.signal.imageeditor.core.model.EditorElement in project Signal-Android by WhisperSystems.
the class WallpaperCropActivity method setupImageEditor.
private void setupImageEditor(@NonNull Uri imageUri) {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
float ratio = width / (float) height;
EditorModel editorModel = EditorModel.createForWallpaperEditing(ratio);
EditorElement image = new EditorElement(new UriGlideRenderer(imageUri, true, width, height, UriGlideRenderer.WEAK_BLUR));
image.getFlags().setSelectable(false).persist();
editorModel.addElement(image);
imageEditor.setModel(editorModel);
imageEditor.setSizeChangedListener((newWidth, newHeight) -> {
float newRatio = newWidth / (float) newHeight;
Log.i(TAG, String.format(Locale.US, "Output size (%d, %d) (ratio %.2f)", newWidth, newHeight, newRatio));
editorModel.setFixedRatio(newRatio);
});
}
use of org.signal.imageeditor.core.model.EditorElement in project Signal-Android by WhisperSystems.
the class WallpaperCropActivity method setBlurred.
private void setBlurred(boolean blurred) {
imageEditor.getModel().clearFaceRenderers();
if (blurred) {
EditorElement mainImage = imageEditor.getModel().getMainImage();
if (mainImage != null) {
EditorElement element = new EditorElement(new FaceBlurRenderer(), EditorModel.Z_MASK);
element.getFlags().setEditable(false).setSelectable(false).persist();
mainImage.addElement(element);
imageEditor.invalidate();
}
}
}
use of org.signal.imageeditor.core.model.EditorElement in project Signal-Android by WhisperSystems.
the class ImageEditorFragment method renderFaceBlurs.
private void renderFaceBlurs(@NonNull FaceDetectionResult result) {
List<FaceDetector.Face> faces = result.faces;
if (faces.isEmpty()) {
cachedFaceDetection = null;
return;
}
imageEditorView.getModel().pushUndoPoint();
Matrix faceMatrix = new Matrix();
for (FaceDetector.Face face : faces) {
Renderer faceBlurRenderer = new FaceBlurRenderer();
EditorElement element = new EditorElement(faceBlurRenderer, EditorModel.Z_MASK);
Matrix localMatrix = element.getLocalMatrix();
faceMatrix.setRectToRect(Bounds.FULL_BOUNDS, face.getBounds(), Matrix.ScaleToFit.FILL);
localMatrix.set(result.position);
localMatrix.preConcat(faceMatrix);
element.getFlags().setEditable(false).setSelectable(false).persist();
imageEditorView.getModel().addElementWithoutPushUndo(element);
}
imageEditorView.invalidate();
cachedFaceDetection = new Pair<>(getUri(), result);
}
use of org.signal.imageeditor.core.model.EditorElement in project Signal-Android by WhisperSystems.
the class ImageEditorFragment method onViewCreated.
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Mode mode = Mode.getByCode(requireArguments().getString(KEY_MODE));
imageEditorHud = view.findViewById(R.id.scribble_hud);
imageEditorView = view.findViewById(R.id.image_editor_view);
int width = getResources().getDisplayMetrics().widthPixels;
int height = (int) ((16 / 9f) * width);
imageEditorView.setMinimumHeight(height);
imageEditorView.requestLayout();
imageEditorHud.setBottomOfImageEditorView(getResources().getDisplayMetrics().heightPixels - height);
imageEditorHud.setEventListener(this);
imageEditorView.setDragListener(dragListener);
imageEditorView.setTapListener(selectionListener);
imageEditorView.setDrawingChangedListener(stillTouching -> onDrawingChanged(stillTouching, true));
imageEditorView.setUndoRedoStackListener(this::onUndoRedoAvailabilityChanged);
EditorModel editorModel = null;
if (restoredModel != null) {
editorModel = restoredModel;
restoredModel = null;
}
if (editorModel == null) {
switch(mode) {
case AVATAR_EDIT:
editorModel = EditorModel.createForAvatarEdit();
break;
case AVATAR_CAPTURE:
editorModel = EditorModel.createForAvatarCapture();
break;
default:
editorModel = EditorModel.create();
break;
}
EditorElement image = new EditorElement(new UriGlideRenderer(imageUri, true, imageMaxWidth, imageMaxHeight, UriGlideRenderer.STRONG_BLUR, mainImageRequestListener));
image.getFlags().setSelectable(false).persist();
editorModel.addElement(image);
} else {
controller.onMainImageLoaded();
}
if (mode == Mode.AVATAR_CAPTURE || mode == Mode.AVATAR_EDIT) {
imageEditorHud.setUpForAvatarEditing();
}
if (mode == Mode.AVATAR_CAPTURE) {
imageEditorHud.enterMode(ImageEditorHudV2.Mode.CROP);
}
imageEditorView.setModel(editorModel);
if (!SignalStore.tooltips().hasSeenBlurHudIconTooltip()) {
imageEditorHud.showBlurHudTooltip();
SignalStore.tooltips().markBlurHudIconTooltipSeen();
}
onDrawingChanged(false, false);
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), onBackPressedCallback);
}
use of org.signal.imageeditor.core.model.EditorElement in project Signal-Android by WhisperSystems.
the class ImageEditorFragment method onBlurFacesToggled.
@Override
public void onBlurFacesToggled(boolean enabled) {
EditorModel model = imageEditorView.getModel();
EditorElement mainImage = model.getMainImage();
if (mainImage == null) {
imageEditorHud.hideBlurToast();
return;
}
if (!enabled) {
model.clearFaceRenderers();
imageEditorHud.hideBlurToast();
return;
}
Matrix inverseCropPosition = model.getInverseCropPosition();
if (cachedFaceDetection != null) {
if (cachedFaceDetection.first().equals(getUri()) && cachedFaceDetection.second().position.equals(inverseCropPosition)) {
renderFaceBlurs(cachedFaceDetection.second());
imageEditorHud.showBlurToast();
return;
} else {
cachedFaceDetection = null;
}
}
AlertDialog progress = SimpleProgressDialog.show(requireContext());
mainImage.getFlags().setChildrenVisible(false);
SimpleTask.run(getLifecycle(), () -> {
if (mainImage.getRenderer() != null) {
Bitmap bitmap = ((UriGlideRenderer) mainImage.getRenderer()).getBitmap();
if (bitmap != null) {
FaceDetector detector = new AndroidFaceDetector();
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();
imageEditorHud.showBlurToast();
});
}
Aggregations