Java 阿里云图片添加水印

该博客介绍了如何使用阿里云OSS SDK在已上传的图片上添加文字水印,并将处理后的图片覆盖原图。代码示例展示了如何创建OSSClient,检查文件是否存在,添加水印,以及上传处理后的图片。水印位置在图片左上角,颜色可定制,支持多行文字。此外,还提供了计算单个字符长度的辅助方法。
摘要由CSDN通过智能技术生成

图片已经上传阿里云,打完文字水印后重新上传,顶替原图片

public void watermark(){
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessId = ossConfig.getAccessId();
    String accessKey = ossConfig.getAccessKey();
    // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
    String endpoint = ossConfig.getEndpoint();
    // 填写Bucket名称,例如examplebucket。
    String bucket = ossConfig.getBucket();
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, accessKey);
    //oss中文件名
    String objectName = "undefined2022/03/31/c9dfebb468440be08b3f9f9d3f281d9.jpg";
    try{
        //判断文件是否存在。如果返回值为true,则文件存在,否则存储空间或者文件不存在。
        boolean found = ossClient.doesObjectExist(bucket, objectName);
        if(found){
        	List<String> list = new ArrayList<>();
        	list.add("时间:2020");
        	list.add("经度:111");
        	list.add("纬度:23");
        	String sbuff = "png";
        	//打水印和上传,因为我是很多文件处理,所以抽取方法
        	upload(ossClient,bucket,objectName,list,sbuff);
        }
        }catch(Exception e){
        	e.printStackTrace();
        }finally {
        if (ossClient != null) {
        	ossClient.shutdown();
        }
    }
}
/**
     * 
     * @param ossClient OSSClient实例
     * @param bucket Bucket名称
     * @param objectName 文件名称
     * @param list 文字水印内容
     * @param sbuff 文件后缀名
     * @throws Exception
     */
public void upload(OSS ossClient, String bucket, String objectName,List<String> list, String sbuff) throws Exception{
    try {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSObject ossObject = ossClient.getObject(bucket, objectName);
        //获取文件流,转成Image
        Image img = ImageIO.read(ossObject.getObjectContent());
        //图片打完水印再转为文件流,然后重新上传到阿里云
        InputStream inputStream = ImgUtil.addWorkMarkUpperLeftToInputStreamFile(img, list, sbuff);
        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, inputStream);
        // ossObject对象使用完毕后必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
        // 上传文件。
        ossClient.putObject(putObjectRequest);
        ossObject.close();
    } catch (OSSException oe) {
        System.out.println("Caught an OSSException, which means your request made it to OSS, "
                + "but was rejected with an error response for some reason.");
        System.out.println("Error Message:" + oe.getErrorMessage());
        System.out.println("Error Code:" + oe.getErrorCode());
        System.out.println("Request ID:" + oe.getRequestId());
        System.out.println("Host ID:" + oe.getHostId());
    } catch (Throwable ce) {
        System.out.println("Caught an ClientException, which means the client encountered "
                + "a serious internal problem while trying to communicate with OSS, "
                + "such as not being able to access the network.");
        System.out.println("Error Message:" + ce.getMessage());
    }
}

打水印方法

// 水印文字颜色
private static Color color = new Color(255, 255, 255);

/**
     * 单个字符长度
     *
     * @Param [c, g]
     * @Author: Smily
     * @Date: 2020/9/9 14:20
     */
    public static int getCharLen(char c, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charWidth(c);
    }

/**
     * 
     * @param img 图片
     * @param logoText 文字水印内容
     * @param suffix 图片后缀名
     * @return
     * @throws IOException
     */
    public static InputStream addWorkMarkUpperLeftToInputStreamFile(Image img, List<String> logoText, String suffix) throws IOException {
       //获取图片大小
        int width = img.getWidth(null);
        int height = img.getHeight(null);
        //通过原图计算出字体大小
        int FONT_SIZE = width / 27;
        //设置字体
        Font font = new Font("宋体", Font.BOLD, FONT_SIZE);

        //画图,获取与原来图片大小一样的画布
        BufferedImage bufImg = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        // 得到画笔
        Graphics2D g = bufImg.createGraphics();
        // 对线段的锯齿状边缘处理
        g.setRenderingHint (RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        //水印图片的坐标点
        g.drawImage(img, 0, 0, width, height, null);
        // 设置水印文字颜色
        g.setColor (color);
        // 设置水印文字Font
        g.setFont (font);
        // 设置水印文字透明度
        g.setComposite(AlphaComposite.getInstance (AlphaComposite.SRC_ATOP, 0.8f));

        int x,y;//水印文字x轴原点,水印文字y轴原点
        //添加多行文字水印,水印文字也在图片左上角
        for (int i = 0;i < logoText.size();i++){
            if (!logoText.get(i).contains("地点")){
                x = 15;
                y = (i + 2) * FONT_SIZE;
                g.drawString (logoText.get(i), x, y);
            }else {
                //如果包含地址信息,文字可能超过图片宽度,这时需要换行操作(注意:地址信息一定要在logoText数组的最后一个)
                x = 15;
                y = (i + 2) * FONT_SIZE;
                int tempCharLen = 0;//单字符长度
                int tempLineLen = 0;//单行字符总长度
                StringBuffer sb = new StringBuffer();
                for (int j = 0; j < logoText.get(i).length(); j++) {
                    char tempChar = logoText.get(i).charAt(j);
                    tempCharLen = getCharLen(tempChar, g);
                    tempLineLen += tempCharLen;
                    //判断长度时,将照片宽度减少一个字体的长度
                    if (tempLineLen >= width - tempCharLen) {
                        //长度已经满一行,进行文字叠加
                        g.drawString(sb.toString(), x, y);
                        //清空内容,重新赋值追加
                        sb.delete(0, sb.length());
                        int k = (i + 2);
                        k++;
                        y = k * FONT_SIZE;
                        tempLineLen = 0;
                    }
                    sb.append(tempChar);//追加字符
                }
                //最后叠加余下的文字
                g.drawString(sb.toString(), x, y);
            }
        }
        g.dispose();

        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
        ImageIO.write(bufImg, suffix, imOut);
        InputStream is = new ByteArrayInputStream(bs.toByteArray());
        //返回加了水印的上传对象
        return is;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值