package com.uploadcare.urls;
import com.uploadcare.api.File;
import java.awt.*;
public class CdnPathBuilder {
public enum ImageFormat {
FORMAT_JPEG {
public String toString() {
return "jpeg";
}
},
FORMAT_PNG {
public String toString() {
return "png";
}
}
}
public enum ImageQuality {
QUALITY_NORMAL {
public String toString() {
return "normal";
}
},
QUALITY_BETTER {
public String toString() {
return "better";
}
},
QUALITY_BEST {
public String toString() {
return "best";
}
},
QUALITY_LIGHTER {
public String toString() {
return "lighter";
}
},
QUALITY_LIGHTEST {
public String toString() {
return "lightest";
}
}
}
private final StringBuilder sb = new StringBuilder("/");
/**
* Creates a new CDN path builder for some image file.
*
* @param file File to be used for the path
*
* @see com.uploadcare.api.File#cdnPath()
*/
public CdnPathBuilder(File file) {
sb.append(file.getFileId());
}
private void dimensionGuard(int dim) {
if (dim < 1 || dim > 2048) {
throw new IllegalArgumentException("Dimensions must be in the range 1-2048");
}
}
private void dimensionsGuard(int width, int height) {
dimensionGuard(width);
dimensionGuard(height);
if (width > 634 && height > 634) {
throw new IllegalArgumentException("At least one dimension must be less than 634");
}
}
private String colorToHex(Color color) {
String rgb = Integer.toHexString(color.getRGB());
return rgb.substring(2);
}
/**
* Adds top-left-aligned crop.
*
* @param width Crop width
* @param height Crop height
*/
public CdnPathBuilder crop(int width, int height) {
dimensionsGuard(width, height);
sb.append("/-/crop/")
.append(width)
.append("x")
.append(height);
return this;
}
/**
* Adds center-aligned crop.
*
* @param width Crop width
* @param height Crop height
*/
public CdnPathBuilder cropCenter(int width, int height) {
dimensionsGuard(width, height);
sb.append("/-/crop/")
.append(width)
.append("x")
.append(height)
.append("/center");
return this;
}
/**
* Adds top-left-aligned crop with a filled background.
*
* @param width Crop width
* @param height Crop height
* @param color Background color
*/
public CdnPathBuilder cropColor(int width, int height, Color color) {
dimensionsGuard(width, height);
sb.append("/-/crop/")
.append(width)
.append("x")
.append(height)
.append("/")
.append(colorToHex(color));
return this;
}
/**
* Adds center-aligned crop with a filled background.
*
* @param width Crop width
* @param height Crop height
* @param color Background color
*/
public CdnPathBuilder cropCenterColor(int width, int height, Color color) {
dimensionsGuard(width, height);
sb.append("/-/crop/")
.append(width)
.append("x")
.append(height)
.append("/center/")
.append(colorToHex(color));
return this;
}
/**
* Resizes width, keeping the aspect ratio.
*
* @param width New width
*/
public CdnPathBuilder resizeWidth(int width) {
dimensionGuard(width);
sb.append("/-/resize/")
.append(width)
.append("x");
return this;
}
/**
* Resizes height, keeping the aspect ratio.
*
* @param height New height
*/
public CdnPathBuilder resizeHeight(int height) {
dimensionGuard(height);
sb.append("/-/resize/x")
.append(height);
return this;
}
/**
* Resizes width and height
*
* @param width New width
* @param height New height
*/
public CdnPathBuilder resize(int width, int height) {
dimensionsGuard(width, height);
sb.append("/-/resize/")
.append(width)
.append("x")
.append(height);
return this;
}
/**
* Scales the image until one of the dimensions fits,
* then crops the bottom or right side.
*
* @param width New width
* @param height New height
*/
public CdnPathBuilder scaleCrop(int width, int height) {
dimensionsGuard(width, height);
sb.append("/-/scale_crop/")
.append(width)
.append("x")
.append(height);
return this;
}
/**
* Scales the image until one of the dimensions fits,
* centers it, then crops the rest.
*
* @param width New width
* @param height New height
*/
public CdnPathBuilder scaleCropCenter(int width, int height) {
dimensionsGuard(width, height);
sb.append("/-/scale_crop/")
.append(width)
.append("x")
.append(height)
.append("/center");
return this;
}
/**
* Flips the image.
*/
public CdnPathBuilder flip() {
sb.append("/-/flip");
return this;
}
/**
* Adds a grayscale effect.
*/
public CdnPathBuilder grayscale() {
sb.append("/-/grayscale");
return this;
}
/**
* Inverts colors.
*/
public CdnPathBuilder invert() {
sb.append("/-/invert");
return this;
}
/**
* Horizontally mirror image.
*/
public CdnPathBuilder mirror() {
sb.append("/-/mirror");
return this;
}
/**
* Performs Gaussian blur on result image.
*/
public CdnPathBuilder blur() {
sb.append("/-/blur");
return this;
}
/**
* Performs Gaussian blur on result image.
*
* @param strength Strength is standard deviation (aka blur radius) multiplied by ten. Strength
* can be up to 5000. Default is 10.
*/
public CdnPathBuilder blur(int strength) {
if (strength < 0 || strength > 5000) {
strength = 10;
}
sb.append("/-/blur/")
.append(strength);
return this;
}
/**
* Performs sharpening on result image. This can be useful after scaling down.
*/
public CdnPathBuilder sharp() {
sb.append("/-/sharp");
return this;
}
/**
* Performs sharpening on result image. This can be useful after scaling down.
*
* @param strength Strength can be from 0 to 20. Default is 5.
*/
public CdnPathBuilder sharp(int strength) {
if (strength < 0 || strength > 20) {
strength = 5;
}
sb.append("/-/sharp/")
.append(strength);
return this;
}
/**
* Reduces an image proportionally in order to fit it into given dimensions.
*
* @param width New width
* @param height New height
*/
public CdnPathBuilder preview(int width, int height) {
dimensionsGuard(width, height);
sb.append("/-/preview/")
.append(width)
.append("x")
.append(height);
return this;
}
/**
* Turn an image to one of the following formats: FORMAT_JPEG or FORMAT_PNG.
*
* @param format @link ImageFormat.
*/
public CdnPathBuilder format(ImageFormat format) {
sb.append("/-/format/")
.append(format.toString());
return this;
}
/**
* Image quality affects size of image and loading speed. Has no effect on non-JPEG images, but does not force format to JPEG.
*
* @param quality @link ImageQuality
* QUALITY_NORMAL – used by default. Fine in most cases.
* QUALITY_BETTER – can be used on relatively small previews with lots of details. ≈125% file size compared to normal image.
* QUALITY_BEST – useful if you're a photography god and you want to get perfect quality without paying attention to size. ≈170% file size.
* QUALITY_LIGHTER – can be used on relatively large images to save traffic without significant quality loss. ≈80% file size.
* QUALITY_LIGHTEST — useful for retina resolutions, when you don't wory about quality of each pixel. ≈50% file size.
*/
public CdnPathBuilder quality(ImageQuality quality) {
sb.append("/-/quality/")
.append(quality.toString());
return this;
}
/**
* Returns the current CDN path as a string.
*
* Avoid using directly.
* Instead, pass the configured builder to a URL factory.
*
* @return CDN path
*
* @see com.uploadcare.urls.Urls#cdn(CdnPathBuilder)
*/
public String build() {
return sb.append("/").toString();
}
}