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:
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;
}
User contributions licensed under CC BY-SA 3.0