-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Feature proposal
Some images have a natural size that is quite large. Users typically expect that image to scale appropriately to fit within the screen. It would be cool if ImageCrop followed that convention. The image below shows an example... note that the cropping tool is barely visible and users have to scroll down to find it.
Describe solution expectations
My caveman approach to solving this is to set some styles for the div containing imageCrop. The code below shows the modifications I made to the openCropDialog method of the UploadImageCropDemo class. Note the use of dialogLayout.getStyle().set() method.
As I said, it's quite crude. It would probably be better to set dimensions as percentages and ensure this works on all devices. Nonetheless, it is effective and creates a much better user experience (provided you can ignore many overlapping dialogs, which is my fault not yours) as you can see in the screenshot.
private void openCropDialog(ByteArrayOutputStream outputStream, String mimeType, Avatar avatar) {
ImageCropGabe imageCrop;
// Set up image crop dialog
Dialog dialog = new Dialog();
dialog.setCloseOnOutsideClick(false);
dialog.setMaxHeight("100%");
dialog.setMaxWidth(dialog.getHeight());
Button cropButton = new Button("Crop image");
Button dialogCancelButton = new Button("Cancel");
dialogCancelButton.addThemeVariants(ButtonVariant.LUMO_ERROR);
String src = getImageAsBase64(outputStream.toByteArray(), mimeType);
imageCrop = new ImageCropGabe(src);
imageCrop.setAspect(1.0);
//imageCrop.setCircularCrop(true);
imageCrop.setCrop(new CropGabe("%", 25, 25, 50, 50)); // centered crop
imageCrop.setKeepSelection(true);
int targetHeight;
int targetWidth = 175;
int naturalWidth = 0;
int naturalHeight = 0;
try {
// Decode base64 back to a byte array
byte[] decodedBytes = Base64.getDecoder().decode(src.split(",")[1]); // Removing "data:image/...;base64,"
ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes);
// Use ImageIO to read the image dimensions
BufferedImage bufferedImage = ImageIO.read(inputStream);
if (bufferedImage != null) {
naturalWidth = bufferedImage.getWidth();
naturalHeight = bufferedImage.getHeight();
}
logger.info("Image dimensions: " + naturalWidth + " x " + naturalHeight);
} catch (Exception e) {
logger.error("Failed to load image dimensions: " + e.getMessage(), e);
}
double aspectRatio = naturalWidth > 0 && naturalHeight > 0 ? (double) naturalHeight / naturalWidth : 1.0;
targetHeight = (int) (targetWidth * aspectRatio);
logger.info("target dimensions: " + targetWidth + ", " + targetHeight);
cropButton.addClickListener(event -> {
byte[] newCroppedPicture = null;
newCroppedPicture = imageCrop.getCroppedImageBase64();
avatar.setImage(imageCrop.getCroppedImageDataUri());
dialog.close();
});
dialogCancelButton.addClickListener(c -> dialog.close());
HorizontalLayout buttonLayout = new HorizontalLayout(dialogCancelButton, cropButton);
Div dialogLayout = new Div(imageCrop);
dialogLayout.setId("imageCropContainer");
dialogLayout.getStyle()
.set("width", targetWidth + "px") // Scale the container
.set("height", targetHeight + "px") // Maintain desired height
.set("overflow", "hidden") // Crop overflow content
.set("margin", "0 auto");
buttonLayout.setWidthFull();
buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
dialog.add(dialogLayout);
dialog.getFooter().add(buttonLayout);
dialog.open();
}
Additional information
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status

