Generalize code to capture and crop a photo

1

This questions refers to Codename One only.

Thanks to the commit 98dcbaa and re-working the test case ImageViewerSample2778, I created a full working example to capture a photo and to crop it. My initial result is satisfying, at least in the Simulator:

enter image description here

It seems ok, however I wasn't able to write a code that is enough generic. The problem is the var width, used more times in the following code (it's used in the override of calcPreferredSize of ImageViewer, in roundMask, maskImg and .fillArc).

Maybe could my code be more generic using a custom layout? The problem of a fixed width is that the UI is not adapted if the Form is resized. Moreover a more generic code could be encapsulated in a method to capture, show and crop a photo.

Do you have any idea or suggestion to improve my code?

Java:

Form hi = new Form("Crop your avatar", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_TOTAL_BELOW));
        hi.getContentPane().setUIID("Crop-Avatar-ContentPane");

        int width = Display.getInstance().getDisplayWidth() - hi.getContentPane().getStyle().getMarginLeftNoRTL() - hi.getContentPane().getStyle().getMarginRightNoRTL();
        Image roundMask = Image.createImage(width, width, 0xFFFFFFFF);
        Graphics gr = roundMask.getGraphics();
        gr.setColor(0x000000);
        gr.fillArc(0, 0, width, width, 0, 360);
        Object mask = roundMask.createMask();
        Image maskImg = Image.createImage(width, width, 0xFFFFFFFF).applyMask(mask);
        maskImg = maskImg.modifyAlpha((byte) 200);
        Label maskLbl = new Label(maskImg, "Crop-Avatar-LabelMask");


        Container imageCropper = new Container(new LayeredLayout(), "NoMarginNoPadding");
        ImageViewer viewer = new ImageViewer() {
            @Override
            public Dimension calcPreferredSize() {
                return new Dimension(width, width);
            }
        };
        Container cnt1 = FlowLayout.encloseCenterMiddle(viewer);
        viewer.setUIID("NoMarginNoPadding");
        cnt1.setUIID("NoMarginNoPadding");
        Container cnt2 = FlowLayout.encloseCenterMiddle(maskLbl);
        cnt2.setUIID("NoMarginNoPadding");
        imageCropper.add(cnt1);
        imageCropper.add(cnt2);

        Button getCroppedImageFullSize = new Button("Confirm");
        getCroppedImageFullSize.addActionListener(e -> {
            ScaleImageLabel l = new ScaleImageLabel(viewer.getCroppedImage(0x0));
            Dialog.show("Crop is", l, new Command("OK"));
        });


        hi.add(BorderLayout.CENTER, imageCropper);
        hi.add(BorderLayout.NORTH, new SpanLabel("Move and zoom your photo to crop it as you want", "Crop-Avatar-Description"));
        hi.add(BorderLayout.SOUTH, FlowLayout.encloseCenter(getCroppedImageFullSize));
        hi.show();

        Capture.capturePhoto(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                if (evt == null || evt.getSource() == null) {
                    // the user cancelled the image capturing
                    return;
                }
                String file = (String) evt.getSource();
                try {
                    Image img = Image.createImage(file);
                    viewer.setImage(img);
                    if (img.getWidth() != img.getHeight()) {
                        // we need to zoom to perfectly fit a square
                        viewer.setZoom(Math.max((float) img.getHeight() / img.getWidth(), (float) img.getWidth() / img.getHeight()) + 0.01f);
                    }                    
                    hi.revalidateWithAnimationSafety();
                } catch (IOException ex) {
                    Log.p("Error loading captured image from camera", Log.ERROR);
                    Log.e(ex);
                }
            }
        });

CSS:

NoMarginNoPadding {
    padding: 0px;
    margin: 0px;
}

Crop-Avatar-LabelMask {
    padding: 0px;
    margin: 0px;
    border: 1mm blue solid;
}

Crop-Avatar-Description {
    padding: 3mm;
    text-align: center;
}

Crop-Avatar-ContentPane {
    padding: 0px;
    margin: 0px;
    margin-left: 3mm;
    margin-right: 3mm;
}
codenameone

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0