使用腾讯云上传图片,并给图片加水印

controller层

@ApiOperation("上传")
@PostMapping("/upload")
//@RequiresRoles("admin")
public Result upload(
    @ApiParam(value = "文件", required = true) @RequestParam("file") MultipartFile multipartFile,
    @ApiParam(value = "是否加水印:0-不加,1-加")@RequestParam(defaultValue = "0") Integer isWaterMark
) {

    Result result = new Result();

    //将文件上传到腾讯云
    try {
        if (isWaterMark == 1) {
            //加水印
            multipartFile = WaterMarkUtils.addWorkMarkToMutipartFile(multipartFile, "找房快");
        }

        //上传腾讯云,返回随机文件名字
        File file = MultipartFileUtil.multipartFileToFile(multipartFile);
        String filename = TengXunOssUtil.uploadFile(file);
        filename = TengXunOssUtil.URL_PREFIX + filename;//拼接访问路径和文件名

		//删除本地临时文件
        MultipartFileUtil.delteTempFile(file);
        result.setCode(200);
        result.setResult(filename);
        result.setMessage("上传成功");
    } catch (Exception e) {
        log.info(e.getMessage(), e);
        result.setCode(500);
        result.setMessage("上传失败");

    }
    return result;
}

图片上传工具

import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author 
 * @version 1.0
 * @date 2021/1/6 15:40
 */
public class WaterMarkUtils {

    /**
     * 加图片水印 : 没有测试
     *
     * @param bufImg  --BufferedImage  用来画图的宽高跟需要加水印的图片一样的空白图
     * @param img --需要加水印的图片
     * @param markImg --水印图片
     * @param width	--水印图片宽
     * @param height --水印图片高
     * @param x	--水印相对于底片的x轴坐标(PS:左上角为(0,0))
     * @param y  --水印相对于底片的y轴坐标(PS:左上角为(0,0))
     */
    public static void markPic(BufferedImage bufImg, Image img, Image markImg, int width, int height, int x, int y) {
        //取到画笔
        Graphics2D g = bufImg.createGraphics();
        //画底片
        g.drawImage(img, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);
        //画水印位置
        g.drawImage(markImg, x, y, width, height, null);
        g.dispose();
    }

