java 图片处理,包括图片裁剪(圆形,矩形),图片的缩放,多张图片组合成一张长图(横向,纵向),边框,水印(45度倾斜),写字,插图,实线、虚线,html格式文本转换成图片(需要html2image-0.9.jar,现在上传下载要5分,我就不上传了,地址https://download.youkuaiyun.com/download/u013296643/10115762)等等。
package com.coolsn.modules.tb.imageTools;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Transparency;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import gui.ava.html.image.generator.HtmlImageGenerator;
/**
* 图片处理
* @author tb
*
*/
public class ImgTools {
/**
* 裁剪图片-优化版本;以图片中心为源点,按照长宽比进行图片裁剪,裁剪圆形
* @param BufferedImage
* @param widthToHeight 长宽比例,若是为1则是圆形
* @return BufferedImage
* @throws IOException
*/
public static BufferedImage cutPicArc(BufferedImage bi,float widthToHeight) throws IOException{
int width=bi.getWidth();
int height=bi.getHeight();
int dw=0;
int dh=0;
if(width/(height*1.0)>widthToHeight){//截长
dw=Math.round(Math.abs(width-widthToHeight*height));
}else{//截高
dh=Math.round(Math.abs(height-(1/widthToHeight)*width));
}
BufferedImage bi2 = new BufferedImage(width-dw,height-dh,Transparency.TRANSLUCENT);
Ellipse2D.Double shape = new Ellipse2D.Double(0,0,width-dw,height-dh);
Graphics2D g2 = bi2.createGraphics();
g2.setClip(shape);
// 使用 setRenderingHint 设置抗锯齿
g2.drawImage(bi,0,0,null);
g2.dispose();
return bi2;
}
/**
* 裁剪图片-优化版本;以图片中心为源点,按照长宽比进行图片裁剪,裁剪矩形
* @param BufferedImage
* @param widthToHeight 长宽比例,若是为1则是正方形
* @return BufferedImage
* @throws IOException
*/
public static BufferedImage cutPicRect(BufferedImage bi,float widthToHeight) throws IOException{
int width=bi.getWidth();
int height=bi.getHeight();
int dw=0;
int dh=0;
if(width/(height*1.0)>widthToHeight){//截长
dw=Math.round(Math.abs(width-widthToHeight*height));
}else{//截高
dh=Math.round(Math.abs(height-(1/widthToHeight)*width));
}
BufferedImage bi2 = new BufferedImage(width-dw,height-dh,Transparency.TRANSLUCENT);
Graphics2D g2 = bi2.createGraphics();
// 使用 setRenderingHint 设置抗锯齿
g2.drawImage(bi,-dw/2,-dh/2,null);
g2.dispose();
return bi2;
}
/**
* 缩放图片
* @param BufferedImage
* @param scale 比例饿
* @return BufferedImage
*/
public static BufferedImage humbnailPic(BufferedImage bi,float scale) throws IOException{
int width=bi.getWidth();
int height=bi.getHeight();
BufferedImage bi2 = new BufferedImage(Math.round(width*scale),Math.round(height*scale),Transparency.TRANSLUCENT);
Graphics2D g2 = bi2.createGraphics();
// 使用 setRenderingHint 设置抗锯齿
g2.drawImage(bi, 0, 0, Math.round(width*scale),Math.round(height*scale), 0, 0, width, height, null);
g2.dispose();
return bi2;
}
/**
* 缩放图片-按最小长宽进行压缩
* @param BufferedImage
* @param scale 比例饿
* @return BufferedImage
*/
public static BufferedImage humbnailPicMin(BufferedImage bi,int minWidth,int minHeight) throws IOException{
int width=bi.getWidth();
int height=bi.getHeight();
float scale = 0f;
if(minWidth/width>minHeight/height) {//取小比例
scale = 1.0f*minHeight/height;
}else scale = 1.0f*minWidth/width;
BufferedImage bi2 = new BufferedImage(Math.round(width*scale),Math.round(height*scale),Transparency.TRANSLUCENT);
Graphics2D g2 = bi2.createGraphics();
// 使用 setRenderingHint 设置抗锯齿
g2.drawImage(bi, 0, 0, Math.round(width*scale),Math.round(height*scale), 0, 0, width, height, null);
g2.dispose();
return bi2;
}
/**
* 多张图片合成为一张图-竖向
* @param imagePaths 图片路径数组
* @param width 合成后图片宽度
* @param widthFixing 是否固宽(固宽即是所有的图片的宽度一致,大于此宽度的等比例压缩,小于的等比例扩大)
* @return
*/
public static BufferedImage composeImageVertical(String[] imagePaths,int width) {
File[] files = new File[imagePaths.length];
for(int index=0; index<files.length; index++) {
files[index] = new File(imagePaths[index]);
}
return composeImageVertical(files, width);
}
/**
* 目录下所有图片合成为一张图-竖向
* @param imagePaths 图片路径数组
* @param width 合成后图片宽度
* @param widthFixing 是否固宽(固宽即是所有的图片的宽度一致,大于此宽度的等比例压缩,小于的等比例扩大)
* @return
*/
public static BufferedImage composeImageVertical(String imageDir,int width) {
File[] files = new File(imageDir).listFiles();
return composeImageVertical(files, width);
}
/**
* 多张图片合成为一张图-竖向
* @param images
* @param width 合成后图片宽度
* @return
*/
public static BufferedImage composeImageVertical(File[] images,int width) {
//计算所有的图片合起来的高度
BufferedImage[] bufferedImages = new BufferedImage[images.length];//处理后的图片
int height = 0;
for(int index=0; index<images.length; index++) {
File image = images[index];
try {
BufferedImage bImage = ImageIO.read(image);
//按宽度进行原图片等比缩放
int newWidth = bImage.getWidth();
float scale = width*1.0f/newWidth;
bImage = humbnailPic(bImage,scale);
height +=bImage.getHeight();
bufferedImages[index] = bImage;
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
//构建目标图片
BufferedImage bi2 = new BufferedImage(width,height,Transparency.TRANSLUCENT);
Graphics2D g2 = bi2.createGraphics();
int finishHeight = 0;//已经完成的高,用于定位下一张图片的起始位置
//将所有图片画于目标图片上
for(int index=0; index<bufferedImages.length; index++) {
BufferedImage bufferedImage = bufferedImages[index];
g2.drawImage(bufferedImage,0,finishHeight, width, bufferedImage.getHeight(), null);
finishHeight +=bufferedImage.getHeight();
}
g2.dispose();
return bi2;
}
/**
* 创建绘图对象
* @param width 宽度
* @param height 高度
* @param color 背景颜色
* @return
*/
public static BufferedImage createImage(int width,int height,Color color) {
BufferedImage bi=new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
Graphics g=bi.getGraphics();
if (color != null) {
g.setColor(color);
g.fillRect(0, 0, width, height);
}
return bi;
}
/**
* 画边框
* @param bi
* @param borderSize 边框宽度
* @param borderColor 边框颜色
* @return
*/
public static BufferedImage drawBorder(BufferedImage bi,float borderSize,Color borderColor) {
int width = bi.getWidth();
int height = bi.getHeight();
Graphics2D g=bi.createGraphics();
g.setStroke(new BasicStroke(borderSize));
g.setColor(borderColor==null?Color.GRAY:borderColor);
g.drawLine(0, 0, width, 0);
g.drawLine(width-2, 0, width-2, height);
g.drawLine(width, height-1, 0,height-1);
g.drawLine(0, height, 0, 0);
g.dispose();
return bi;
}
/**
* 水印
* @param bi
* @param str 水印字符串
* @param color 水印颜色
* @param size 字体大小
* @param hDis 高间隔
* @param yDis 宽间隔
* @return
*/
public static BufferedImage watermark(BufferedImage bi,String str,Color color,int size,int hDis,int yDis) {
int len = str.length();
Graphics2D g = bi.createGraphics();
g.translate(0, 0);
g.rotate(-Math.PI / 4);
g.setColor(color);
g.setFont(new Font("Fixedsys", Font.PLAIN, size));
for(int py=0; py<=2*bi.getHeight(); py+=hDis) {
for(int px=-bi.getWidth()/2; px<=bi.getWidth()/2; px+=len*20+yDis) {
g.drawString(str, px, py);
}
}
g.dispose();
return bi;
}
/**
* 写字
* @param bi BufferedImage
* @param text 文本
* @param color Color.green
* @param pointX 起点的x坐标
* @param pointY 起点的y坐标
* @param size 字体大小
* @return
*/
public static BufferedImage drawFont(BufferedImage bi,String text,Color color,int pointX,int pointY,int size){
//g.setColor(Color.green);
Graphics2D g = bi.createGraphics();
g.setColor(color);
g.setFont(new Font("Fixedsys", Font.PLAIN, size));
g.drawString(text, pointX, pointY);
g.dispose();
return bi;
}
/**
* 插入图片
* @param g Graphics
* @param image 图片文件file
* @param pointX 起点x坐标
* @param pointY 起点y坐标
* @param width 自定义插入图片的宽度(高度按比例缩放),若是为0则表示原图片的宽高
* @return
* @throws IOException
*/
public static BufferedImage drawImage(BufferedImage bi,File image,int pointX,int pointY,int width) throws IOException{
//g.setColor(Color.green);
Graphics2D g = bi.createGraphics();
BufferedImage bufferedImage = ImageIO.read(image);
int sWidth = bufferedImage.getWidth();
int sHeight = bufferedImage.getHeight();
if (width != 0) {
//按比例计算图片的高度
sHeight = Integer.valueOf(String.valueOf(Math.round((width*1.0/sWidth)*sHeight)));
sWidth = width;
}
g.drawImage(bufferedImage,pointX, pointY,sWidth, sHeight, null);
g.dispose();
return bi;
}
/**
* 插入图片
* @param bi BufferedImage
* @param BufferedImage
* @param pointX 起点x坐标
* @param pointY 起点y坐标
* @param width 自定义插入图片的宽度(高度按比例缩放),若是为0则表示原图片的宽高
* @return
* @throws IOException
*/
public static BufferedImage drawImage(BufferedImage bi,BufferedImage bufferedImage,int pointX,int pointY,int width) throws IOException{
//g.setColor(Color.green);
Graphics2D g = bi.createGraphics();
int sWidth = bufferedImage.getWidth();
int sHeight = bufferedImage.getHeight();
if (width != 0) {
//按比例计算图片的高度
sHeight = Integer.valueOf(String.valueOf(Math.round((width*1.0/sWidth)*sHeight)));
sWidth = width;
}
g.drawImage(bufferedImage,pointX, pointY,sWidth, sHeight, null);
g.dispose();
return bi;
}
/**
* 画正玄曲线 横向的
* 注:内嵌了随机颜色生成,故而产生的线是多彩色
* @param g graphics
* @param width img'width
* @param height img'height
* @param r 周期半径
* @param f 峰度
* @return graphics
*/
public static BufferedImage drawCurve(BufferedImage bi,int x1,int y1,Integer x2,Integer y2,int r,int f){
Graphics2D g = bi.createGraphics();
int disX = x2-x1;
int disY = y2-y1;
double yd = y1;
for(int j=1;j<=disX;j++){
x2=x1+1;
if (disY != 0) {
yd=disY*1.0/disX*1+y1;
}
y2=(int) Math.round(Math.sin(x2/r)*f+yd);
setRandomColor(g);
g.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
g.dispose();
return bi;
}
/**
* 画正玄曲线 纵向的
* 注:内嵌了随机颜色生成,故而产生的线是多彩色
* @param g graphics
* @param width img'width
* @param height img'height
* @param r 周期半径
* @param f 峰度
* @return graphics
*/
public static BufferedImage drawCurveH(BufferedImage bi,int width,int height,int r,int f){
Graphics2D g = bi.createGraphics();
int xD=(int) Math.round(Math.random()*width);
int x1=xD;
int y1=0;
int y2=0;
int x2=0;
for(int j=0;j<height;j++){
y2=y1+1;
setRandomColor(g);
x2=(int) Math.round(Math.sin(y2/r)*f)+xD;
g.drawLine(x1, y1, x2, y2);
x1=x2;
y1=y2;
}
g.dispose();
return bi;
}
/**
* 画圆,其实上是画椭圆,如果横半径与纵半径相等则是特殊的椭圆-->圆
* @param g graphics
* @param wR 横半径
* @param hR 纵半径
* @param startW 开始角度
* @param endW 结束角度
* 注:角度均是0到360
* @return
*/
public static BufferedImage drawCirCle(BufferedImage bi,int wR,int hR,int startW,int endW){
Graphics2D g = bi.createGraphics();
setRandomColor(g);
g.drawArc(0, 0, wR, hR,startW,endW);
//画椭圆的,不过感觉是多余的
//g.drawOval(0, 0, wR, hR);
g.dispose();
return bi;
}
/**
* 自带的画圆很有局限性,该方法可以将圆设置为多彩色
* 注:内嵌了随机颜色生成,故而产生的线是多彩色
* @param g graphics
* @param xDs 圆心的x坐标
* @param yDs 圆心的y坐标
* @param r 该圆的半径
* @return graphics
*/
public static BufferedImage drawCirCleByMine(BufferedImage bi,int xDs,int yDs,int r){
Graphics2D g = bi.createGraphics();
int yD=yDs;
int xD=xDs-20;
int y1=yD;
int x1=0;
int x2=0;
int y2=0;
for(int j=0;j<=r*2;j++){
x2=x1+1;
y2=(int) Math.round(Math.sqrt(r*r-(x2-r)*(x2-r)))+yD;
setRandomColor(g);
g.drawLine(x1+xD, y1, x2+xD, y2);
x1=x2;
y1=y2;
}
x1=0;
y1=yD;
for(int j=0;j<=r*2;j++){
x2=x1+1;
y2=yD-(int) Math.round(Math.sqrt(r*r-(x2-r)*(x2-r)));
setRandomColor(g);
g.drawLine(x1+xD, y1, x2+xD, y2);
x1=x2;
y1=y2;
}
g.dispose();
return bi;
}
/**
* 设置随机颜色
* @param g
* @return
*/
public static Graphics setRandomColor(Graphics g){
int red=0;
int green=0;
int blue=0;
Random random=new Random();
// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
// 用随机产生的颜色将验证码绘制到图像中。
g.setColor(new Color(red, green, blue));
return g;
}
/**
* html格式文本转换成图片
* @param htmlStr
* @return
*/
public static BufferedImage html2image(String htmlStr) {
HtmlImageGenerator imageGenerator = new HtmlImageGenerator();
imageGenerator.loadHtml(htmlStr);
BufferedImage bufferedImage = imageGenerator.getBufferedImage();
return bufferedImage;
}
/**
* 画线-实线
* @param bi
* @param x1 起点x坐标
* @param y1 起点y坐标
* @param x2 终点x坐标
* @param y2 终点y坐标
* @param color 颜色
* @param size 粗细
* @return
*/
public static BufferedImage drawLine(BufferedImage bi,int x1,int y1, int x2, int y2,Color color,float size) {
Graphics2D g = bi.createGraphics();
g.setColor(color);
g.setStroke(new BasicStroke(size));
g.drawLine(x1, y1, x2, y2);
g.dispose();
return bi;
}
/**
* 画线-虚线
* @param bi
* @param x1 起点x坐标
* @param y1 起点y坐标
* @param x2 终点x坐标
* @param y2 终点y坐标
* @param color 颜色
* @param size 粗细
* @param lineSize 线段长度
* @param disSize 间隔长度
* @return
*/
public static BufferedImage drawLine(BufferedImage bi,int x1,int y1, int x2, int y2,Color color,float size,int lineLen,int disLen) {
Graphics2D g = bi.createGraphics();
g.setColor(color);
g.setStroke(new BasicStroke(size));
int lenX = x2-x1;
int lenY = y2-y1;
if (lenX != 0 && lenY != 0) {//画斜线
int disXu = (int) Math.round(Math.sqrt((Math.pow(lenY, 2)*Math.pow(lineLen, 2))/(Math.pow(lenX, 2)+Math.pow(lenY, 2))));//x的步长
int disXdu = (int) Math.round(Math.sqrt((Math.pow(lenY, 2)*Math.pow(disLen, 2))/(Math.pow(lenX, 2)+Math.pow(lenY, 2))));//x的间隔步长
int disYu = (int) Math.round(lenY*1.0*disXu/lenX);//y的步长
int disYdu = (int) Math.round(lenY*1.0*disXdu/lenX);//y的间隔步长
if (disXu == 0) {
disXu = 1;
}
if (disXdu == 0) {
disXdu = 1;
}
for(int disX=0; disX<=lenX; disX+=(disXu+disXdu)) {
x2 = x1+disXu;
y2 = y1+disYu;
g.drawLine(x1, y1, x2, y2);
x1 = x2+disXdu;
y1 = y2+disYdu;
}
}else {//画横竖线
if (lenX == 0) {//画横线
for(int disY=0; disY<=lenY; disY+=(lineLen+disLen)) {
y2 = y1+lineLen;
g.drawLine(x1, y1, x2, y2);
y1 =y2+disLen;
}
}else {
for(int disX=0; disX<=lenX; disX+=(lineLen+disLen)) {
x2 = x1+lineLen;
g.drawLine(x1, y1, x2, y2);
x1 =x2+disLen;
}
}
}
g.dispose();
return bi;
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
/*BufferedImage bi=ImageIO.read(new File("F:\\1.jpeg"));
bi=cutPicRect(bi,1);
ImageIO.write(bi, "png", new File("F:\\1_1.jpeg"));*/
/*BufferedImage bImage = composeImageVertical(new String[] {"F:\\picture\\壁纸\\14ce36d3d539b6004675e6c6ea50352ac65cb70c.jpg",
"F:\\picture\\壁纸\\138-140F9154532.jpg",
"F:\\picture\\壁纸\\82240c15ed7bc76f2af9cb0882770dd6.jpg",
"F:\\picture\\壁纸\\22197937_1371459132142.jpg",
"F:\\picture\\壁纸\\c0e0b81d5066c275d6f8c954b1202386.jpg"},2000);*/
//BufferedImage bImage = composeImageVertical("F:\\picture\\壁纸",500);
//ImageIO.write(bImage, "png", new File("F:\\picture\\壁纸\\compose.jpg"));
BufferedImage bi=createImage(450, 630, Color.WHITE);
bi = drawFont(bi,"测试", Color.RED, 10, 10, 15);
ImageIO.write(bi, "jpg", new File("F:\\picture\\test\\参赛证.jpg"));
}
}