Java图像处理工具类
程序员文章站
2024-03-02 23:43:28
本工具类的功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
复制代码 代码如下:
package net.kitbox.util;
impor...
本工具类的功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
复制代码 代码如下:
package net.kitbox.util;
import java.awt.alphacomposite;
import java.awt.color;
import java.awt.font;
import java.awt.graphics;
import java.awt.graphics2d;
import java.awt.image;
import java.awt.renderinghints;
import java.awt.toolkit;
import java.awt.color.colorspace;
import java.awt.image.bufferedimage;
import java.awt.image.colorconvertop;
import java.awt.image.cropimagefilter;
import java.awt.image.filteredimagesource;
import java.awt.image.imagefilter;
import java.awt.image.imagingopexception;
import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import javax.imageio.imageio;
/**
* author:lldy
* time:2012-5-6下午6:37:18
* 图片处理工具类:<br>
* 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
*/
public class imageutils {
/**
* 相对于图片的位置
*/
private static final int position_upperleft=0;
private static final int position_upperright=10;
private static final int position_lowerleft=1;
private static final int position_lowerright=11;
/**
* 几种常见的图片格式
*/
public static string image_type_gif = "gif";// 图形交换格式
public static string image_type_jpg = "jpg";// 联合照片专家组
public static string image_type_jpeg = "jpeg";// 联合照片专家组
public static string image_type_bmp = "bmp";// 英文bitmap(位图)的简写,它是windows操作系统中的标准图像文件格式
public static string image_type_png = "png";// 可移植网络图形
private static imageutils instance;
private imageutils() {
instance = this;
}
/**
* 获取实例
* @return
*/
public static imageutils getinstance() {
if (instance == null) {
instance = new imageutils();
}
return instance;
}
public bufferedimage image2bufferedimage(image image){
system.out.println(image.getwidth(null));
system.out.println(image.getheight(null));
bufferedimage bufferedimage = new bufferedimage(image.getwidth(null), image.getheight(null), bufferedimage.type_int_argb);
graphics2d g = bufferedimage.creategraphics();
g.drawimage(image, null, null);
g.dispose();
system.out.println(bufferedimage.getwidth());
system.out.println(bufferedimage.getheight());
return bufferedimage;
}
/**
* 缩放并转换格式后保存
* @param srcpath源路径
* @param destpath目标路径
* @param width:目标宽
* @param height:目标高
* @param format:文件格式
* @return
*/
public static boolean scaletofile(string srcpath, string destpath, int width, int height,string format) {
boolean flag = false;
try {
file file = new file(srcpath);
file destfile = new file(destpath);
if (!destfile.getparentfile().exists()) {
destfile.getparentfile().mkdir();
}
bufferedimage src = imageio.read(file); // 读入文件
image image = src.getscaledinstance(width, height, image.scale_default);
bufferedimage tag = new bufferedimage(width, height, bufferedimage.type_int_rgb);
graphics g = tag.getgraphics();
g.drawimage(image, 0, 0, null); // 绘制缩小后的图
g.dispose();
flag = imageio.write(tag, format, new fileoutputstream(destfile));// 输出到文件流
} catch (ioexception e) {
e.printstacktrace();
}
return flag;
}
/**
* 缩放image,此方法返回源图像按百分比缩放后的图像
* @param inputimage
* @param percentage 百分比 允许的输入0<percentage<10000
* @return
*/
public static bufferedimage scalebypercentage(bufferedimage inputimage,int percentage){
//允许百分比
if(0>percentage||percentage>10000){
throw new imagingopexception("error::不合法的参数:percentage->"+percentage+",percentage应该大于0~小于10000");
}
//获取原始图像透明度类型
int type = inputimage.getcolormodel().gettransparency();
//获取目标图像大小
int w=inputimage.getwidth()*percentage;
int h=inputimage.getheight()*percentage;
//开启抗锯齿
renderinghints renderinghints=new renderinghints(renderinghints.key_interpolation,
renderinghints.value_antialias_on);
//使用高质量压缩
renderinghints.put(renderinghints.key_interpolation, renderinghints.value_render_quality);
bufferedimage img = new bufferedimage(w, h, type);
graphics2d graphics2d =img.creategraphics();
graphics2d.setrenderinghints(renderinghints);
graphics2d.drawimage(inputimage, 0, 0, w, h, 0, 0, inputimage
.getwidth(), inputimage.getheight(), null);
graphics2d.dispose();
return img;
/*此代码将返回image类型
return inputimage.getscaledinstance(inputimage.getwidth()*percentage,
inputimage.getheight()*percentage, image.scale_smooth);
*/
}
/**
* 缩放image,此方法返回源图像按给定最大宽度限制下按比例缩放后的图像
* @param inputimage
* @param maxwidth:压缩后允许的最大宽度
* @param maxheight:压缩后允许的最大高度
* @throws java.io.ioexception
* return
*/
public static bufferedimage scalebypixelrate(bufferedimage inputimage, int maxwidth, int maxheight) throws exception {
//获取原始图像透明度类型
int type = inputimage.getcolormodel().gettransparency();
int width = inputimage.getwidth();
int height = inputimage.getheight();
int newwidth = maxwidth;
int newheight =maxheight;
//如果指定最大宽度超过比例
if(width*maxheight<height*maxwidth){
newwidth=(int)(newheight*width/height) ;
}
//如果指定最大高度超过比例
if(width*maxheight>height*maxwidth){
newheight=(int)(newwidth*height/width);
}
//开启抗锯齿
renderinghints renderinghints=new renderinghints(renderinghints.key_interpolation,
renderinghints.value_antialias_on);
//使用高质量压缩
renderinghints.put(renderinghints.key_interpolation, renderinghints.value_render_quality);
bufferedimage img = new bufferedimage(newwidth, newheight, type);
graphics2d graphics2d =img.creategraphics();
graphics2d.setrenderinghints(renderinghints);
graphics2d.drawimage(inputimage, 0, 0, newwidth, newheight, 0, 0, width, height, null);
graphics2d.dispose();
return img;
}
/**
* 缩放image,此方法返回源图像按给定宽度、高度限制下缩放后的图像
* @param inputimage
* @param maxwidth:压缩后宽度
* @param maxheight:压缩后高度
* @throws java.io.ioexception
* return
*/
public static bufferedimage scalebypixel(bufferedimage inputimage, int newwidth, int newheight) throws exception {
//获取原始图像透明度类型
int type = inputimage.getcolormodel().gettransparency();
int width = inputimage.getwidth();
int height = inputimage.getheight();
//开启抗锯齿
renderinghints renderinghints=new renderinghints(renderinghints.key_antialiasing,
renderinghints.value_antialias_on);
//使用高质量压缩
renderinghints.put(renderinghints.key_rendering, renderinghints.value_render_quality);
bufferedimage img = new bufferedimage(newwidth, newheight, type);
graphics2d graphics2d =img.creategraphics();
graphics2d.setrenderinghints(renderinghints);
graphics2d.drawimage(inputimage, 0, 0, newwidth, newheight, 0, 0, width, height, null);
graphics2d.dispose();
return img;
}
/**
* 切割图像,返回指定范围的图像
* @param inputimage
* @param x 起点横坐标
* @param y 起点纵坐标
* @param width 切割图片宽度:如果宽度超出图片,将改为图片自x剩余宽度
* @param height 切割图片高度:如果高度超出图片,将改为图片自y剩余高度
* @param fill 指定目标图像大小超出时是否补白,如果true,则表示补白;false表示不补白,此时将重置目标图像大小
* @return
*/
public static bufferedimage cut(bufferedimage inputimage,int x,int y,int width,int height,boolean fill){
//获取原始图像透明度类型
int type = inputimage.getcolormodel().gettransparency();
int w = inputimage.getwidth();
int h = inputimage.getheight();
int endx=x+width;
int endy=y+height;
if(x>w)
throw new imagingopexception("起点横坐标超出源图像范围");
if(y>h)
throw new imagingopexception("起点纵坐标超出源图像范围");
bufferedimage img;
//补白
if(fill){
img = new bufferedimage(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 = new bufferedimage(width, height, type);
}
//开启抗锯齿
renderinghints renderinghints=new renderinghints(renderinghints.key_interpolation,
renderinghints.value_antialias_on);
//使用高质量压缩
renderinghints.put(renderinghints.key_interpolation, renderinghints.value_render_quality);
graphics2d graphics2d =img.creategraphics();
graphics2d.setrenderinghints(renderinghints);
graphics2d.drawimage(inputimage, 0, 0, width, height, x, y, endx, endy, null);
graphics2d.dispose();
return img;
}
/**
* 切割图像,返回指定起点位置指定大小图像
* @param inputimage
* @param startpoint 起点位置:左上:0、右上:10、左下:1、右下:11
* @param width 切割图片宽度
* @param height 切割图片高度
* @param fill 指定目标图像大小超出时是否补白,如果true,则表示补白;false表示不补白,此时将重置目标图像大小
* @return
*/
public static bufferedimage cut(bufferedimage inputimage,int startpoint,int width,int height,boolean fill){
//获取原始图像透明度类型
int type = inputimage.getcolormodel().gettransparency();
int w = inputimage.getwidth();
int h = inputimage.getheight();
bufferedimage img;
//补白
if(fill){
img = new bufferedimage(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 = new bufferedimage(width, height, type);
}
//开启抗锯齿
renderinghints renderinghints=new renderinghints(renderinghints.key_interpolation,
renderinghints.value_antialias_on);
//使用高质量压缩
renderinghints.put(renderinghints.key_interpolation, renderinghints.value_render_quality);
graphics2d graphics2d =img.creategraphics();
graphics2d.setrenderinghints(renderinghints);
switch(startpoint){
//右上
case position_upperright:
graphics2d.drawimage(inputimage, w-width, 0, w, height, 0, 0, width, height, null);
break;
//左下
case position_lowerleft:
graphics2d.drawimage(inputimage, 0, h-height, width, h, 0, 0, width, height, null);
break;
//右下
case position_lowerright:
graphics2d.drawimage(inputimage, w-width, h-height, w, h, 0, 0, width, height, null);
break;
//默认左上
case position_upperleft:
default:
graphics2d.drawimage(inputimage, 0, 0, width, height, 0, 0, width, height, null);
}
graphics2d.dispose();
return img;
}
/**
* 以指定角度旋转图片:使用正角度 theta 进行旋转,可将正 x 轴上的点转向正 y 轴。
* @param inputimage
* @param degree 角度:以度数为单位
* @return
*/
public static bufferedimage rotateimage(final bufferedimage inputimage,
final int degree) {
int w = inputimage.getwidth();
int h = inputimage.getheight();
int type = inputimage.getcolormodel().gettransparency();
bufferedimage img=new bufferedimage(w, h, type);
graphics2d graphics2d =img.creategraphics();
//开启抗锯齿
renderinghints renderinghints=new renderinghints(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();
return img;
}
/**
* 水平翻转图像
*
* @param bufferedimage 目标图像
* @return
*/
public static bufferedimage fliphorizontalimage(final bufferedimage inputimage) {
int w = inputimage.getwidth();
int h = inputimage.getheight();
bufferedimage img;
graphics2d graphics2d;
(graphics2d = (img = new bufferedimage(w, h, inputimage
.getcolormodel().gettransparency())).creategraphics())
.drawimage(inputimage, 0, 0, w, h, w, 0, 0, h, null);
graphics2d.dispose();
return img;
}
/**
* 竖直翻转图像
*
* @param bufferedimage 目标图像
* @return
*/
public static bufferedimage flipverticalimage(final bufferedimage inputimage) {
int w = inputimage.getwidth();
int h = inputimage.getheight();
bufferedimage img;
graphics2d graphics2d;
(graphics2d = (img = new bufferedimage(w, h, inputimage
.getcolormodel().gettransparency())).creategraphics())
.drawimage(inputimage, 0, 0, w, h, 0, h, w, 0, null);
graphics2d.dispose();
return img;
}
/**
* 图片水印
*
* @param inputimage
* 待处理图像
* @param markimage
* 水印图像
* @param x
* 水印位于图片左上角的 x 坐标值
* @param y
* 水印位于图片左上角的 y 坐标值
* @param alpha
* 水印透明度 0.1f ~ 1.0f
* */
public static bufferedimage watermark(bufferedimage inputimage,bufferedimage markimage, int x, int y,
float alpha) {
bufferedimage image = new bufferedimage(inputimage.getwidth(), inputimage
.getheight(), bufferedimage.type_int_argb);
graphics2d g = image.creategraphics();
g.drawimage(inputimage, 0, 0, null);
// 加载水印图像
g.setcomposite(alphacomposite.getinstance(alphacomposite.src_atop,
alpha));
g.drawimage(markimage, x, y, null);
g.dispose();
return image;
}
/**
* 文字水印
*
* @param inputimage
* 待处理图像
* @param text
* 水印文字
* @param font
* 水印字体信息
* @param color
* 水印字体颜色
* @param x
* 水印位于图片左上角的 x 坐标值
* @param y
* 水印位于图片左上角的 y 坐标值
* @param alpha
* 水印透明度 0.1f ~ 1.0f
*/
public static bufferedimage textmark(bufferedimage inputimage, string text, font font,
color color, int x, int y, float alpha) {
font dfont = (font == null) ? new font("宋体", 20, 13) : font;
bufferedimage image = new bufferedimage(inputimage.getwidth(), inputimage
.getheight(), bufferedimage.type_int_argb);
graphics2d g = 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();
return image;
}
/**
* 图像彩色转黑白色
* @param inputimage
* @return 转换后的bufferedimage
*/
public final static bufferedimage togray(bufferedimage inputimage)
{
colorspace cs = colorspace.getinstance(colorspace.cs_gray);
//对源 bufferedimage 进行颜色转换。如果目标图像为 null,
//则根据适当的 colormodel 创建 bufferedimage。
colorconvertop op = new colorconvertop(cs, null);
return op.filter(inputimage, null);
}
/**
* 图像彩色转为黑白
* @param srcimagefile
* 源图像地址
* @param destimagefile
* 目标图像地址
* @param formattype
* 目标图像格式:如果formattype为null;将默认转换为png
*/
public final static void togray(string srcimagefile, string destimagefile,string formattype)
{
try
{
bufferedimage src = imageio.read(new file(srcimagefile));
colorspace cs = colorspace.getinstance(colorspace.cs_gray);
colorconvertop op = new colorconvertop(cs, null);
src = op.filter(src, null);
//如果formattype为null;将默认转换为png
if(formattype==null){
formattype="png";
}
imageio.write(src,formattype,new file(destimagefile));
} catch (ioexception e)
{
e.printstacktrace();
}
}
/**
* 图像类型转换:gif->jpg、gif->png、png->jpg、png->gif(x)、bmp->png
*
* @param inputimage
* 源图像地址
* @param formattype
* 包含格式非正式名称的 string:如jpg、jpeg、gif等
* @param destimagefile
* 目标图像地址
*/
public final static void convert(bufferedimage inputimage, string formattype,string destimagefile)
{
try
{
imageio.write(inputimage, formattype, new file(destimagefile));
} catch (exception e)
{
e.printstacktrace();
}
}
/**
* 图像切割(指定切片的行数和列数)
*
* @param srcimagefile
* 源图像地址
* @param destdir
* 切片目标文件夹
* @param formattype
* 目标格式
* @param rows
* 目标切片行数。默认2,必须是范围 [1, 20] 之内
* @param cols
* 目标切片列数。默认2,必须是范围 [1, 20] 之内
*/
public final static void cut(bufferedimage inputimage, string destdir,
string formattype,int rows, int cols)
{
try
{
if (rows <= 0 || rows > 20)
rows = 2; // 切片行数
if (cols <= 0 || cols > 20)
cols = 2; // 切片列数
// 读取源图像
//bufferedimage bi = imageio.read(new file(srcimagefile));
int w = inputimage.getheight(); // 源图宽度
int h = inputimage.getwidth(); // 源图高度
if (w > 0 && h > 0)
{
image img;
imagefilter cropfilter;
image image = inputimage.getscaledinstance(w, h,
image.scale_default);
int destwidth = w; // 每张切片的宽度
int destheight = 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 (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
// 四个参数分别为图像起点坐标和宽高
// 即: cropimagefilter(int x,int y,int width,int height)
cropfilter = new cropimagefilter(j * destwidth, i
* destheight, destwidth, destheight);
img = toolkit.getdefaulttoolkit().createimage(
new filteredimagesource(image.getsource(),
cropfilter));
bufferedimage tag = new bufferedimage(destwidth,
destheight, bufferedimage.type_int_argb);
graphics g = tag.getgraphics();
g.drawimage(img, 0, 0, null); // 绘制缩小后的图
g.dispose();
// 输出为文件
imageio.write(tag, formattype, new file(destdir + "_r" + i
+ "_c" + j + "."+formattype.tolowercase()));
}
}
}
} catch (exception e)
{
e.printstacktrace();
}
}
/**
* 给图片添加文字水印
*
* @param presstext
* 水印文字
* @param srcimagefile
* 源图像地址
* @param destimagefile
* 目标图像地址
* @param fontname
* 水印的字体名称
* @param fontstyle
* 水印的字体样式
* @param color
* 水印的字体颜色
* @param fontsize
* 水印的字体大小
* @param x
* 修正值
* @param y
* 修正值
* @param alpha
* 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
* @param formattype
* 目标格式
*/
public final static void presstext(string presstext, string srcimagefile,
string destimagefile, string fontname, int fontstyle, color color,
int fontsize, int x, int y, float alpha,string formattype)
{
try
{
file img = new file(srcimagefile);
image src = imageio.read(img);
int width = src.getwidth(null);
int height = src.getheight(null);
bufferedimage image = new bufferedimage(width, height,
bufferedimage.type_int_argb);
graphics2d g = image.creategraphics();
g.drawimage(src, 0, 0, width, height, null);
g.setcolor(color);
g.setfont(new font(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,
new file(destimagefile));// 输出到文件流
} catch (exception e)
{
e.printstacktrace();
}
}
/**
* 给图片添加图片水印
*
* @param pressimg
* 水印图片
* @param srcimagefile
* 源图像地址
* @param destimagefile
* 目标图像地址
* @param x
* 修正值。 默认在中间
* @param y
* 修正值。 默认在中间
* @param alpha
* 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
* @param formattype
* 目标格式
*/
public final static void pressimage(string pressimg, string srcimagefile,
string destimagefile, int x, int y, float alpha,string formattype)
{
try
{
file img = new file(srcimagefile);
image src = imageio.read(img);
int wideth = src.getwidth(null);
int height = src.getheight(null);
bufferedimage image = new bufferedimage(wideth, height,
bufferedimage.type_int_argb);
graphics2d g = image.creategraphics();
g.drawimage(src, 0, 0, wideth, height, null);
// 水印文件
image src_biao = imageio.read(new file(pressimg));
int wideth_biao = src_biao.getwidth(null);
int height_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,
new file(destimagefile));
} catch (exception e)
{
e.printstacktrace();
}
}
/**
* 计算text的长度(一个中文算两个字符)
*
* @param text
* @return
*/
public final static int getlength(string text)
{
int length = 0;
for (int i = 0; i < text.length(); i++)
{
if (new string(text.charat(i) + "").getbytes().length > 1)
{
length += 2;
} else
{
length += 1;
}
}
return length / 2;
}
}
非常实用的图像处理功能,希望大家能够喜欢。