java将多张图片添加水印并生成压缩包导出2(不复制图片,不需要擦出绘制记录)
程序员文章站
2022-05-26 23:52:21
...
java将多张图片添加水印并生成压缩包导出2(不复制图片)
package com.centit.imgsdown.controller;
import com.alibaba.fastjson.JSONArray;
import com.centit.framework.core.controller.BaseController;
import com.centit.njjs.file.service.FileManager;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* File Controller.
* create by scaffold 2020-04-21
* 文件表null
*/
@Controller
@RequestMapping("/imgsdown/imgs/down")
public class ImgsDownController2 extends BaseController {
private static final Log log = LogFactory.getLog(ImgsDownController2.class);
private BufferedImage image;
private int imageWidth = 400; // 图片的宽度
private int imageHeight = 400; // 图片的高度
private final static String fileStr = "D:\\image";
private final static String fileDemoShang = "D:\\shang.jpg";
private final static String fileDemoXia = "D:\\xia.jpg";
@Value("${njjs.file.basepath}")
private String FILE_BASEPATH;
@Resource
private FileManager fileMag;
public static void main(String[] args) throws Exception {
// 创建一个文件夹
java.io.File file = new java.io.File(fileStr);
file.mkdirs();
ImgsDownController2 f=new ImgsDownController2();
int year=1;
if(year==1){
f.getImageSizeByBufferedImage(fileDemoShang);
}else{
f.getImageSizeByBufferedImage(fileDemoXia);
}
String[] pressText={"0001","南京市道路规划展览馆","040307","1000","2000","3000","4000","5000","6000","23456立方米","2","0010,0020","宣武门22号","0.10","未展开","2020年07月28日"};
String[] pressText2={"0002","京市道路规划展览馆2","040307","2000","2000","3000","4000","5000","6000","2立方米","2","0010,0020","宣武门22号","0.10","未展开","2020年07月30日"};
JSONArray jsonArray =new JSONArray();
jsonArray.add(pressText);
jsonArray.add(pressText2);
String fileP="";
//下载图片
if(year==1){
fileP=fileDemoShang;
}else{
fileP=fileDemoXia;
}
f.graphicsGeneration(fileP,jsonArray);
//压缩文件
String zipFileStr = "D:\\image.zip";
f.FileMain(null,fileStr,zipFileStr);
}
/**------------------------------*/
/*下载图片到D:\image文件夹下并添加水印*/
/**------------------------------*/
public void getImageSizeByBufferedImage(String src) {
long beginTime = new Date().getTime();
java.io.File file = new java.io.File(src);
FileInputStream is = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
BufferedImage sourceImg = null;
try {
sourceImg = javax.imageio.ImageIO.read(is);
System.out.println("width:" + sourceImg.getWidth());
System.out.println("height:" + sourceImg.getHeight());
imageWidth=sourceImg.getWidth();
imageHeight=sourceImg.getHeight();
System.out.println("imageWidth:" + imageWidth);
System.out.println("imageHeight:" + imageHeight);
} catch (IOException e1) {
e1.printStackTrace();
}
long endTime = new Date().getTime();
System.out.println("使用[BufferedImage]获取图片尺寸耗时:[" + (endTime - beginTime)+"]ms");
}
public void graphicsGeneration(String imgurl,JSONArray jsonArray) {
// int H_tip = 60; // 文字的高度
image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
String fontName="宋体";
int fontStyle=Font.TRUETYPE_FONT;
int fontSize=14;
Color color=Color.BLACK;
float alpha=1f;
int width = image.getWidth(null);
int height = image.getHeight(null);
/** 不加年份日期,16组数据,加年份半年18组数据*/
//页码,单位,用户代码,月1-月6,定额总量,水表块数量,户号,水表地址,增减系数,截止时间,日期
int[] xn={580,122,546,123,206,289,378,466,546,356,185,148,216,197,291,500};
int[] yn={10,153,153,314,314,314,314,314,314,387,438,482,517,566,632,927};
if(jsonArray.size()>0){
for(int i=0;i<jsonArray.size();i++){
/**区别在于这个地方,每次生成水印图片时都会新建一个新的画布,不需要擦除步骤*/
huabuNew((String[])jsonArray.get(i),width,height,imgurl,fontName,fontStyle,fontSize,color,xn,yn,alpha,i);
}
}
}
public void huabuNew(String[] text,int width,int height,String imgurl,String fontName,int fontStyle,int fontSize,
Color color,int[] xn,int[] yn,float alpha,int i){
// ***********************模板照片**************
Graphics mainPic = image.getGraphics();
BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
try {
bimg = javax.imageio.ImageIO.read(new java.io.File(imgurl));
} catch (Exception e) {
}
if (bimg != null) {
mainPic.drawImage(bimg, 0, 0, imageWidth, imageHeight, null);
mainPic.dispose();
}
creatNewImg(text,bimg,width,height,fontName,fontStyle,fontSize,color,xn,yn,alpha,i);
}
private static boolean creatNewImg(String[] pressText,BufferedImage image,int width,int height,String fontName,int fontStyle,int fontSize,
Color color,int[] xn,int[] yn,float alpha,int i){
// ***********************设置水印内容****************
Graphics2D tip = image.createGraphics();
//图片抗锯齿设置
tip.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
tip.drawImage(image,0,0, width, height, null);
tip.setFont(new Font(fontName, fontStyle, fontSize));
tip.setColor(color);
tip.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
int width_wi = 0;
int height_wi = fontSize;
int widthDiff = width-width_wi;
int heightDiff = height-height_wi;
for (int n=0;n<xn.length;n++){
width_wi=fontSize*getTextLength(pressText[n]);
if(xn[n]<0){
xn[n] = widthDiff/2;
}else if(xn[n]>widthDiff){
xn[n]=widthDiff;
}
if(yn[n]<0){
yn[n] = heightDiff/2;
}else if(yn[n]>heightDiff){
yn[n] = heightDiff;
}
tip.drawString(pressText[n], xn[n], yn[n]+height_wi);//水印文件
}
tip.dispose();
createImage(image,fileStr+"\\"+i+".jpg");
System.out.println("生成图片成功");
return false;
}
/**
* 计算文字像素长度
* @param text
* @return
*/
private static int getTextLength(String text){
int textLength = text.length();
int length = textLength;
for (int i = 0; i < textLength; i++) {
int wordLength = String.valueOf(text.charAt(i)).getBytes().length;
if(wordLength > 1){
length+=(wordLength-1);
}
}
return length%2==0 ? length/2:length/2+1;
}
// 生成图片文件
@SuppressWarnings("restriction")
public static void createImage(BufferedImage image,String fileLocation) {
BufferedOutputStream bos = null;
if (image != null) {
try {
FileOutputStream fos = new FileOutputStream(fileLocation);
bos = new BufferedOutputStream(fos);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
encoder.encode(image);
bos.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {// 关闭输出流
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**------------------------------*/
/*将文件压缩*/
/**------------------------------*/
public void FileMain(String[] files,String fileStr,String zipFileStr) throws Exception{
try {
// 压缩法
FileOutputStream fos1 = new FileOutputStream(new java.io.File(zipFileStr));
this.toZip1(fileStr, fos1,false);
// 删除文件和压缩文件
ImgsDownController2 f=new ImgsDownController2();
f.delFolder(fileStr);
//FileUtil.delFolder(zipFileStr);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 递归压缩方法
* @param sourceFile 源文件
* @param zos zip输出流
* @param name 压缩后的名称
* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
* false:所有文件跑到压缩包根目录***意:不保留目录结构可能会出现同名文件,会压缩失败)
* @throws Exception
*/
private static void compress(java.io.File sourceFile, ZipOutputStream zos, String name,
boolean KeepDirStructure) throws Exception{
byte[] buf = new byte[2 * 1024];
if(sourceFile.isFile()){
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
// Complete the entry
zos.closeEntry();
in.close();
} else {
java.io.File[] listFiles = sourceFile.listFiles();
if(listFiles == null || listFiles.length == 0){
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if(KeepDirStructure){
// 空文件夹的处理
zos.putNextEntry(new ZipEntry(name + "/"));
// 没有文件,不需要文件的copy
zos.closeEntry();
}
}else {
for (java.io.File file : listFiles) {
// 判断是否需要保留原来的文件结构
if (KeepDirStructure) {
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
} else {
compress(file, zos, file.getName(),KeepDirStructure);
}
}
}
}
}
/**
* 压缩成ZIP 方法1
* @param srcDir 压缩文件夹路径
* @param out 压缩文件输出流
* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
* false:所有文件跑到压缩包根目录***意:不保留目录结构可能会出现同名文件,会压缩失败)
* @throws RuntimeException 压缩失败会抛出运行时异常
*/
public static void toZip1(String srcDir, OutputStream out, boolean KeepDirStructure)
throws RuntimeException{
long start = System.currentTimeMillis();
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(out);
java.io.File sourceFile = new java.io.File(srcDir);
compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) +" ms");
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 压缩成ZIP 方法2
* @param srcFiles 需要压缩的文件列表
* @param out 压缩文件输出流
* @throws RuntimeException 压缩失败会抛出运行时异常
*/
public static void toZip2(List<java.io.File> srcFiles , OutputStream out)throws RuntimeException {
long start = System.currentTimeMillis();
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(out);
for (java.io.File srcFile : srcFiles) {
byte[] buf = new byte[2 * 1024];
zos.putNextEntry(new ZipEntry(srcFile.getName()));
int len;
FileInputStream in = new FileInputStream(srcFile);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) +" ms");
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 得到图片的二进制数据,以二进制封装得到数据,具有通用性
* @param inStream
* @return
* @throws Exception
*/
private byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=inStream.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
/**
* 删除文件夹
* @param folderPath 文件夹完整绝对路径
* @return
*/
public static void delFolder(String folderPath) {
try {
delAllFile(folderPath); //删除完里面所有内容
String filePath = folderPath;
filePath = filePath.toString();
java.io.File myFilePath = new java.io.File(filePath);
myFilePath.delete(); //删除空文件夹
System.out.println("删除文件夹操作成功!");
}
catch (Exception e) {
String message = ("删除文件夹操作出错");
}
}
/**
* 删除指定文件夹下所有文件
* @param path 文件夹完整绝对路径
* @return
* @return
*/
public static boolean delAllFile(String path) {
boolean bea = false;
java.io.File file = new java.io.File(path);
if (!file.exists()) {
return bea;
}
if (!file.isDirectory()) {
return bea;
}
String[] tempList = file.list();
java.io.File temp = null;
for (int i = 0; i < tempList.length; i++) {
if (path.endsWith(java.io.File.separator)) {
temp = new java.io.File(path + tempList[i]);
}else{
temp = new java.io.File(path + java.io.File.separator + tempList[i]);
}
if (temp.isFile()) {
temp.delete();
}
if (temp.isDirectory()) {
delAllFile(path+"/"+ tempList[i]);//先删除文件夹里面的文件
delFolder(path+"/"+ tempList[i]);//再删除空文件夹
bea = true;
}
}
return bea;
}
}
最终效果
下一篇: 劲爆笑图,有事没事看图乐呵乐呵!