    /**
     * 直接给multipartFile加上图片水印再进行保存图片的操作方便省事
     *
     * @param multipartFile
     *            文件上传的对象
     * @param markImg
     *            水印文件的路径 如果是相对路径请使用相对路径new Image的方法,此处用的是url
     * @return
     * @throws IOException
     * @author 高永强
     * @version 2018年11月30日 上午11:15:56
     */
    public static MultipartFile addPicMarkToMutipartFile(MultipartFile multipartFile,
                                                         String markImg) throws IOException {
        // 获取图片文件名 xxx.png xxx
        String originFileName = multipartFile.getOriginalFilename();
        // 获取原图片后缀 png
        int lastSplit = originFileName.lastIndexOf(".");
        String suffix = originFileName.substring(lastSplit + 1);
        // 获取图片原始信息
        String dOriginFileName = multipartFile.getOriginalFilename();
        String dContentType = multipartFile.getContentType();
        // 是图片且不是gif才加水印
        if (!suffix.equalsIgnoreCase("gif") && dContentType.contains("image")) {
            // 获取水印图片
            InputStream inputImg = multipartFile.getInputStream();
            Image img = ImageIO.read(inputImg);
            URL url = new URL(markImg);
            // 创建url连接;
            HttpURLConnection urlconn = (HttpURLConnection) url.openConnection();
            urlconn.connect();
            InputStream inputStream = urlconn.getInputStream();
            Image mark = ImageIO.read(inputStream);

            // 加图片水印
            int imgWidth = img.getWidth(null);
            int imgHeight = img.getHeight(null);

            int markWidth = mark.getWidth(null);
            int markHeight = mark.getHeight(null);

            BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight,
                BufferedImage.TYPE_INT_RGB);
            //水印的相对位置  ps:这里是右下角  水印宽为底片的四分之一  位置自己可以调整
            markPic(bufImg, img, mark, imgWidth / 4, (imgWidth * markHeight) / (4 * markWidth),
                imgWidth - imgWidth / 4, imgHeight - (imgWidth * markHeight) / (4 * markWidth));
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
            ImageIO.write(bufImg, suffix, imOut);
            InputStream is = new ByteArrayInputStream(bs.toByteArray());

            // 加水印后的文件上传
            multipartFile = new MockMultipartFile(dOriginFileName, dOriginFileName, dContentType, is);
        }
        //返回加了水印的上传对象
        return multipartFile;
    }

    /**
     * 加文字水印
     * @param bufImg --BufferedImage  用来画图的宽高跟需要加水印的图片一样的空白图
     * @param img --需要加水印的图片
     * @param text --水印文字
     * @param font --字体
     * @param degree --旋转角度
     * @param color --颜色
     * @param x  --水印相对于底片的x轴坐标(PS:左上角为(0,0))
     * @param y  --水印相对于底片的y轴坐标(PS:左上角为(0,0))
     * @author 高永强
     * @version 2018年11月30日 上午11:39:57
     */
    public static void markWord(BufferedImage bufImg, Image img, String text, Font font, Color color,Integer degree, int x, int y) {
        //取到画笔
        Graphics2D g = bufImg.createGraphics();
        //画底片
        g.drawImage(img, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);
        g.setColor(color);//设置水印颜色
        //g.setFont(font);//设置字体.设置字体后台linux系统中无法打印,故注释掉
        float alpha = 0.5f;//设置水印透明度 默认为1.0  值越小颜色越浅
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));//设置水印文字透明度
        if (null != degree) {
            g.rotate(Math.toRadians(degree),(double)bufImg.getWidth(),(double)bufImg.getHeight());//设置水印旋转
        }
        //位置
        g.drawString(text, x, y);
        JLabel label = new JLabel(text);
        FontMetrics metrics = label.getFontMetrics(font);
        int width = metrics.stringWidth(label.getText());//文字水印的宽
        int srcImgHeight = bufImg.getHeight();
        int srcImgWidth = bufImg.getWidth();
        int rowsNumber = srcImgHeight/width+srcImgHeight%width;// 图片的高  除以  文字水印的宽  打印的行数(以文字水印的宽为间隔)
        int columnsNumber = srcImgWidth/width+srcImgWidth%width;//图片的宽 除以 文字水印的宽  每行打印的列数(以文字水印的宽为间隔)
        //防止图片太小而文字水印太长,所以至少打印一次
        if(rowsNumber < 1){
            rowsNumber = 1;
        }
        if(columnsNumber < 1){
            columnsNumber = 1;
        }
        for(int j=0;j<rowsNumber;j++){
            for(int i=0;i<columnsNumber;i++){
                g.drawString(text, i*width + j*width, -i*width + j*width);//画出水印,并设置水印位置
            }
        }
        g.dispose();// 释放资源

    }

    /**
     * 直接给multipartFile加上文字水印再进行保存图片的操作方便省事
     *
     * @param multipartFile
     *            文件上传的对象
     * @param markImg
     *            水印文件的路径 如果是相对路径请使用相对路径new Image的方法,此处用的是url
     * @return
     * @throws IOException
     * @author 高永强
     * @version 2018年11月30日 上午11:15:56
     */
    public static MultipartFile addWorkMarkToMutipartFile(MultipartFile multipartFile,
                                                          String word) throws IOException {
        // 获取图片文件名 xxx.png xxx
        String originFileName = multipartFile.getOriginalFilename();
        // 获取原图片后缀 png
        int lastSplit = originFileName.lastIndexOf(".");
        String suffix = originFileName.substring(lastSplit + 1);
        // 获取图片原始信息
        String dOriginFileName = multipartFile.getOriginalFilename();
        String dContentType = multipartFile.getContentType();
        // 是图片且不是gif才加水印
        if (!suffix.equalsIgnoreCase("gif") && dContentType.contains("image")) {
            // 获取水印图片
            InputStream inputImg = multipartFile.getInputStream();
            Image img = ImageIO.read(inputImg);
            // 加图片水印
            int imgWidth = img.getWidth(null);
            int imgHeight = img.getHeight(null);

            BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight,
                BufferedImage.TYPE_INT_RGB);
            //设置字体
            Font font = new Font("宋体", Font.PLAIN, 14);
            //调用画文字水印的方法
            markWord(bufImg, img, word, font , Color.white,-45, imgWidth/8, imgHeight/8);
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
            ImageIO.write(bufImg, suffix, imOut);
            InputStream is = new ByteArrayInputStream(bs.toByteArray());

            // 加水印后的文件上传
            multipartFile = new MockMultipartFile(dOriginFileName, dOriginFileName, dContentType,
                is);
        }
        //返回加了水印的上传对象
        return multipartFile;
    }
    
}

MultipartFile 转 File工具


import org.springframework.web.multipart.MultipartFile;

import java.io.*;

/**
 * @author 卿通胜
 * @version 1.0
 * @date 2020/9/11 9:41
 */
