java将多张图片添加水印并生成压缩包导出

模板

在这里插入图片描述

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.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 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 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 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();
        ImgsDownController f=new ImgsDownController();
        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;
        }
        if(jsonArray.size()>0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                f.copy(fileP,i);//复制一张图片出来
                String p=fileStr+"\\"+i+"-"+i+".jpg";
                f.graphicsGeneration(p,(String[])jsonArray.get(i),i);
            }
        }
        //压缩文件
        String zipFileStr = "D:\\image.zip";
        f.FileMain(null,fileStr,zipFileStr);
    }
    /**------------------------------*/
    /*下载图片到D:\image文件夹下并添加水印*/
    /**------------------------------*/
    public void copy(String imgurl,int i){
        image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
        int width = image.getWidth(null);
        int height = image.getHeight(null);
        Graphics mainPic = image.getGraphics();
        BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        try {
            bimg = javax.imageio.ImageIO.read(new File(imgurl));
        } catch (Exception e) {

        }
        if (bimg != null) {
            mainPic.drawImage(bimg, 0, 0, imageWidth, imageHeight, null);
            mainPic.dispose();
        }
        createImage(image,fileStr+"\\"+i+"-"+i+".jpg");
    }
    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,String[] text,int i) {
//        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};
        // 设置图片的背景色
//        Graphics2D main = image.createGraphics();
//        main.setColor(Color.white);
//        main.fillRect(0, 0, imageWidth, imageHeight);

        // ***********************模板照片**************
        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,image,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();
                    }
                }
            }
        }
    }
/**------------------------------*/
    /*删除文件*/
/**------------------------------*/
    /**
     * 判断指定的文件或文件夹删除是否成功
     * @param FileName 文件或文件夹的路径
     * @return true or false 成功返回true,失败返回false
     */
    public static boolean deleteAnyone(String FileName){

        File file = new File(FileName);//根据指定的文件名创建File对象


        if ( !file.exists() ){  //要删除的文件不存在
            System.out.println("文件"+FileName+"不存在,删除失败!" );
            return false;
        }else{ //要删除的文件存在

            if ( file.isFile() ){ //如果目标文件是文件

                return deleteFile(FileName);

            }else{  //如果目标文件是目录
                return deleteDir(FileName);
            }
        }
    }
    /**
     * 删除指定的目录以及目录下的所有子文件
     * @param dirName is 目录路径
     * @return true or false 成功返回true,失败返回false
     */
    public static boolean deleteDir(String dirName){

        if ( dirName.endsWith(File.separator) )//dirName不以分隔符结尾则自动添加分隔符
            dirName = dirName + File.separator;

        File file = new File(dirName);//根据指定的文件名创建File对象
        if ( !file.exists() || ( !file.isDirectory() ) ){ //目录不存在或者
            System.out.println("目录删除失败"+dirName+"目录不存在!" );
            return false;
        }
        File[] fileArrays = file.listFiles();//列出源文件下所有文件,包括子目录

        for ( int i = 0 ; i < fileArrays.length ; i++ ){//将源文件下的所有文件逐个删除
            ImgsDownController.deleteAnyone(fileArrays[i].getAbsolutePath());
        }
        if ( file.delete() )//删除当前目录
            System.out.println("目录"+dirName+"删除成功!" );

        return true;

    }
    /**
     * 判断指定的文件删除是否成功
     * @param --FileName 文件路径
     * @return true or false 成功返回true,失败返回false
     */
    public static boolean deleteFile(String fileName){

        File file = new File(fileName);//根据指定的文件名创建File对象

        if (  file.exists() && file.isFile() ){ //要删除的文件存在且是文件

            if ( file.delete()){
                System.out.println("文件"+fileName+"删除成功!");
                return true;
            }else{
                System.out.println("文件"+fileName+"删除失败!");
                return false;
            }
        }else{

            System.out.println("文件"+fileName+"不存在,删除失败!" );
            return false;
        }
    }
/**------------------------------*/
    /*将文件压缩*/
/**------------------------------*/
    public void FileMain(String[] files,String fileStr,String zipFileStr)  throws Exception{
        try {
            File file = new File(fileStr);//根据指定的文件名创建File对象
            if ( !file.exists() || ( !file.isDirectory() ) ){ //目录不存在或者
                System.out.println("目录删除失败"+fileStr+"目录不存在!" );
            }
            File[] fileArrays = file.listFiles();//列出源文件下所有文件,包括子目录
            for ( int i = 0 ; i < fileArrays.length ; i++ ){//将源文件下的所有文件逐个删除
                if(fileArrays[i].getName().contains("-")){//删除包含-标识符的图片
                    ImgsDownController.deleteAnyone(fileArrays[i].getAbsolutePath());
                }
            }
            // 压缩法
            FileOutputStream fos1 = new FileOutputStream(new java.io.File(zipFileStr));
            this.toZip1(fileStr, fos1,false);

            // 删除文件和压缩文件
            ImgsDownController f=new ImgsDownController();
            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;
    }
}


最终效果

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值