📄 cmsimagescaler.java
字号:
package org.opencms.loader;
import com.alkacon.simapi.RenderSettings;
import com.alkacon.simapi.Simapi;
import com.alkacon.simapi.filter.GrayscaleFilter;
import com.alkacon.simapi.filter.ShadowFilter;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.file.CmsResource;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsStringUtil;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
/**
* Creates scaled images, acting as it's own parameter container.<p>
*
* @author Alexander Kandzior
*
* @version $Revision: 1.3 $
*
* @since 6.2.0
*/
public class CmsImageScaler {
/** The name of the transparent color (for the backgound image). */
public static final String COLOR_TRANSPARENT = "transparent";
/** The name of the grayscale image filter. */
public static final String FILTER_GRAYSCALE = "grayscale";
/** The name of the shadow image filter. */
public static final String FILTER_SHADOW = "shadow";
/** The supported image filter names. */
public static final List FILTERS = Arrays.asList(new String[] {FILTER_GRAYSCALE, FILTER_SHADOW});
/** The (optional) parameter used for sending the scale information of an image in the http request. */
public static final String PARAM_SCALE = "__scale";
/** The default maximum image size (width * height) to apply image blurring when downscaling (setting this to high may case "out of memory" errors). */
public static final int SCALE_DEFAULT_MAX_BLUR_SIZE = 2500 * 2500;
/** The default maximum image size (width or height) to allow when updowscaling an image using request parameters. */
public static final int SCALE_DEFAULT_MAX_SIZE = 1500;
/** The scaler parameter to indicate the requested image background color (if required). */
public static final String SCALE_PARAM_COLOR = "c";
/** The scaler parameter to indicate the requested image filter. */
public static final String SCALE_PARAM_FILTER = "f";
/** The scaler parameter to indicate the requested image height. */
public static final String SCALE_PARAM_HEIGHT = "h";
/** The scaler parameter to indicate the requested image position (if required). */
public static final String SCALE_PARAM_POS = "p";
/** The scaler parameter to indicate to requested image save quality in percent (if applicable, for example used with JPEG images). */
public static final String SCALE_PARAM_QUALITY = "q";
/** The scaler parameter to indicate to requested <code>{@link java.awt.RenderingHints}</code> settings. */
public static final String SCALE_PARAM_RENDERMODE = "r";
/** The scaler parameter to indicate the requested scale type. */
public static final String SCALE_PARAM_TYPE = "t";
/** The scaler parameter to indicate the requested image width. */
public static final String SCALE_PARAM_WIDTH = "w";
/** The log object for this class. */
protected static final Log LOG = CmsLog.getLog(CmsImageScaler.class);
/** The target background color (optional). */
private Color m_color;
/** The list of image filter names (Strings) to apply. */
private List m_filters;
/** The target height (required). */
private int m_height;
/** The maximum image size (width * height) to apply image blurring when downscaling (setting this to high may case "out of memory" errors). */
private int m_maxBlurSize;
/** The target position (optional). */
private int m_position;
/** The target image save quality (if applicable, for example used with JPEG images) (optional). */
private int m_quality;
/** The image processing renderings hints constant mode indicator (optional). */
private int m_renderMode;
/** The final (parsed and corrected) scale parameters. */
private String m_scaleParameters;
/** The target scale type (optional). */
private int m_type;
/** The target width (required). */
private int m_width;
/**
* Creates a new, empty image scaler object.<p>
*/
public CmsImageScaler() {
init();
}
/**
* Creates a new image scaler for the given image contained in the byte array.<p>
*
* <b>Please note:</b>The image itself is not stored in the scaler, only the width and
* height dimensions of the image. To actually scale an image, you need to use
* <code>{@link #scaleImage(CmsFile)}</code>. This constructor is commonly used only
* to extract the image dimensions, for example when creating a String value for
* the <code>{@link CmsPropertyDefinition#PROPERTY_IMAGE_SIZE}</code> property.<p>
*
* In case the byte array can not be decoded to an image, or in case of other errors,
* <code>{@link #isValid()}</code> will return <code>false</code>.<p>
*
* @param content the image to calculate the dimensions for
* @param rootPath the root path of the resource (for error logging)
*/
public CmsImageScaler(byte[] content, String rootPath) {
init();
try {
// read the scaled image
BufferedImage image = Simapi.read(content);
m_height = image.getHeight();
m_width = image.getWidth();
} catch (Exception e) {
// nothing we can do about this, keep the original properties
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.get().getBundle().key(Messages.ERR_UNABLE_TO_EXTRACT_IMAGE_SIZE_1, rootPath), e);
}
// set height / width to default of -1
init();
}
}
/**
* Creates a new image scaler that is a recale from the original size to the given scaler.<p>
*
* @param original the scaler that holds the original image dimensions
* @param target the image scaler to be used for rescaling this image scaler
*
* @deprecated use {@link #getReScaler(CmsImageScaler)} on the <code>original</code> scaler instead
*/
public CmsImageScaler(CmsImageScaler original, CmsImageScaler target) {
CmsImageScaler scaler = original.getReScaler(target);
initValuesFrom(scaler);
}
/**
* Creates a new image scaler by reading the property <code>{@link CmsPropertyDefinition#PROPERTY_IMAGE_SIZE}</code>
* from the given resource.<p>
*
* In case of any errors reading or parsing the property,
* <code>{@link #isValid()}</code> will return <code>false</code>.<p>
*
* @param cms the OpenCms user context to use when reading the property
* @param res the resource to read the property from
*/
public CmsImageScaler(CmsObject cms, CmsResource res) {
init();
String sizeValue = null;
if ((cms != null) && (res != null)) {
try {
CmsProperty sizeProp = cms.readPropertyObject(res, CmsPropertyDefinition.PROPERTY_IMAGE_SIZE, false);
if (!sizeProp.isNullProperty()) {
// parse property value using standard procedures
sizeValue = sizeProp.getValue();
}
} catch (Exception e) {
// ignore
}
}
if (CmsStringUtil.isNotEmpty(sizeValue)) {
parseParameters(sizeValue);
}
}
/**
* Creates a new image scaler based on the given http request.<p>
*
* @param request the http request to read the parameters from
* @param maxScaleSize the maximum scale size (width or height) for the image
* @param maxBlurSize the maximum size of the image (width * height) to apply blur (may cause "out of memory" for large images)
*/
public CmsImageScaler(HttpServletRequest request, int maxScaleSize, int maxBlurSize) {
init();
m_maxBlurSize = maxBlurSize;
String parameters = request.getParameter(CmsImageScaler.PARAM_SCALE);
if (CmsStringUtil.isNotEmpty(parameters)) {
parseParameters(parameters);
if (isValid()) {
// valid parameters, check if scale size is not too big
if ((getWidth() > maxScaleSize) || (getHeight() > maxScaleSize)) {
// scale size is too big, reset scaler
init();
}
}
}
}
/**
* Creates a new image scaler based on the given parameter String.<p>
*
* @param parameters the scale parameters to use
*/
public CmsImageScaler(String parameters) {
init();
if (CmsStringUtil.isNotEmpty(parameters)) {
parseParameters(parameters);
}
}
/**
* Creates a new image scaler based on the given base scaler and the given width and height.<p>
*
* @param base the base scaler to initialize the values with
* @param width the width to set for this scaler
* @param height the height to set for this scaler
*/
protected CmsImageScaler(CmsImageScaler base, int width, int height) {
initValuesFrom(base);
setWidth(width);
setHeight(height);
}
/**
* Adds a filter name to the list of filters that should be applied to the image.<p>
*
* @param filter the filter name to add
*/
public void addFilter(String filter) {
if (CmsStringUtil.isNotEmpty(filter)) {
filter = filter.trim().toLowerCase();
if (FILTERS.contains(filter)) {
m_filters.add(filter);
}
}
}
/**
* @see java.lang.Object#clone()
*/
public Object clone() {
CmsImageScaler clone = new CmsImageScaler();
clone.initValuesFrom(this);
return clone;
}
/**
* Returns the color.<p>
*
* @return the color
*/
public Color getColor() {
return m_color;
}
/**
* Returns the color as a String.<p>
*
* @return the color as a String
*/
public String getColorString() {
StringBuffer result = new StringBuffer();
if (m_color == Simapi.COLOR_TRANSPARENT) {
result.append(COLOR_TRANSPARENT);
} else {
if (m_color.getRed() < 16) {
result.append('0');
}
result.append(Integer.toString(m_color.getRed(), 16));
if (m_color.getGreen() < 16) {
result.append('0');
}
result.append(Integer.toString(m_color.getGreen(), 16));
if (m_color.getBlue() < 16) {
result.append('0');
}
result.append(Integer.toString(m_color.getBlue(), 16));
}
return result.toString();
}
/**
* Returns a new image scaler that is a downscale from the size of <code>this</code> scaler
* to the given scaler size.<p>
*
* If no downscale from this to the given scaler is required according to
* {@link #isDownScaleRequired(CmsImageScaler)}, then <code>null</code> is returned.<p>
*
* @param downScaler the image scaler that holds the downscaled target image dimensions
*
* @return a new image scaler that is a downscale from the size of <code>this</code> scaler
* to the given target scaler size, or <code>null</code>
*/
public CmsImageScaler getDownScaler(CmsImageScaler downScaler) {
if (!isDownScaleRequired(downScaler)) {
// no downscaling is required
return null;
}
int downHeight = downScaler.getHeight();
int downWidth = downScaler.getWidth();
int height = getHeight();
int width = getWidth();
if (((height > width) && (downHeight < downWidth)) || ((width > height) && (downWidth < downHeight))) {
// adjust orientation
downHeight = downWidth;
downWidth = downScaler.getHeight();
}
if (width > downWidth) {
// width is too large, re-calculate height
float scale = (float)downWidth / (float)width;
downHeight = Math.round(height * scale);
} else if (height > downHeight) {
// height is too large, re-calculate width
float scale = (float)downHeight / (float)height;
downWidth = Math.round(width * scale);
} else {
// something is wrong, don't downscale
return null;
}
// now create and initialize the result scaler
return new CmsImageScaler(downScaler, downWidth, downHeight);
}
/**
* Returns the list of image filter names (Strings) to be applied to the image.<p>
*
* @return the list of image filter names (Strings) to be applied to the image
*/
public List getFilters() {
return m_filters;
}
/**
* Returns the list of image filter names (Strings) to be applied to the image as a String.<p>
*
* @return the list of image filter names (Strings) to be applied to the image as a String
*/
public String getFiltersString() {
StringBuffer result = new StringBuffer();
Iterator i = m_filters.iterator();
while (i.hasNext()) {
String filter = (String)i.next();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -