Search in sources :

Example 1 with EditorElement

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);
    });
}
Also used : UriGlideRenderer(org.thoughtcrime.securesms.scribbles.UriGlideRenderer) EditorModel(org.signal.imageeditor.core.model.EditorModel) EditorElement(org.signal.imageeditor.core.model.EditorElement) DisplayMetrics(android.util.DisplayMetrics) Point(android.graphics.Point)

Example 2 with EditorElement

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();
        }
    }
}
Also used : EditorElement(org.signal.imageeditor.core.model.EditorElement) FaceBlurRenderer(org.signal.imageeditor.core.renderers.FaceBlurRenderer)

Example 3 with EditorElement

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);
}
Also used : Matrix(android.graphics.Matrix) SelectableRenderer(org.signal.imageeditor.core.SelectableRenderer) Renderer(org.signal.imageeditor.core.Renderer) ColorableRenderer(org.signal.imageeditor.core.ColorableRenderer) BezierDrawingRenderer(org.signal.imageeditor.core.renderers.BezierDrawingRenderer) MultiLineTextRenderer(org.signal.imageeditor.core.renderers.MultiLineTextRenderer) FaceBlurRenderer(org.signal.imageeditor.core.renderers.FaceBlurRenderer) EditorElement(org.signal.imageeditor.core.model.EditorElement) FaceBlurRenderer(org.signal.imageeditor.core.renderers.FaceBlurRenderer)

Example 4 with EditorElement

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);
}
Also used : EditorModel(org.signal.imageeditor.core.model.EditorModel) EditorElement(org.signal.imageeditor.core.model.EditorElement) Paint(android.graphics.Paint) Point(android.graphics.Point)

Example 5 with EditorElement

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();
    });
}
Also used : AlertDialog(androidx.appcompat.app.AlertDialog) Bitmap(android.graphics.Bitmap) Matrix(android.graphics.Matrix) EditorModel(org.signal.imageeditor.core.model.EditorModel) EditorElement(org.signal.imageeditor.core.model.EditorElement) Point(android.graphics.Point)

Aggregations

EditorElement (org.signal.imageeditor.core.model.EditorElement)12 EditorModel (org.signal.imageeditor.core.model.EditorModel)5 Matrix (android.graphics.Matrix)4 Point (android.graphics.Point)4 MultiLineTextRenderer (org.signal.imageeditor.core.renderers.MultiLineTextRenderer)4 Paint (android.graphics.Paint)3 BezierDrawingRenderer (org.signal.imageeditor.core.renderers.BezierDrawingRenderer)2 FaceBlurRenderer (org.signal.imageeditor.core.renderers.FaceBlurRenderer)2 Bitmap (android.graphics.Bitmap)1 PorterDuffXfermode (android.graphics.PorterDuffXfermode)1 RectF (android.graphics.RectF)1 Uri (android.net.Uri)1 DisplayMetrics (android.util.DisplayMetrics)1 MenuItem (android.view.MenuItem)1 AlertDialog (androidx.appcompat.app.AlertDialog)1 Toolbar (androidx.appcompat.widget.Toolbar)1 UriRenderer (org.signal.imageeditor.app.renderers.UriRenderer)1 UrlRenderer (org.signal.imageeditor.app.renderers.UrlRenderer)1 ColorableRenderer (org.signal.imageeditor.core.ColorableRenderer)1 ImageEditorView (org.signal.imageeditor.core.ImageEditorView)1