Java图像处理工具类
本工具类的功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
packagenet.kitbox.util;
importjava.awt.AlphaComposite;
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Graphics;
importjava.awt.Graphics2D;
importjava.awt.Image;
importjava.awt.RenderingHints;
importjava.awt.Toolkit;
importjava.awt.color.ColorSpace;
importjava.awt.image.BufferedImage;
importjava.awt.image.ColorConvertOp;
importjava.awt.image.CropImageFilter;
importjava.awt.image.FilteredImageSource;
importjava.awt.image.ImageFilter;
importjava.awt.image.ImagingOpException;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjavax.imageio.ImageIO;
/**
*author:lldy
*time:2012-5-6下午6:37:18
*图片处理工具类:<br>
*功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
*/
publicclassImageUtils{
/**
*相对于图片的位置
*/
privatestaticfinalintPOSITION_UPPERLEFT=0;
privatestaticfinalintPOSITION_UPPERRIGHT=10;
privatestaticfinalintPOSITION_LOWERLEFT=1;
privatestaticfinalintPOSITION_LOWERRIGHT=11;
/**
*几种常见的图片格式
*/
publicstaticStringIMAGE_TYPE_GIF="gif";//图形交换格式
publicstaticStringIMAGE_TYPE_JPG="jpg";//联合照片专家组
publicstaticStringIMAGE_TYPE_JPEG="jpeg";//联合照片专家组
publicstaticStringIMAGE_TYPE_BMP="bmp";//英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式
publicstaticStringIMAGE_TYPE_PNG="png";//可移植网络图形
privatestaticImageUtilsinstance;
privateImageUtils(){
instance=this;
}
/**
*获取实例
*@return
*/
publicstaticImageUtilsgetInstance(){
if(instance==null){
instance=newImageUtils();
}
returninstance;
}
public BufferedImageimage2BufferedImage(Imageimage){
System.out.println(image.getWidth(null));
System.out.println(image.getHeight(null));
BufferedImagebufferedImage=newBufferedImage(image.getWidth(null),image.getHeight(null),BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=bufferedImage.createGraphics();
g.drawImage(image,null,null);
g.dispose();
System.out.println(bufferedImage.getWidth());
System.out.println(bufferedImage.getHeight());
returnbufferedImage;
}
/**
*缩放并转换格式后保存
*@paramsrcPath源路径
*@paramdestPath目标路径
*@paramwidth:目标宽
*@paramheight:目标高
*@paramformat:文件格式
*@return
*/
publicstaticbooleanscaleToFile(StringsrcPath,StringdestPath,intwidth, intheight,Stringformat){
booleanflag=false;
try{
Filefile=newFile(srcPath);
FiledestFile=newFile(destPath);
if(!destFile.getParentFile().exists()){
destFile.getParentFile().mkdir();
}
BufferedImagesrc=ImageIO.read(file);//读入文件
Imageimage=src.getScaledInstance(width,height,Image.SCALE_DEFAULT);
BufferedImagetag=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphicsg=tag.getGraphics();
g.drawImage(image,0,0,null);//绘制缩小后的图
g.dispose();
flag=ImageIO.write(tag,format,newFileOutputStream(destFile));//输出到文件流
}catch(IOExceptione){
e.printStackTrace();
}
returnflag;
}
/**
*缩放Image,此方法返回源图像按百分比缩放后的图像
*@paraminputImage
*@parampercentage百分比允许的输入0<percentage<10000
*@return
*/
publicstaticBufferedImagescaleByPercentage(BufferedImageinputImage,intpercentage){
//允许百分比
if(0>percentage||percentage>10000){
thrownewImagingOpException("Error::不合法的参数:percentage->"+percentage+",percentage应该大于0~小于10000");
}
//获取原始图像透明度类型
inttype=inputImage.getColorModel().getTransparency();
//获取目标图像大小
intw=inputImage.getWidth()*percentage;
inth=inputImage.getHeight()*percentage;
//开启抗锯齿
RenderingHintsrenderingHints=newRenderingHints(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_ANTIALIAS_ON);
//使用高质量压缩
renderingHints.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_RENDER_QUALITY);
BufferedImageimg=newBufferedImage(w,h,type);
Graphics2Dgraphics2d=img.createGraphics();
graphics2d.setRenderingHints(renderingHints);
graphics2d.drawImage(inputImage,0,0,w,h,0,0,inputImage
.getWidth(),inputImage.getHeight(),null);
graphics2d.dispose();
returnimg;
/*此代码将返回Image类型
returninputImage.getScaledInstance(inputImage.getWidth()*percentage,
inputImage.getHeight()*percentage,Image.SCALE_SMOOTH);
*/
}
/**
*缩放Image,此方法返回源图像按给定最大宽度限制下按比例缩放后的图像
*@paraminputImage
*@parammaxWidth:压缩后允许的最大宽度
*@parammaxHeight:压缩后允许的最大高度
*@throwsjava.io.IOException
*return
*/
publicstaticBufferedImagescaleByPixelRate(BufferedImageinputImage,intmaxWidth,intmaxHeight)throwsException{
//获取原始图像透明度类型
inttype=inputImage.getColorModel().getTransparency();
intwidth=inputImage.getWidth();
intheight=inputImage.getHeight();
intnewWidth=maxWidth;
intnewHeight=maxHeight;
//如果指定最大宽度超过比例
if(width*maxHeight<height*maxWidth){
newWidth=(int)(newHeight*width/height);
}
//如果指定最大高度超过比例
if(width*maxHeight>height*maxWidth){
newHeight=(int)(newWidth*height/width);
}
//开启抗锯齿
RenderingHintsrenderingHints=newRenderingHints(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_ANTIALIAS_ON);
//使用高质量压缩
renderingHints.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_RENDER_QUALITY);
BufferedImageimg=newBufferedImage(newWidth,newHeight,type);
Graphics2Dgraphics2d=img.createGraphics();
graphics2d.setRenderingHints(renderingHints);
graphics2d.drawImage(inputImage,0,0,newWidth,newHeight,0,0,width,height,null);
graphics2d.dispose();
returnimg;
}
/**
*缩放Image,此方法返回源图像按给定宽度、高度限制下缩放后的图像
*@paraminputImage
*@parammaxWidth:压缩后宽度
*@parammaxHeight:压缩后高度
*@throwsjava.io.IOException
*return
*/
publicstaticBufferedImagescaleByPixel(BufferedImageinputImage,intnewWidth,intnewHeight)throwsException{
//获取原始图像透明度类型
inttype=inputImage.getColorModel().getTransparency();
intwidth=inputImage.getWidth();
intheight=inputImage.getHeight();
//开启抗锯齿
RenderingHintsrenderingHints=newRenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//使用高质量压缩
renderingHints.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
BufferedImageimg=newBufferedImage(newWidth,newHeight,type);
Graphics2Dgraphics2d=img.createGraphics();
graphics2d.setRenderingHints(renderingHints);
graphics2d.drawImage(inputImage,0,0,newWidth,newHeight,0,0,width,height,null);
graphics2d.dispose();
returnimg;
}
/**
*切割图像,返回指定范围的图像
*@paraminputImage
*@paramx起点横坐标
*@paramy起点纵坐标
*@paramwidth切割图片宽度:如果宽度超出图片,将改为图片自x剩余宽度
*@paramheight切割图片高度:如果高度超出图片,将改为图片自y剩余高度
*@paramfill指定目标图像大小超出时是否补白,如果true,则表示补白;false表示不补白,此时将重置目标图像大小
*@return
*/
publicstaticBufferedImagecut(BufferedImageinputImage,intx,inty,intwidth,intheight,booleanfill){
//获取原始图像透明度类型
inttype=inputImage.getColorModel().getTransparency();
intw=inputImage.getWidth();
inth=inputImage.getHeight();
intendx=x+width;
intendy=y+height;
if(x>w)
thrownewImagingOpException("起点横坐标超出源图像范围");
if(y>h)
thrownewImagingOpException("起点纵坐标超出源图像范围");
BufferedImageimg;
//补白
if(fill){
img=newBufferedImage(width,height,type);
//宽度超出限制
if((w-x)<width){
width=w-x;
endx=w;
}
//高度超出限制
if((h-y)<height){
height=h-y;
endy=h;
}
//不补
}else{
//宽度超出限制
if((w-x)<width){
width=w-x;
endx=w;
}
//高度超出限制
if((h-y)<height){
height=h-y;
endy=h;
}
img=newBufferedImage(width,height,type);
}
//开启抗锯齿
RenderingHintsrenderingHints=newRenderingHints(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_ANTIALIAS_ON);
//使用高质量压缩
renderingHints.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_RENDER_QUALITY);
Graphics2Dgraphics2d=img.createGraphics();
graphics2d.setRenderingHints(renderingHints);
graphics2d.drawImage(inputImage,0,0,width,height,x,y,endx,endy,null);
graphics2d.dispose();
returnimg;
}
/**
*切割图像,返回指定起点位置指定大小图像
*@paraminputImage
*@paramstartPoint起点位置:左上:0、右上:10、左下:1、右下:11
*@paramwidth切割图片宽度
*@paramheight切割图片高度
*@paramfill指定目标图像大小超出时是否补白,如果true,则表示补白;false表示不补白,此时将重置目标图像大小
*@return
*/
publicstaticBufferedImagecut(BufferedImageinputImage,intstartPoint,intwidth,intheight,booleanfill){
//获取原始图像透明度类型
inttype=inputImage.getColorModel().getTransparency();
intw=inputImage.getWidth();
inth=inputImage.getHeight();
BufferedImageimg;
//补白
if(fill){
img=newBufferedImage(width,height,type);
if(width>w)
width=w;
if(height>h)
height=h;
//不补
}else{
if(width>w)
width=w;
if(height>h)
height=h;
img=newBufferedImage(width,height,type);
}
//开启抗锯齿
RenderingHintsrenderingHints=newRenderingHints(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_ANTIALIAS_ON);
//使用高质量压缩
renderingHints.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_RENDER_QUALITY);
Graphics2Dgraphics2d=img.createGraphics();
graphics2d.setRenderingHints(renderingHints);
switch(startPoint){
//右上
casePOSITION_UPPERRIGHT:
graphics2d.drawImage(inputImage,w-width,0,w,height,0,0,width,height,null);
break;
//左下
casePOSITION_LOWERLEFT:
graphics2d.drawImage(inputImage,0,h-height,width,h,0,0,width,height,null);
break;
//右下
casePOSITION_LOWERRIGHT:
graphics2d.drawImage(inputImage,w-width,h-height,w,h,0,0,width,height,null);
break;
//默认左上
casePOSITION_UPPERLEFT:
default:
graphics2d.drawImage(inputImage,0,0,width,height,0,0,width,height,null);
}
graphics2d.dispose();
returnimg;
}
/**
*以指定角度旋转图片:使用正角度theta进行旋转,可将正x轴上的点转向正y轴。
*@paraminputImage
*@paramdegree角度:以度数为单位
*@return
*/
publicstaticBufferedImagerotateImage(finalBufferedImageinputImage,
finalintdegree){
intw=inputImage.getWidth();
inth=inputImage.getHeight();
inttype=inputImage.getColorModel().getTransparency();
BufferedImageimg=newBufferedImage(w,h,type);
Graphics2Dgraphics2d=img.createGraphics();
//开启抗锯齿
RenderingHintsrenderingHints=newRenderingHints(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_ANTIALIAS_ON);
//使用高质量压缩
renderingHints.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_RENDER_QUALITY);
graphics2d.setRenderingHints(renderingHints);
graphics2d.rotate(Math.toRadians(degree),w/2,h/2);
graphics2d.drawImage(inputImage,0,0,null);
graphics2d.dispose();
returnimg;
}
/**
*水平翻转图像
*
*@parambufferedimage目标图像
*@return
*/
publicstaticBufferedImageflipHorizontalImage(finalBufferedImageinputImage){
intw=inputImage.getWidth();
inth=inputImage.getHeight();
BufferedImageimg;
Graphics2Dgraphics2d;
(graphics2d=(img=newBufferedImage(w,h,inputImage
.getColorModel().getTransparency())).createGraphics())
.drawImage(inputImage,0,0,w,h,w,0,0,h,null);
graphics2d.dispose();
returnimg;
}
/**
*竖直翻转图像
*
*@parambufferedimage目标图像
*@return
*/
publicstaticBufferedImageflipVerticalImage(finalBufferedImageinputImage){
intw=inputImage.getWidth();
inth=inputImage.getHeight();
BufferedImageimg;
Graphics2Dgraphics2d;
(graphics2d=(img=newBufferedImage(w,h,inputImage
.getColorModel().getTransparency())).createGraphics())
.drawImage(inputImage,0,0,w,h,0,h,w,0,null);
graphics2d.dispose();
returnimg;
}
/**
*图片水印
*
*@paraminputImage
* 待处理图像
*@parammarkImage
* 水印图像
*@paramx
* 水印位于图片左上角的x坐标值
*@paramy
* 水印位于图片左上角的y坐标值
*@paramalpha
* 水印透明度0.1f~1.0f
**/
publicstaticBufferedImagewaterMark(BufferedImageinputImage,BufferedImagemarkImage,intx,inty,
floatalpha){
BufferedImageimage=newBufferedImage(inputImage.getWidth(),inputImage
.getHeight(),BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=image.createGraphics();
g.drawImage(inputImage,0,0,null);
//加载水印图像
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
g.drawImage(markImage,x,y,null);
g.dispose();
returnimage;
}
/**
*文字水印
*
*@paraminputImage
* 待处理图像
*@paramtext
* 水印文字
*@paramfont
* 水印字体信息
*@paramcolor
* 水印字体颜色
*@paramx
* 水印位于图片左上角的x坐标值
*@paramy
* 水印位于图片左上角的y坐标值
*@paramalpha
* 水印透明度0.1f~1.0f
*/
publicstaticBufferedImagetextMark(BufferedImageinputImage,Stringtext,Fontfont,
Colorcolor,intx,inty,floatalpha){
Fontdfont=(font==null)?newFont("宋体",20,13):font;
BufferedImageimage=newBufferedImage(inputImage.getWidth(),inputImage
.getHeight(),BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=image.createGraphics();
g.drawImage(inputImage,0,0,null);
g.setColor(color);
g.setFont(dfont);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
g.drawString(text,x,y);
g.dispose();
returnimage;
}
/**
*图像彩色转黑白色
*@paraminputImage
*@return转换后的BufferedImage
*/
publicfinalstaticBufferedImagetoGray(BufferedImageinputImage)
{
ColorSpacecs=ColorSpace.getInstance(ColorSpace.CS_GRAY);
//对源BufferedImage进行颜色转换。如果目标图像为null,
//则根据适当的ColorModel创建BufferedImage。
ColorConvertOpop=newColorConvertOp(cs,null);
returnop.filter(inputImage,null);
}
/**
*图像彩色转为黑白
*@paramsrcImageFile
* 源图像地址
*@paramdestImageFile
* 目标图像地址
*@paramformatType
* 目标图像格式:如果formatType为null;将默认转换为PNG
*/
publicfinalstaticvoidtoGray(StringsrcImageFile,StringdestImageFile,StringformatType)
{
try
{
BufferedImagesrc=ImageIO.read(newFile(srcImageFile));
ColorSpacecs=ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOpop=newColorConvertOp(cs,null);
src=op.filter(src,null);
//如果formatType为null;将默认转换为PNG
if(formatType==null){
formatType="PNG";
}
ImageIO.write(src,formatType,newFile(destImageFile));
}catch(IOExceptione)
{
e.printStackTrace();
}
}
/**
*图像类型转换:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG
*
*@paraminputImage
* 源图像地址
*@paramformatType
* 包含格式非正式名称的String:如JPG、JPEG、GIF等
*@paramdestImageFile
* 目标图像地址
*/
publicfinalstaticvoidconvert(BufferedImageinputImage,StringformatType,StringdestImageFile)
{
try
{
ImageIO.write(inputImage,formatType,newFile(destImageFile));
}catch(Exceptione)
{
e.printStackTrace();
}
}
/**
*图像切割(指定切片的行数和列数)
*
*@paramsrcImageFile
* 源图像地址
*@paramdestDir
* 切片目标文件夹
*@paramformatType
* 目标格式
*@paramrows
* 目标切片行数。默认2,必须是范围[1,20]之内
*@paramcols
* 目标切片列数。默认2,必须是范围[1,20]之内
*/
publicfinalstaticvoidcut(BufferedImageinputImage,StringdestDir,
StringformatType,introws,intcols)
{
try
{
if(rows<=0||rows>20)
rows=2;//切片行数
if(cols<=0||cols>20)
cols=2;//切片列数
//读取源图像
//BufferedImagebi=ImageIO.read(newFile(srcImageFile));
intw=inputImage.getHeight();//源图宽度
inth=inputImage.getWidth();//源图高度
if(w>0&&h>0)
{
Imageimg;
ImageFiltercropFilter;
Imageimage=inputImage.getScaledInstance(w,h,
Image.SCALE_DEFAULT);
intdestWidth=w;//每张切片的宽度
intdestHeight=h;//每张切片的高度
//计算切片的宽度和高度
if(w%cols==0)
{
destWidth=w/cols;
}else
{
destWidth=(int)Math.floor(w/cols)+1;
}
if(h%rows==0)
{
destHeight=h/rows;
}else
{
destHeight=(int)Math.floor(h/rows)+1;
}
//循环建立切片
//改进的想法:是否可用多线程加快切割速度
for(inti=0;i<rows;i++)
{
for(intj=0;j<cols;j++)
{
//四个参数分别为图像起点坐标和宽高
//即:CropImageFilter(intx,inty,intwidth,intheight)
cropFilter=newCropImageFilter(j*destWidth,i
*destHeight,destWidth,destHeight);
img=Toolkit.getDefaultToolkit().createImage(
newFilteredImageSource(image.getSource(),
cropFilter));
BufferedImagetag=newBufferedImage(destWidth,
destHeight,BufferedImage.TYPE_INT_ARGB);
Graphicsg=tag.getGraphics();
g.drawImage(img,0,0,null);//绘制缩小后的图
g.dispose();
//输出为文件
ImageIO.write(tag,formatType,newFile(destDir+"_r"+i
+"_c"+j+"."+formatType.toLowerCase()));
}
}
}
}catch(Exceptione)
{
e.printStackTrace();
}
}
/**
*给图片添加文字水印
*
*@parampressText
* 水印文字
*@paramsrcImageFile
* 源图像地址
*@paramdestImageFile
* 目标图像地址
*@paramfontName
* 水印的字体名称
*@paramfontStyle
* 水印的字体样式
*@paramcolor
* 水印的字体颜色
*@paramfontSize
* 水印的字体大小
*@paramx
* 修正值
*@paramy
* 修正值
*@paramalpha
* 透明度:alpha必须是范围[0.0,1.0]之内(包含边界值)的一个浮点数字
*@paramformatType
* 目标格式
*/
publicfinalstaticvoidpressText(StringpressText,StringsrcImageFile,
StringdestImageFile,StringfontName,intfontStyle,Colorcolor,
intfontSize,intx,inty,floatalpha,StringformatType)
{
try
{
Fileimg=newFile(srcImageFile);
Imagesrc=ImageIO.read(img);
intwidth=src.getWidth(null);
intheight=src.getHeight(null);
BufferedImageimage=newBufferedImage(width,height,
BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=image.createGraphics();
g.drawImage(src,0,0,width,height,null);
g.setColor(color);
g.setFont(newFont(fontName,fontStyle,fontSize));
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
//在指定坐标绘制水印文字
g.drawString(pressText,(width-(getLength(pressText)*fontSize))
/2+x,(height-fontSize)/2+y);
g.dispose();
ImageIO.write((BufferedImage)image,formatType,
newFile(destImageFile));//输出到文件流
}catch(Exceptione)
{
e.printStackTrace();
}
}
/**
*给图片添加图片水印
*
*@parampressImg
* 水印图片
*@paramsrcImageFile
* 源图像地址
*@paramdestImageFile
* 目标图像地址
*@paramx
* 修正值。默认在中间
*@paramy
* 修正值。默认在中间
*@paramalpha
* 透明度:alpha必须是范围[0.0,1.0]之内(包含边界值)的一个浮点数字
*@paramformatType
* 目标格式
*/
publicfinalstaticvoidpressImage(StringpressImg,StringsrcImageFile,
StringdestImageFile,intx,inty,floatalpha,StringformatType)
{
try
{
Fileimg=newFile(srcImageFile);
Imagesrc=ImageIO.read(img);
intwideth=src.getWidth(null);
intheight=src.getHeight(null);
BufferedImageimage=newBufferedImage(wideth,height,
BufferedImage.TYPE_INT_ARGB);
Graphics2Dg=image.createGraphics();
g.drawImage(src,0,0,wideth,height,null);
//水印文件
Imagesrc_biao=ImageIO.read(newFile(pressImg));
intwideth_biao=src_biao.getWidth(null);
intheight_biao=src_biao.getHeight(null);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
g.drawImage(src_biao,(wideth-wideth_biao)/2,
(height-height_biao)/2,wideth_biao,height_biao,null);
//水印文件结束
g.dispose();
ImageIO.write((BufferedImage)image,formatType,
newFile(destImageFile));
}catch(Exceptione)
{
e.printStackTrace();
}
}
/**
*计算text的长度(一个中文算两个字符)
*
*@paramtext
*@return
*/
publicfinalstaticintgetLength(Stringtext)
{
intlength=0;
for(inti=0;i<text.length();i++)
{
if(newString(text.charAt(i)+"").getBytes().length>1)
{
length+=2;
}else
{
length+=1;
}
}
returnlength/2;
}
}
非常实用的图像处理功能,希望大家能够喜欢。