Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,9 @@ temp/

### Vaadin ###
.vaadin-designer
.designer
.designer

# vs-code history
.history


11 changes: 11 additions & 0 deletions .project
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,15 @@
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
<filteredResources>
<filter>
<id>1689214028499</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Install the component using [Vaadin Directory](https://vaadin.com/directory/comp

[docs.f0rce.de/cropper](https://docs.f0rce.de/cropper)

## Example
Check the example folder for an example Vaadin view that uses cropper.


## License

Expand Down
66 changes: 66 additions & 0 deletions example/src/de/f0rce/cropper/view/ImageCropView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package de.f0rce.cropper.example;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;

import de.f0rce.cropper.settings.enums.ViewMode;
import de.f0rce.cropper.CroppableImage;
import de.f0rce.cropper.CroppableImageBuilder;

@Route(value = ImageCropView.NAME)
public class ImageCropView extends VerticalLayout
{
private static final long serialVersionUID = 1L;
Logger logger = LogManager.getLogger();

public static final String NAME = "ImageCropView";


public ImageCropView()
{
build();
}

/**
* @throws Exception
*/
protected void build()
{
var builder = new CroppableImageBuilder(
() -> fetchImage(), "image/png");
builder.setId(generatedImage.buildSwatchS3Key(this.category, includeVersion));
builder.setViewMode(ViewMode.ONE);
builder.setAspectRatio(0.0);
builder.setInitialAspectRatio(GeneratedImage.SWATCH_HEIGHT / GeneratedImage.SWATCH_WIDTH);
builder.setScalable(false);
builder.setZoomable(false);
builder.setMinCropBoxWidth(ImageRequest.DEFAULT_WIDTH);
builder.setMinCropBoxHeight(ImageRequest.DEFAULT_HEIGHT);


var copper = builder.build();
Button cropButton = new Button("crop", e -> {
/// Displayed the cropped image.
var image = cropper.getImage();
add(image);
});

add(cropper, cropButton);

}

InputStream fetchImage() {
/// load the image from a file or the network and return it
/// as an input stream of bytes
}

}
121 changes: 121 additions & 0 deletions example/src/de/f0rce/cropper/widgets/CroppableImage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package de.f0rce.cropper.widgets;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Image;

import de.f0rce.cropper.Cropper;

public class CroppableImage extends Div
{
private static final long serialVersionUID = 1L;
Logger logger = LogManager.getLogger();
private Cropper cropper;
CroppableImageBuilder builder;


public CroppableImage(CroppableImageBuilder builder) throws Exception
{
this.builder = builder;
build();
}

private void build() throws Exception
{
getStyle().set("display", "block");
getStyle().set("max-width", "100%");
this.setId(builder.imageId);

add(buildCropper());
}

Component buildCropper() throws Exception
{
try (var imageStream = this.builder.imageFetcher.apply())
{
try
{
var b64Image = getB64Src();
this.cropper = new Cropper(
this.builder.cropperSettings, b64Image, this.builder.mimeType);
this.cropper.setId(this.builder.imageId);

return this.cropper;
}
catch (IOException e1)
{
this.logger.error(e1, e1);
throw e1;
}

}

}

private String getB64Src() throws Exception
{
String b64Image;
try (var imageStream = this.builder.imageFetcher.apply())
{
b64Image = java.util.Base64.getEncoder()
.encodeToString(IOUtils.toByteArray(imageStream));

return b64Image;
}
catch (IOException e1)
{
this.logger.error(e1, e1);
throw e1;
}

}

// Get the cropped image as a byte stream
public InputStream getCroppedStream()
{
return new ByteArrayInputStream(this.cropper.getImageBase64());
}

/// Returns the uncropped image with a b64 embedded src.
public Image getImage() throws Exception
{
var image = new Image();
image.setSrc("data:" + this.builder.mimeType + ";base64," + this.getB64Src());
return image;
}

/// Returns the cropped image with a b64 embedded src.
public Image getCroppedImage() throws Exception
{
var bytes = this.cropper.getImageBase64();
// var b64String = new String(bytes);

var b64String = java.util.Base64.getEncoder()
.encodeToString(bytes);

var image = new Image();
image.setSrc("data:" + this.builder.mimeType + ";base64," + b64String);
return image;
}


public static interface ImageFetcher
{
InputStream apply() throws Exception;
}

public void setImageId(String id)
{
this.builder.imageId = id;

}

}
100 changes: 100 additions & 0 deletions example/src/de/f0rce/cropper/widgets/CroppableImageBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package de.f0rce.cropper.widgets;

import java.io.InputStream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import de.f0rce.cropper.settings.CropperSettings;
import de.f0rce.cropper.settings.enums.ViewMode;

public class CroppableImageBuilder
{
Logger logger = LogManager.getLogger();
ImageFetcher imageFetcher;
CropperSettings cropperSettings = new CropperSettings();
String mimeType;
String imageId;

public CroppableImageBuilder(ImageFetcher imageFetcher, String mimeType) throws Exception
{
this.imageFetcher = imageFetcher;
this.mimeType = mimeType;

}

public void setInitialAspectRatio(double initialAspectRatio)
{
this.cropperSettings.setInitialAspectRatio(initialAspectRatio);
}

/* There is no way to directly set the size of the crop box so we hack it.
* By calling this method we set the min crop box size (width and height)
* and then set the autoCropArea to a really small value which results
* in the min crop box size being set as the initial crop box.
*/
public void forceCropBoxSize(int widthPx, int heightPx)
{
this.cropperSettings.setAutoCropArea(0.01);
this.cropperSettings.setMinCropBoxWidth(widthPx);
this.cropperSettings.setMinCropBoxHeight(heightPx);
}

public void setCroppedImageHeight(int heightPx)
{
this.cropperSettings.setCroppedImageHeight(heightPx);
}

public void setCroppedImageWidth(int widthPx)
{
this.cropperSettings.setCroppedImageWidth(widthPx);
}

public void setMinCropBoxHeight(int heightPx)
{

this.cropperSettings.setMinCropBoxHeight(heightPx);
}

public void setMinCropBoxWidth(int widthPx)
{
this.cropperSettings.setMinCropBoxWidth(widthPx);
}

public void setViewMode(ViewMode mode)
{
this.cropperSettings.setViewMode(mode);
}

public void setAspectRatio(double aspectRatio)
{
this.cropperSettings.setAspectRatio(aspectRatio);
}

public void setScalable(boolean scalable)
{
this.cropperSettings.setScalable(scalable);
}

public void setZoomable(boolean zoomable)
{
this.cropperSettings.setZoomable(zoomable);
}

public CroppableImage build() throws Exception
{
return new CroppableImage(this);
}

public static interface ImageFetcher
{
InputStream apply() throws Exception;
}

public void setImageId(String id)
{
this.imageId = id;

}

}