Java之Graphics2D图片生成水印

目录

一、介绍

二、效果图

三、代码

四、优化方向

五、参考链接


一、介绍

百度百科:Graphics2D ,Graphics 类,提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制

不止通过JDK提供的工具类,还可以使用第三方的Thumbnailator工具,进行添加水印、制作缩略图等功能

二、效果图

1、生成水印前:

2、生成水印后:

三、代码

public class WaterMarkUtil {

    private final static String[] IMAGE_TYPE = {"PNG","JPEG","JPG", "BMP", "GIF"};

    private final static int HEADER_SIZE = 4;

    public static byte[] getImageWithWaterMark(InputStream inputStream, String waterMarkContent) throws Exception {
        if(null == inputStream){
            throw new Exception("输入流不能为空");
        }

        if(null == waterMarkContent || waterMarkContent.isEmpty()){
            throw new Exception("水印内容不能为空");
        }

        // 封装为BufferedInputStream,用于流文件类型读取后的重置
        BufferedInputStream bufferedInputStream  = new BufferedInputStream(inputStream);
        // 标记读取的文件类型长度
        bufferedInputStream.mark(HEADER_SIZE);

        // 获取文件类型
        String fileType = getFileType(bufferedInputStream);

        // 重置流到开始位置
        bufferedInputStream.reset();

        // 判断是否图片,否则结束处理
        boolean isImage = matchImageType(fileType);
        if(!isImage){
            throw new Exception("文件类型非图片类型,支持:png、jpeg、jpg、bmp、gif,当前文件类型:" + fileType);
        }

        BufferedImage targetImg = ImageIO.read(bufferedInputStream);
        int height = targetImg.getHeight();
        int width = targetImg.getWidth();

        //-------------------------文字水印 start----------------------------
        BufferedImage waterMarkImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 创建画笔
        Graphics2D graphics2D = waterMarkImage.createGraphics();
        // 绘制原始图片
        graphics2D.drawImage(targetImg, 0, 0, width, height, null);

        // 设置水印颜色
        graphics2D.setColor(new Color(255, 255, 255, 50));

        double scale = 1.0;
        if(width < height){
            scale = (double) width / height;
        }
        int fontSize = (int) Math.ceil((double) (height / 25) * scale);
        // 设置字体 画笔字体样式为微软雅黑,加粗,文字大小按比例给
        graphics2D.setFont(new Font("微软雅黑", Font.BOLD, fontSize));

        // 水印旋转度
        graphics2D.rotate(Math.toRadians(-25), (double) width / 2, (double) height / 2);

        int x = -width * 3;
        int y;
        // 计算水印文字的宽度
        FontMetrics fontMetrics = graphics2D.getFontMetrics();
        int watermarkWidth = fontMetrics.stringWidth(waterMarkContent);
        // 水印横向间隔
        int positionWidth = (int)(width * 0.15);
        // 水印竖向间隔
        int positionHeight  = (int)(height * 0.15);

        while (x < width * 3) {
            y = -height * 3;
            while (y < height * 3) {
                graphics2D.drawString(waterMarkContent, x, y);
                y += fontSize + positionWidth;
            }
            x += watermarkWidth + positionHeight;
        }

        graphics2D.dispose();
        //-------------------------文字水印 end----------------------------

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(waterMarkImage, fileType, byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }

    private static boolean matchImageType(String fileType){
        if(null == fileType || fileType.isEmpty()){
            return false;
        }

        for (String type : IMAGE_TYPE) {
            if (fileType.equalsIgnoreCase(type)) {
                return true;
            }
        }

        return false;
    }


    private static String getFileType(InputStream is){
        String fileType = null;
        String fileHeader;
        byte[] temp = new byte[HEADER_SIZE];

        try {
            is.read(temp, 0, HEADER_SIZE);
            // 将读取到的字节数组转为十六进制字符串,,方法来自apache的commons-codec包
            fileHeader = Hex.encodeHexString(temp).toUpperCase();

            // 以下罗列几种类型,更多自行拓展
            if (fileHeader.contains("504B0304")) {

                fileType = "xlsx";
            } else if (fileHeader.contains("FFD8FF")) {

                fileType = "jpg";
            } else if (fileHeader.contains("89504E47")) {

                fileType = "png";
            } else if (fileHeader.contains("47494638")) {

                fileType = "gif";
            } else if (fileHeader.contains("25504446")) {

                fileType = "pdf";
            } else if (fileHeader.contains("424D")) {

                fileType = "bmp";
            } else {

                fileType = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return fileType;
    }


}

四、优化方向

目前这个版本的水印生成还是有局限性的,比如:图片太小、水印内容太长之类的问题,会导致生成的效果有问题,所有如果你遇到这种情况,可以通过以下的方面进行优化:

1、水印文字大小按照图片等比例进行控制

2、限制水印文字大小,水印宽度不得超过图片宽度的百分之多少,通过水印宽度反出水印文字字数过多

3、限制图文长度与宽度,过小就不生成,或者只生成一个水印之类的

五、参考链接

Java实现给图片加单个、多个文字水印_java添加多个水印_斯内克喜欢吃益达的博客-CSDN博客

java实现给图片添加水印(文字水印或图片水印)_12程序猿的博客-CSDN博客 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用JavaGraphics2D类压缩图片,你可以按照以下步骤: 1. 载要压缩的图片,可以使用ImageIO类: ```java BufferedImage originalImage = ImageIO.read(new File("path/to/image")); ``` 2. 创建一个新的BufferedImage对象,设置它的宽度和高度为原始图像的一半,或者其他你想要的压缩比例: ```java int originalWidth = originalImage.getWidth(); int originalHeight = originalImage.getHeight(); int newWidth = originalWidth / 2; // 压缩一半 int newHeight = originalHeight / 2; // 压缩一半 BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, originalImage.getType()); ``` 3. 获取Graphics2D对象,用它来绘制压缩后的图像: ```java Graphics2D g2d = compressedImage.createGraphics(); g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null); g2d.dispose(); ``` 4. 最后,将压缩后的图像保存到文件或输出流中,可以使用ImageIO类: ```java ImageIO.write(compressedImage, "jpg", new File("path/to/compressed/image.jpg")); ``` 完整的代码: ```java import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class ImageCompressor { public static void main(String[] args) throws Exception { BufferedImage originalImage = ImageIO.read(new File("path/to/image")); int originalWidth = originalImage.getWidth(); int originalHeight = originalImage.getHeight(); int newWidth = originalWidth / 2; // 压缩一半 int newHeight = originalHeight / 2; // 压缩一半 BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, originalImage.getType()); Graphics2D g2d = compressedImage.createGraphics(); g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null); g2d.dispose(); ImageIO.write(compressedImage, "jpg", new File("path/to/compressed/image.jpg")); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值