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; } }
非常实用的图像处理功能,希望大家能够喜欢。