java将多张图片添加水印并生成压缩包导出2(不复制图片)
package com.centit.imgsdown.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.centit.commons.CommonsUtil;
import com.centit.framework.common.JsonResultUtils;
import com.centit.framework.core.controller.BaseController;
import com.centit.njjs.file.service.FileManager;
import com.centit.njjs.jhgl.service.PlanListManager;
import com.centit.njjs.yshgl.po.WaterUser;
import com.centit.njjs.yshgl.service.MeterManager;
import com.centit.njjs.yshgl.service.WaterUserManager;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.apache.commons.lang3.StringUtils;
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 org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
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
* 根据模板图片,生成多张水印图片并导出压缩包
*/
@Controller
@RequestMapping("/imgsdown/imgs/down")
public class ImgsDownController extends BaseController {
private static final Log log = LogFactory.getLog(ImgsDownController.class);
private BufferedImage image;
private int imageWidth = 400; // 图片的宽度
private int imageHeight = 400; // 图片的高度
private final static String fileStr = "D:\\image";
private String fileDemoShang = "";
private String fileDemoXia = "";
@Value("${njjs.file.basepath}")
private String FILE_BASEPATH;
@Resource
private PlanListManager planListManager;
@Resource
private WaterUserManager waterUserManager;
@Resource
private MeterManager meterManager;
@RequestMapping(value = "/downloadZipQr", method = {RequestMethod.GET})
public void getWatersavingVillage(HttpServletRequest request, HttpServletResponse response) {
String classpath = this.getClass().getResource("/").getPath().replaceFirst("/", "");//获取服务器地址
String webappRoot = classpath.replaceAll("WEB-INF/classes/", "template/");//获取服务器地址下template目录所有文件
fileDemoShang=webappRoot+"shangDemo.jpg";
fileDemoXia=webappRoot+"xiaDemo.jpg";
// 创建一个文件夹
java.io.File file = new java.io.File(fileStr);
file.mkdirs();
String fileP="";
Map<String, Object> searchColumn = collectRequestParameters(request);
searchColumn.put("isExported", CommonsUtil.ISEXPORTED_NO);
JSONArray jsonArray = new JSONArray();
String period = (String) searchColumn.get("planPeriod");
if (StringUtils.isBlank(period)) {
}else {
if(period.contains("A")){
this.getImageSizeByBufferedImage(fileDemoShang);
fileP=fileDemoShang;
}else{
this.getImageSizeByBufferedImage(fileDemoXia);
fileP=fileDemoXia;
}
jsonArray = planListManager.listObjectsAsJson(searchColumn, null);
}
//压缩文件
String zipFileStr = "image";
if(jsonArray.size()==0){
this.configDownloadZip(response, zipFileStr+".zip");
this.generateZip(request, response);
}
JSONArray jsonArray2 = new JSONArray();
for(int i=0;i<jsonArray.size();i++){
JSONObject obj=jsonArray.getJSONObject(i);
String text[]=new String[19];
if(i<10){
text[0]="000"+(i+1);
}else if(i>9 && i<100){
text[0]="00"+(i+1);
}else if(i>100 && i<999){
text[0]="0"+(i+1);
}else{
text[0]=""+(i+1);
}
text[1]=period.substring(period.length()-3,period.length()).substring(0,2);
text[2]=obj.getString("userName")==null?"":obj.getString("userName");
text[3]=obj.getString("userCode")==null?"":obj.getString("userCode");
text[4]=obj.getString("one")==null?"":obj.getString("one");
text[5]=obj.getString("two")==null?"":obj.getString("two");
text[6]=obj.getString("three")==null?"":obj.getString("three");
text[7]=obj.getString("four")==null?"":obj.getString("four");
text[8]=obj.getString("five")==null?"":obj.getString("five");
text[9]=obj.getString("six")==null?"":obj.getString("six");
text[10]="20"+period.substring(period.length()-3,period.length()).substring(0,2);
text[11]=Double.valueOf(obj.getString("one"))+Double.valueOf(obj.getString("two"))+Double.valueOf(obj.getString("three"))+Double.valueOf(obj.getString("four"))+Double.valueOf(obj.getString("five"))+Double.valueOf(obj.getString("six"))+"立方米";
Map<String,Object> m=new HashMap<String,Object>();
m.put("userCode",text[3]);
if(waterUserManager.getObjectByProperties(m)!=null){
WaterUser waterUser=waterUserManager.getObjectByProperties(m);
m.clear();
m.put("waterusreId",waterUser.getRowId());
if(meterManager.listObjects(m).size()>0){
text[12]=""+meterManager.listObjects(m).size();
String biao="";
String addr="";
for(int j=0;j<meterManager.listObjects(m).size();j++){
if(j==0){
biao+=meterManager.listObjects(m).get(j).getMeterNo();
addr+=meterManager.listObjects(m).get(j).getAddress();
}else{
biao+=","+meterManager.listObjects(m).get(j).getMeterNo();
addr+=","+meterManager.listObjects(m).get(j).getAddress();
}
}
text[13]=biao;
//判断长度
if(getTextLength(addr)>30){
text[14]=addr.substring(0,34);
text[15]=addr.substring(34,addr.length());
}else{
text[14]=addr;
text[15]="";
}
}
}else{
text[12]="";
text[13]="";
text[14]="";
text[15]="";
}
//增减系数----暂无
text[16]="";
//下一次水平衡测试截止时间----暂无
text[17]="";
Calendar now = Calendar.getInstance();
text[18]=now.get(Calendar.YEAR)+"年"+Integer.valueOf(now.get(Calendar.MONTH)+1)+"月"+now.get(Calendar.DAY_OF_MONTH)+"日";
jsonArray2.add(text);
}
//下载图片
this.graphicsGeneration(fileP,jsonArray2);
try {
//将文件打zip包
this.configDownloadZip(response, zipFileStr+".zip");
this.generateZip(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**------------------------------*/
/*下载图片到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,年份,定额总量,水表块数量,户号,水表地址1,水表地址2,增减系数,截止时间,日期
int[] xn={580,151,122,546,123,206,289,378,466,546,130,356,185,148,216,143,197,291,500};
int[] yn={10 ,46 ,153,153,314,314,314,314,314,314,387,387,438,482,517,543,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.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++){
if(n==1){
tip.setFont(new Font(fontName, Font.BOLD, 25));
}else {
tip.setFont(new Font(fontName, fontStyle, fontSize));
}
// 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();
}
}
}
}
}
/**------------------------------*/
/*将文件压缩*/
/**------------------------------*/
/**
* 删除文件夹
* @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) {
// System.out.println("删除文件夹操作出错");
log.info("删除文件夹操作出错");
}
}
/**
* 删除指定文件夹下所有文件
* @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;
}
/**
* 设置response头 为下载zip, 设置文件名. 应该在response写出之前被调用
*/
public static void configDownloadZip(HttpServletResponse response, String fileName) {
response.setHeader("Content-Type", "application/zip");
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
}
/**
* 生成压缩包
* @param request
* @return
*/
public static void generateZip(HttpServletRequest request,
HttpServletResponse response){
// //获取存储路径
//遍历存储路径
//获取pathName的File对象
File dirFile = new File(fileStr);
//获取此目录下的所有文件名与目录名
String[] fileList = dirFile.list();
ZipOutputStream zos = null;
try {
//关联response输出流,直接将zip包文件内容写入到response输出流并下载
zos = new ZipOutputStream(response.getOutputStream());
//循环读取文件路径集合,获取每一个文件的路径
if(fileList.length>0)
for(String fp : fileList){
File f = new File(fileStr, fp); //根据文件路径创建文件
zipFile(f, zos); //将每一个文件写入zip文件包内,即进行打包
//刷新缓冲区
response.flushBuffer();
}
// 删除文件和压缩文件
if(fileList.length>0)
delFolder(fileStr);
} catch (IOException e) {
e.printStackTrace();
}finally {
try{
if(zos != null){
zos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 封装压缩文件的方法
* @param inputFile
* @param zipoutputStream
*/
public static void zipFile(File inputFile,ZipOutputStream zipoutputStream) {
try {
if(inputFile.exists()) { //判断文件是否存在
if (inputFile.isFile()) { //判断是否属于文件,还是文件夹
//创建输入流读取文件
FileInputStream fis = new FileInputStream(inputFile);
BufferedInputStream bis = new BufferedInputStream(fis);
//将文件写入zip内,即将文件进行打包
ZipEntry ze = new ZipEntry(inputFile.getName()); //获取文件名
zipoutputStream.putNextEntry(ze);
//写入文件的方法,同上
byte [] b=new byte[1024];
long l=0;
while(l<inputFile.length()){
int j=bis.read(b,0,1024);
l+=j;
zipoutputStream.write(b,0,j);
}
//关闭输入输出流
fis.close();
bis.close();
} else { //如果是文件夹,则使用穷举的方法获取文件,写入zip
try {
File[] files = inputFile.listFiles();
for (int i = 0; i < files.length; i++) {
zipFile(files[i], zipoutputStream);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
最终效果