Search in sources :

Example 11 with EditorModel

use of org.signal.imageeditor.core.model.EditorModel 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 12 with EditorModel

use of org.signal.imageeditor.core.model.EditorModel 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)

Example 13 with EditorModel

use of org.signal.imageeditor.core.model.EditorModel in project Signal-Android by WhisperSystems.

the class MainActivity method initialModel.

private static EditorModel initialModel() {
    EditorModel model = EditorModel.create();
    EditorElement image = new EditorElement(new UrlRenderer("https://cdn.aarp.net/content/dam/aarp/home-and-family/your-home/2018/06/1140-house-inheriting.imgcache.rev68c065601779c5d76b913cf9ec3a977e.jpg"));
    image.getFlags().setSelectable(false).persist();
    model.addElement(image);
    EditorElement elementC = new EditorElement(new UrlRenderer("https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/SNice.svg/220px-SNice.svg.png"));
    elementC.getLocalMatrix().postScale(0.2f, 0.2f);
    // elementC.getLocalMatrix().postRotate(30);
    model.addElement(elementC);
    EditorElement elementE = new EditorElement(new UrlRenderer("https://www.vitalessentialsraw.com/assets/images/background-images/laying-grey-cat.png"));
    elementE.getLocalMatrix().postScale(0.2f, 0.2f);
    // elementE.getLocalMatrix().postRotate(60);
    model.addElement(elementE);
    EditorElement elementD = new EditorElement(new UrlRenderer("https://petspluslubbocktx.com/files/2016/11/DC-Cat-Weight-Management.png"));
    elementD.getLocalMatrix().postScale(0.2f, 0.2f);
    // elementD.getLocalMatrix().postRotate(60);
    model.addElement(elementD);
    EditorElement elementF = new EditorElement(new UrlRenderer("https://purepng.com/public/uploads/large/purepng.com-black-top-hathatsstandard-sizeblacktop-14215263591972x0zh.png"));
    elementF.getLocalMatrix().postScale(0.2f, 0.2f);
    // elementF.getLocalMatrix().postRotatF(60);
    model.addElement(elementF);
    EditorElement elementG = new EditorElement(new UriRenderer(Uri.parse("file:///android_asset/food/apple.png")));
    elementG.getLocalMatrix().postScale(0.2f, 0.2f);
    // elementG.getLocalMatrix().postRotatG(60);
    model.addElement(elementG);
    EditorElement elementH = new EditorElement(new MultiLineTextRenderer("Hello, World!", 0xff0000ff, MultiLineTextRenderer.Mode.REGULAR));
    // elementH.getLocalMatrix().postScale(0.2f, 0.2f);
    model.addElement(elementH);
    EditorElement elementH2 = new EditorElement(new MultiLineTextRenderer("Hello, World 2!", 0xff0000ff, MultiLineTextRenderer.Mode.REGULAR));
    // elementH.getLocalMatrix().postScale(0.2f, 0.2f);
    model.addElement(elementH2);
    return model;
}
Also used : EditorModel(org.signal.imageeditor.core.model.EditorModel) MultiLineTextRenderer(org.signal.imageeditor.core.renderers.MultiLineTextRenderer) EditorElement(org.signal.imageeditor.core.model.EditorElement) UrlRenderer(org.signal.imageeditor.app.renderers.UrlRenderer) UriRenderer(org.signal.imageeditor.app.renderers.UriRenderer)

Example 14 with EditorModel

use of org.signal.imageeditor.core.model.EditorModel in project Signal-Android by WhisperSystems.