public class MultipartFileUtil {

    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file){

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            try {
                ins = file.getInputStream();
                toFile = new File(file.getOriginalFilename());
                inputStreamToFile(ins, toFile);
                ins.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ins != null) {
                    try {
                        ins.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        OutputStream os = null;
        try {
            os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //释放资源
            if (ins != null) {
                try {
                    ins.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
        }
    }

    /**
     * 删除本地临时文件: 
     * @param file
     */
    public static void delteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }
}

文件上传依赖

<!--腾讯云oss-->
<dependency>
	<groupId>com.qcloud</groupId>
	<artifactId>cos_api</artifactId>
	<version>5.6.24</version>
</dependency>

腾讯云文件上传

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.utils.UuidUtils;

import java.io.File;
import java.util.List;

/**
 * 腾讯云oss
 *
 * @author 卿通胜
 * @version 1.0
 * @date 2020/9/8 15:29
 */
@Slf4j
public class TengXunOssUtil {

    public static final String URL_PREFIX = "https://findhouse-1302106834.cos.ap-chongqing.myqcloud.com/";

    // 1 初始化用户身份信息(secretId, secretKey)。
    private static String secretId = "填写腾讯云cos密钥id";
    private static String secretKey = "填写腾讯云cos密钥key";
    private static COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);

    private static String bucket = "填写存储桶名称"; //存储桶名称,格式:BucketName-APPID

    // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
    // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
    private static Region region = new Region("ap-chongqing");
    private static ClientConfig clientConfig = new ClientConfig(region);
    // 3 生成 cos 客户端。
    private static COSClient cosClient = new COSClient(cred, clientConfig);


    /**
     * 查询存储桶列表
     *
     * @return
     */
    public static List<Bucket> getBuckets() {
        List<Bucket> buckets = cosClient.listBuckets();
        for (Bucket bucketElement : buckets) {
            String bucketName = bucketElement.getName();
            String bucketLocation = bucketElement.getLocation();
        }
        return buckets;
    }

    /**
     * 上传文件
     *
     * @param localFile
     * @return 文件名称
     */
    public static String uploadFile(File localFile) {

        // 指定要上传到 COS 上对象键
        String filename = localFile.getName();
        String suffix = filename.substring(filename.lastIndexOf("."));//文件后缀
        filename = UuidUtils.getUUID() + suffix;

        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, filename, localFile);
        PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);

        return filename;
    }

    /**
     * 删除文件
     *
     * @param fileName 文件名称
     */
    public static void deletefile(String fileName) throws CosClientException, CosServiceException {

        // 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);

        //处理图片名称
        if (fileName.contains(TengXunOssUtil.URL_PREFIX)) {
            //如果文件名中包含了url前缀,则去掉
            fileName = fileName.replace(TengXunOssUtil.URL_PREFIX, "");
        }
        // 指定要删除的 bucket 和路径
        cosclient.deleteObject(bucket, fileName);

        // 关闭客户端(关闭后台线程)
        cosclient.shutdown();

    }

    /**
     *
     * @describe 上传文件的方法
     * @methods uploadObject 方法名
     * @param  fileUrl 上传文件地址
     * @param  fileKey 文件对象名称
     * @parameter @return 对象列表
     */
    public PutObjectResult uploadObject(String fileUrl, String fileKey) {
        try {
            // 指定要上传的文件
            File localFile = new File(fileUrl);
            // fileKey 指定要上传到 COS 上对象键
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, fileKey, localFile);
            PutObjectResult  putObjectResult = cosClient.putObject(putObjectRequest);
            return putObjectResult;
        } catch (CosServiceException serverException) {
            log.error(serverException.getErrorMessage());
            throw  new RuntimeException("上传文件平台Server异常"+serverException.getErrorMessage());
        } catch (CosClientException clientException) {
            log.error(clientException.getMessage());
            throw  new RuntimeException("上传文件平台Client异常"+clientException.getMessage());
        }

    }


    //测试
    /*public static void main(String [] args){
        try {

            File localFile = new File("F:\\找房快.jpg");
            uploadFile(localFile);

        }catch (Exception e){
            e.printStackTrace();
        }
    }*/

    /**
     * 测试删除
     * @param args
     */
    /*public static void main(String[] args) {
        deletefile("clipboard.png");
    }*/


}

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

解决上传图片到服务器 水印文字显示框框不显示文字的问题 ,java本地中文正确显示,服务器变成口口口
去此处: https://blog.csdn.net/lhq186/article/details/98621405

猜你喜欢

转载自blog.csdn.net/weixin_44684303/article/details/112515144