import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.alkacon.simapi.RenderSettings;
import com.alkacon.simapi.Simapi;
//import com.xunware.framework.exception.CsdeException;
import java.io.File;
* @author Oy
* @类名 :ImageUtil.java
* @作用 :图片处理工具类,1、按指定宽度高度进行居中裁剪并缩放图片,2、按图片比例缩放图片
* 图片大小应不要超过500KB,图片太大,转换时可能导致内存溢出
public class ImageUtil {
protected static final Log log = LogFactory.getLog(ImageUtil.class);
/** The default maximum image size (width * height) to apply image blurring when down scaling (setting this 1to 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 up or down scaling an image using request parameters. */
public static final int SCALE_DEFAULT_MAX_SIZE = 1500;
* Hides the public constructor.<p>
*/
private ImageUtil() {
//noop
* 按指定宽度高度进行居中裁剪并缩放图片
* @param imageSrcPath 源图片地址
* @param width 目标图片宽度(为0时,不限制)
* @param height 目标图片高度(为0时,不限制)
* @param conversionFlag 是否放大(如果源图片高度和宽度均小于目标的宽度和高度)
* @return 目标图片地址
* @throws CsdeException
*/
public static String showImageFromMiddleCut(String imageSrcPath, int width, int height, boolean conversionFlag)throws Exception{
if(imageSrcPath.indexOf(".")==-1){
log.warn("图片没有处理直接返回,原因:不能识别源图片类型,源图片地址:"+imageSrcPath);
return imageSrcPath;
}http://www.huiyi8.com/tupiantexiao/ 图片特效
String imageType=imageSrcPath.substring(imageSrcPath.lastIndexOf(".")+1);
return showImageFromMiddleCut(imageSrcPath, imageType, width, height, conversionFlag);
}
/**
* 按指定宽度高度进行居中裁剪并缩放图片
* @param imageSrcPath 源图片地址
* @param imageType 目标图片类型
* @param width 目标图片宽度(为0时,不限制)
* @param height 目标图片高度(为0时,不限制)
* @param conversionFlag 是否放大(如果源图片高度和宽度均小于目标的宽度和高度)
* @return 目标图片地址
* @throws CsdeException
*/
public static String showImageFromMiddleCut(String imageSrcPath, String imageType, int width, int height, boolean conversionFlag)throws Exception{
if(width>SCALE_DEFAULT_MAX_SIZE){
log.warn("图片没有处理直接返回,原因:目标图片宽度不能超过最大默认宽度"+SCALE_DEFAULT_MAX_SIZE+",源图片地址:"+imageSrcPath);
return imageSrcPath;
}
if(height>SCALE_DEFAULT_MAX_SIZE){
log.warn("图片没有处理直接返回,原因:目标图片高度不能超过最大默认高度"+SCALE_DEFAULT_MAX_SIZE+",源图片地址:"+imageSrcPath);
return imageSrcPath;
}
if(imageSrcPath.indexOf(".")==-1){
log.warn("图片没有处理直接返回,原因:不能识别源图片类型,源图片地址:"+imageSrcPath);
return imageSrcPath;
}
if(!existFile(imageSrcPath, true)){
log.warn("图片没有处理直接返回,原因:源图片不存在,源图片地址:"+imageSrcPath);
return imageSrcPath;
}
BufferedImage image=null;
try {
image = Simapi.read(imageSrcPath);
} catch (IOException e1) {
log.error(e1);
e1.printStackTrace();
}
if(image.getWidth()>SCALE_DEFAULT_MAX_SIZE||image.getHeight()>SCALE_DEFAULT_MAX_SIZE){
image=resize(image, SCALE_DEFAULT_MAX_SIZE, SCALE_DEFAULT_MAX_SIZE, false);
}
int m_cropX=0;
int m_cropY=0;
int m_cropWidth=image.getWidth();
int m_cropHeight=image.getHeight();
int m_Width=width;
if(m_Width>SCALE_DEFAULT_MAX_SIZE){
m_Width=SCALE_DEFAULT_MAX_SIZE;
}
int m_Height=height;
if(m_Height>SCALE_DEFAULT_MAX_SIZE){
m_Height=SCALE_DEFAULT_MAX_SIZE;
}
//宽度没有限制
if(m_Width==0&&m_Height>0){
m_Width=m_Height*m_cropWidth/m_cropHeight;
return cropToSize(image, m_cropX, m_cropY, m_cropWidth, m_cropHeight, m_Width, m_Height, m_color, imageSrcPath, imageType, conversionFlag);
}else
//高度没有限制
if(m_Height==0&&m_Width>0){
m_Height=m_Width*m_cropHeight/m_cropWidth;
return cropToSize(image, m_cropX, m_cropY, m_cropWidth, m_cropHeight, m_Width, m_Height, m_color, imageSrcPath, imageType, conversionFlag);
}else
//设置了宽度和高度
if(m_Height>0&&m_Width>0){
if(m_cropWidth>m_cropHeight*m_Width/m_Height){
m_cropWidth=m_cropHeight*m_Width/m_Height;
m_cropX=(image.getWidth()-m_cropWidth)/2;
}else if(m_cropWidth<m_cropHeight*m_Width/m_Height){
m_cropHeight=m_cropWidth*m_Height/m_Width;
m_cropY=(image.getHeight()-m_cropHeight)/2;
}else {
//不需改变
}
return cropToSize(image, m_cropX, m_cropY, m_cropWidth, m_cropHeight, m_Width, m_Height, m_color, imageSrcPath, imageType, conversionFlag);
}else
//宽度和高度都没有限制
{
return cropToSize(image, m_cropX, m_cropY, m_cropWidth, m_cropHeight, m_cropWidth, m_cropHeight, m_color, imageSrcPath, imageType, false);
}
}
/**
* 按指定宽度高度缩放并裁剪图片
* @param image 图片缓存
* @param m_cropX 裁剪源图片起始位置X
* @param m_cropY 裁剪源图片起始位置Y
* @param m_cropWidth 裁剪源图片宽度
* @param m_cropHeight 裁剪源图片高度
* @param m_Width 生成的目标图片宽度(为0时,不限制)
* @param m_Height 生成的目标图片高度(为0时,不限制)
* @param m_color 填充的背景颜色
* @param imageSrcPath 源图片地址
* @param imageType 图片类型
* @param conversionFlag 是否放大(如果源图片高度和宽度均小于目标的宽度和高度)
* @return 目标图片地址
*/
private static String cropToSize(BufferedImage image, int m_cropX, int m_cropY, int m_cropWidth,
int m_cropHeight, int m_Width, int m_Height, Color m_color, String imageSrcPath, String imageType, boolean conversionFlag){
String imageTarget;
if(conversionFlag || m_cropWidth>m_Width || m_cropHeight>m_Height){
// target image path
imageTarget = buildTargetImageFilePath(imageSrcPath, m_Width, m_Height, imageType);
}else{
// target image path
imageTarget = buildTargetImageFilePath(imageSrcPath, image.getWidth(), image.getHeight(), imageType);
}
if(existFile(imageTarget, false)){
log.warn("图片没有处理直接返回,原因:目标图片路径存在文件");
return imageTarget;
}
// use default render mode and quality
RenderSettings renderSettings=new RenderSettings(Simapi.RENDER_QUALITY);
// set max blur size
renderSettings.setMaximumBlurSize(SCALE_DEFAULT_MAX_BLUR_SIZE);
// new create the scaler
Simapi scaler = new Simapi(renderSettings);
if(conversionFlag || m_cropWidth>m_Width || m_cropHeight>m_Height){
BufferedImage buferedImage=scaler.cropToSize(
image,
m_cropX,
m_cropY,
m_cropWidth,
m_cropHeight,
m_Width,
m_Height,
m_color);
try {
scaler.write(buferedImage, imageTarget, imageType);
} catch (IOException e) {
log.error(e);
e.printStackTrace();
}
}else{
try {
scaler.write(image, imageTarget, imageType);
} catch (IOException e) {
log.error(e);
e.printStackTrace();
}
}
return imageTarget;
}
/**
* 按图片比例缩放图片
* @param imageSrcPath 源图片路径
* @param width 目标图片宽度(为0时,不限制)
* @param height 目标图片高度(为0时,不限制)
* @param conversionFlag 是否放大
* @return 目标图片路径
* @throws CsdeException
*/
public static String resize(String imageSrcPath, int width, int height, boolean conversionFlag)throws Exception{
if(imageSrcPath.indexOf(".")==-1){
log.warn("图片没有处理直接返回,原因:不能识别源图片类型,源图片地址:"+imageSrcPath);
return imageSrcPath;
}
String imageType=imageSrcPath.substring(imageSrcPath.lastIndexOf(".")+1);
return resize(imageSrcPath, imageType, width, height, conversionFlag);
}
/**
* 按图片比例缩放图片
* @param imageSrcPath 源图片路径
* @param imageType 目标图片类型
* @param width 目标图片宽度(为0时,不限制)
* @param height 目标图片高度(为0时,不限制)
* @param conversionFlag 是否放大
* @return 目标图片路径
* @throws CsdeException
*/
public static String resize(String imageSrcPath, String imageType, int width, int height, boolean conversionFlag)throws Exception{
if(width>SCALE_DEFAULT_MAX_SIZE){
log.warn("图片没有处理直接返回,原因:目标图片宽度不能超过最大默认宽度"+SCALE_DEFAULT_MAX_SIZE+",源图片地址:"+imageSrcPath);
return imageSrcPath;
}
if(height>SCALE_DEFAULT_MAX_SIZE){
log.warn("图片没有处理直接返回,原因:目标图片高度不能超过最大默认高度"+SCALE_DEFAULT_MAX_SIZE+",源图片地址:"+imageSrcPath);
return imageSrcPath;
}
if(imageSrcPath.indexOf(".")==-1){
log.warn("图片没有处理直接返回,原因:不能识别源图片类型,源图片地址:"+imageSrcPath);
return imageSrcPath;
}
if(!existFile(imageSrcPath, true)){
log.warn("图片没有处理直接返回,原因:源图片不存在,源图片地址:"+imageSrcPath);
return imageSrcPath;
}
BufferedImage image=null;
try {
image = Simapi.read(imageSrcPath);
} catch (IOException e1) {
log.error(e1);
e1.printStackTrace();
}
return resize(image, width, height, imageSrcPath, imageType, conversionFlag);
}
/**
* 按图片比例缩放图片
* @param image 图片缓存
* @param m_Width 缩放最大宽度(为0时,不限制)
* @param m_Height 缩放最大高度(为0时,不限制)
* @param imageSrcPath 源图片地址
* @param imageType 目标图片类型
* @param conversionFlag 是否放大
* @return 目标图片路径
private static String resize(BufferedImage image, int m_Width, int m_Height, String imageSrcPath,
String imageType, boolean conversionFlag){
image=resize(image, m_Width, m_Height, conversionFlag);
// use default render mode and quality
RenderSettings renderSettings=new RenderSettings(Simapi.RENDER_QUALITY);
// set max blur size
renderSettings.setMaximumBlurSize(SCALE_DEFAULT_MAX_BLUR_SIZE);
// new create the scaler
Simapi scaler = new Simapi(renderSettings);
// target image path
String imageTarget = buildTargetImageFilePath(imageSrcPath, image.getWidth(), image.getHeight(), imageType);
if(existFile(imageTarget, false)){
log.warn("图片没有处理直接返回,原因:目标图片路径存在文件");
return imageTarget;
try {
scaler.write(image, imageTarget, imageType);
} catch (IOException e) {
log.error(e);
e.printStackTrace();
}
return imageTarget;
* 按图片比例缩放图片
* @param image 图片缓存
* @param m_Width 缩放最大宽度(为0时,不限制)
* @param m_Height 缩放最大高度(为0时,不限制)
* @param conversionFlag 是否放大
* @return
*/
private static BufferedImage resize(BufferedImage image, int m_Width, int m_Height, boolean conversionFlag){
int i_w=0;
int i_h=0;
if(m_Width>0&&m_Height==0){
i_w=m_Width<SCALE_DEFAULT_MAX_SIZE?m_Width:SCALE_DEFAULT_MAX_SIZE;
i_h=image.getHeight()*i_w/image.getWidth();
}else if(m_Width==0&&m_Height>0){
i_h=m_Height<SCALE_DEFAULT_MAX_SIZE?m_Height:SCALE_DEFAULT_MAX_SIZE;
i_w=image.getWidth()*i_h/image.getHeight();
}else if(m_Width>0&&m_Height>0){
int i_w_w=m_Width<SCALE_DEFAULT_MAX_SIZE?m_Width:SCALE_DEFAULT_MAX_SIZE;
int i_h_w=image.getHeight()*i_w_w/image.getWidth();
int i_h_h=m_Height<SCALE_DEFAULT_MAX_SIZE?m_Height:SCALE_DEFAULT_MAX_SIZE;
int i_w_h=image.getWidth()*i_h_h/image.getHeight();
if(i_w_w>i_w_h){
i_w=i_w_h;
i_h=i_h_h;
}else{
i_w=i_w_w;
i_h=i_h_w;
}
}else{
i_w=image.getWidth();
i_h=image.getHeight();
if(i_w>SCALE_DEFAULT_MAX_SIZE||i_h>SCALE_DEFAULT_MAX_SIZE){
return resize(image, SCALE_DEFAULT_MAX_SIZE, SCALE_DEFAULT_MAX_SIZE, conversionFlag);
}else{
return image;
return new Simapi().resize(image, i_w, i_h, true, conversionFlag);*
* 判断是否存在文件(含目录)
* @param fp 文件路径
* @param ignoreDir 忽略目录
* @return 是否存在
*/
private static boolean existFile(String fp, boolean ignoreDir){
File f=new File(fp);
if(f.exists()&&(f.isFile()||(!ignoreDir)&&f.isDirectory())){
return true;
}else{
return false;
}
}
/**
* 根据源图片路径创建目标图片路径
* @param srcfilepath 源图片路径
* @param width 目标图片宽度
* @param height 目标图片高度
* @param imageType 目标图片类型
* @return 目标图片路径
*/
private static String buildTargetImageFilePath(String srcfilepath, int width, int height, String imageType){
String path;
if(srcfilepath.indexOf(".")>-1){
path = srcfilepath.substring(0,srcfilepath.lastIndexOf("."))+"W"+String.valueOf(width)+"H"+String.valueOf(height)+"."+imageType;
}else{
path = srcfilepath+"W"+String.valueOf(width)+"H"+String.valueOf(height)+"."+imageType;
}
return filterImagePath(path);
private static String filterImagePath(String srcPath){
return srcPath.replaceAll("[%?&=#]", "");
public static void main(String[] args) {
try {
log.info(ImageUtil.showImageFromMiddleCut("D:\\My Documents\\图片收藏\\top.jpg", 300, 400, true));
// log.info(ImageUtil.showImageFromMiddleCut("D:\\我的文档\\My Documents\\图片收藏\\无标题.bmp", 300, 400, true));
// log.info(ImageUtil.showImageFromMiddleCut("D:\\我的文档\\My Documents\\图片收藏\\dede7d10eff23c1c213f2e25.jpg", 300, 400, true));
// log.info(ImageUtil.showImageFromMiddleCut("D:\\我的文档\\My Documents\\图片收藏\\wm001_014.png", 300, 400, true));
log.info(ImageUtil.resize("D:\\My Documents\\图片收藏\\top.jpg", 300, 400, true));
// log.info(ImageUtil.resize("D:\\我的文档\\My Documents\\图片收藏\\无标题.bmp", 300, 400, true));
// log.info(ImageUtil.resize("D:\\我的文档\\My Documents\\图片收藏\\dede7d10eff23c1c213f2e25.jpg", 300, 400, true));
// log.info(ImageUtil.resize("D:\\我的文档\\My Documents\\图片收藏\\wm001_014.png", 300, 400, true));
} catch (Exception e) {
log.error(e);
// TODO Auto-generated catch block
e.printStackTrace();
}