the class MainActivity method onCreate.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);
    Toolbar toolbar = findViewById(R.id.toolbar);
    toolbar.setTitle(R.string.app_name_short);
    setSupportActionBar(toolbar);
    imageEditorView = findViewById(R.id.image_editor);
    imageEditorView.setUndoRedoStackListener((undoAvailable, redoAvailable) -> {
        Log.d("ALAN", String.format("Undo/Redo available: %s, %s", undoAvailable ? "Y" : "N", redoAvailable ? "Y" : "N"));
        if (menu == null)
            return;
        MenuItem undo = menu.findItem(R.id.action_undo);
        MenuItem redo = menu.findItem(R.id.action_redo);
        if (undo != null)
            undo.setVisible(undoAvailable);
        if (redo != null)
            redo.setVisible(redoAvailable);
    });
    EditorModel model = null;
    if (savedInstanceState != null) {
        model = savedInstanceState.getParcelable("MODEL");
        Log.d("ALAN", "Restoring instance " + (model != null ? model.hashCode() : 0));
    }
    if (model == null) {
        model = initialModel();
        Log.d("ALAN", "New instance created " + model.hashCode());
    }
    imageEditorView.setModel(model);
    imageEditorView.setTapListener(new ImageEditorView.TapListener() {

        @Override
        public void onEntityDown(@Nullable EditorElement editorElement) {
            Log.d("ALAN", "Entity down " + editorElement);
        }

        @Override
        public void onEntitySingleTap(@Nullable EditorElement editorElement) {
            Log.d("ALAN", "Entity single tapped " + editorElement);
        }

        @Override
        public void onEntityDoubleTap(@NonNull EditorElement editorElement) {
            Log.d("ALAN", "Entity double tapped " + editorElement);
            if (editorElement.getRenderer() instanceof MultiLineTextRenderer) {
                imageEditorView.startTextEditing(editorElement);
            } else {
                imageEditorView.deleteElement(editorElement);
            }
        }
    });
}
Also used : EditorModel(org.signal.imageeditor.core.model.EditorModel) MultiLineTextRenderer(org.signal.imageeditor.core.renderers.MultiLineTextRenderer) EditorElement(org.signal.imageeditor.core.model.EditorElement) MenuItem(android.view.MenuItem) ImageEditorView(org.signal.imageeditor.core.ImageEditorView) Toolbar(androidx.appcompat.widget.Toolbar)

Example 15 with EditorModel

use of org.signal.imageeditor.core.model.EditorModel in project Signal-Android by WhisperSystems.

the class ImageEditorFragment method restoreState.

@Override
public void restoreState(@NonNull Object state) {
    if (state instanceof Data) {
        Data data = (Data) state;
        EditorModel model = data.readModel();
        if (model != null) {
            if (imageEditorView != null) {
                imageEditorView.setModel(model);
                onDrawingChanged(false, false);
            } else {
                this.restoredModel = model;
            }
        }
    } else {
        Log.w(TAG, "Received a bad saved state. Received class: " + state.getClass().getName());
    }
}
Also used : EditorModel(org.signal.imageeditor.core.model.EditorModel)

Aggregations

EditorModel (org.signal.imageeditor.core.model.EditorModel)16 EditorElement (org.signal.imageeditor.core.model.EditorElement)10 Point (android.graphics.Point)8 Intent (android.content.Intent)4 AlertDialog (androidx.appcompat.app.AlertDialog)4 MultiLineTextRenderer (org.signal.imageeditor.core.renderers.MultiLineTextRenderer)4 Bitmap (android.graphics.Bitmap)2 Matrix (android.graphics.Matrix)2 Paint (android.graphics.Paint)2 DisplayMetrics (android.util.DisplayMetrics)2 MenuItem (android.view.MenuItem)2 Nullable (androidx.annotation.Nullable)2 Toolbar (androidx.appcompat.widget.Toolbar)2 LiveData (androidx.lifecycle.LiveData)2 UriRenderer (org.signal.imageeditor.app.renderers.UriRenderer)2 UrlRenderer (org.signal.imageeditor.app.renderers.UrlRenderer)2 ImageEditorView (org.signal.imageeditor.core.ImageEditorView)2 ImageEditorFragment (org.thoughtcrime.securesms.scribbles.ImageEditorFragment)2 UriGlideRenderer (org.thoughtcrime.securesms.scribbles.UriGlideRenderer)2 DefaultValueLiveData (org.thoughtcrime.securesms.util.DefaultValueLiveData)2