给图片添加文字水印

@如何给图片添加文字水印??????

思路:将文字生成一张图片,再将该图片作为水印覆盖到源文件

网上:关于直接添加文字水印的方法,试了很多种无论怎么调试,都会因为文字的长度导致水印排版异常,只适合添加固定长度的文字水印,并不适合拓展延伸。

代码直接粘贴如下:

	//可能引用的包
	import javax.imageio.ImageIO;
	import javax.swing.*;
	import java.awt.*;
	import java.awt.font.FontRenderContext;
	import java.awt.geom.Rectangle2D;
	import java.awt.image.BufferedImage;
	import java.io.ByteArrayOutputStream;
	import java.io.File;
	import java.io.FileOutputStream;
	import java.io.IOException;

	//代码
   /**
     * 生成背景透明的文字水印,文字位于透明区域正中央,可设置旋转角度
     * @param word   水印文字
     * @param color  颜色
     * @param path   文字转水印后的文件地址
     * @param degree 水印文字旋转角度
     * @param alpha  水印不透明度0f-1.0f
     */
    public static String createWordImage(String word, String path, Color color, Double degree, float alpha) throws IOException {
        File outFile = new File(path);
        Font font = new Font("微软雅黑", Font.PLAIN, 350);
        //设置一个分辨率高的画布,分辨率低了,生成水印覆盖到源文件上时会出现锯齿状,无法通过设置去除锯齿边缘。
        int width = 2550;   //画布宽
        int height = 690;   //画布高
        //1,创建画布 生成像素 2550*690  像素高一点避免出现生成的图会有锯齿状
        BufferedImage buffImg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        /**2,得到画笔对象*/
        Graphics2D g2d = buffImg.createGraphics();
        // ----------  增加下面的代码使得背景透明  -----------------
        buffImg = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = buffImg.createGraphics();
        // ----------  背景透明代码结束  -----------------

        // 设置对线段的锯齿状边缘处理    这里设置作用不大,只有画布分辨率高,才能解决锯齿状
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        // 设置水印旋转
        if (null != degree) {
            //注意rotate函数参数theta,为弧度制,故需用Math.toRadians转换一下 以矩形区域中央为圆心旋转
            g2d.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
        }
        // 设置颜色
        g2d.setColor(color);
        // 设置 Font
        g2d.setFont(font);
        //设置透明度:1.0f为透明度 ,值从0-1.0,依次变得不透明
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));

        //获取真实宽度
        float realWidth = getRealFontWidth(word);
        float fontSize = font.getSize();
        //计算绘图偏移x、y,使得使得水印文字在图片中居中 这里需要理解x、y坐标是基于Graphics2D.rotate过后的坐标系
        float x = 0.5f * width - 0.5f * fontSize * realWidth;
        float y = 0.5f * height + 0.5f * fontSize;
        //取绘制的字串宽度、高度中间点进行偏移,使得文字在图片坐标中居中
        g2d.drawString(word, x, y);
        //释放资源
        g2d.dispose();
        if (outFile != null) {
            //输出png图片到指定目录
            ImageIO.write(buffImg, "png", outFile);
        }
        //返回数据流
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        boolean flag = ImageIO.write(buffImg, "png", out);
        if (flag) {
            return path;
        }
        return null;
    }
	
    /**
     * 获取真实字符串宽度,ascii字符占用0.5,中文字符占用1.0
     */
    private static float getRealFontWidth(String text) {
        int len = text.length();
        float width = 0f;
        for (int i = 0; i < len; i++) {
            if (text.charAt(i) < 256) {
                width += 0.5f;
            } else {
                width += 1.0f;
            }
        }
        return width;
    }

	//加水印过程
   	/**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        String source = "C:\\Users\\Administrator\\Desktop\\11111.jpg";  	//要加水印的源文件图片
        String imageType = "png"; 											//图片类型jpg,jpeg,png,gif
        String imageName = System.currentTimeMillis() + "IMG_603222" + "." + imageType; //生成的图片名称
        String output = "D:\\photo\\" + imageName + imageType;  //保存地址
        String word = "文字水印";								//文字长度暂无限制,可根据实际情况自行测试调整
        String newicon = "D:\\photo\\newlogo.png"; 				//组合生成后的logo图路劲 
        Integer degree = null; 									//水印旋转角度-45,null表示不旋转
 
        //生成文字水印
        String logo = createWordImage(text, output + System.currentTimeMillis() + ".png", Color.BLACK, null, 0.1f);
        //加水印
        String url = markImageByMoreLogo(logo, newicon, new File(source), output, degree);
        System.out.println("加水印后文件地址:" + url);
    }
    /**
     * @Description : 平铺水印,根据水印设置的不同方式展示效果 
     * @param: [
     * logo:原水印文件地址
     * , newicon:覆盖水印后的地址
     * , source:要加水印的源文件
     * , output:图片存储地址
     * , outArtwork:输出地址
     * , imageName:图片名称
     * , imageType:图片类型
     * , degree:水印旋转角度,null表示不旋转
     * , logoNum:水印的设置展示方式,目前有5种样式效果
     * ] 
     */
    public static String markImageByMoreLogo(String logo, String newicon, File source, String output, Integer degree) {
        try {
            if (!source.isFile()) {
                return source + " 不是一个图片文件!";
            }
            //将源图片读到内存中
            Image img = ImageIO.read(source);
            //图片宽
            int width = img.getWidth(null);
            //图片高
            int height = img.getHeight(null);
            //调整水印宽度
            ImageWaterMarkUtil.resizeImage(logo, newicon, (int) (width / 3.5));
            //将logo读到内存中
            File ficon = new File(newicon);
            //将icon加载到内存中
            Image ic = ImageIO.read(ficon);
            //icon高度
            int icheight = ic.getHeight(null);
            //icon宽度
            int icwidth = ic.getWidth(null);
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //创建一个指定 BufferedImage 的 Graphics2D 对象
            Graphics2D g = bi.createGraphics();
            //水印宽度  水印宽度 = 2(图片宽度)/(3logoNum + 1)
            int temp2 = icwidth;
            //水印间隔  水印宽度/2
			// int space2 = icwidth / 2;
            //默认两张水印图片的  间隔高度  是水印的高度的2倍
            int temp = 2 * icheight;
            //水印高个数
            int space = height / 3 / icheight;
            //初始化图片位置
            int x = 0;
            int y = icheight;
            //设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

            //呈现一个图像,在绘制前进行从图像空间到用户空间的转换
            g.drawImage(img.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
            //透明度,最小值为0,最大值为1
            float clarity;
            for (int i = 0; i < space; i++) {
                //水印图象的地址 水印一般为gif或者png的,这样可设置透明度
                ImageIcon imgIcon = new ImageIcon(newicon);
                //得到Image对象。
                Image con = imgIcon.getImage();
                //透明度,最小值为0,最大值为1
                clarity = 1f;
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, clarity));
                //表示水印图片的坐标位置(x,y)
                //g.drawImage(con, 300, 220, null);
                x = icwidth / 2;
                if (null != degree) {
                    //设置水印旋转
                    g.rotate(Math.toRadians(degree), (double) x + icwidth / 2, (double) y + icheight / 2);
                }
                //给图片横向加水印
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, clarity));
                //表示水印图片的坐标位置(x,y)
                g.drawImage(con, x, y, null);
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
                if (null != degree) {
                    //设置水印旋转
                    g.rotate(Math.toRadians(-degree), (double) x + icwidth / 2, (double) y + icheight / 2);
                }
                x += 3 * temp2 / 2;
                y += (icheight + temp);
                //给图片纵向加水印
                g.drawImage(con, x, y, null);
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            }
            g.dispose();
            //保存原图
            try {
                // 输出 文件 到指定的地址
                FileOutputStream out = new FileOutputStream(output);
                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
                JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
                param.setQuality(1, true);
                encoder.encode(bi, param);
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            ficon.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return output;
    }
    
   /**
     * 修改logo的像素 
     * @param srcPath   源图片地址
     * @param desPath   修改大小后图片地址
     * @param scaleSize 图片的修改比例,目标宽度
     */
    public static void resizeImage(String srcPath, String desPath, int scaleSize) throws IOException {
        File srcFile = new File(srcPath);
        Image srcImg = ImageIO.read(srcFile);
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(srcFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        float width = bi.getWidth(); // 像素
        float height = bi.getHeight(); // 像素
        float scale = width / scaleSize;
        BufferedImage buffImg = null;
        buffImg = new BufferedImage(scaleSize, (int) (height / scale),
                BufferedImage.TYPE_INT_RGB);
        //保持Png图片的透明背景属性
        Graphics2D g = buffImg.createGraphics();
        buffImg = g.getDeviceConfiguration().createCompatibleImage(scaleSize, (int) (height / scale), Transparency.TRANSLUCENT);
        g = buffImg.createGraphics();
        //使用TYPE_INT_RGB修改的图片会变色
        buffImg.getGraphics().drawImage(
                srcImg.getScaledInstance(scaleSize, (int) (height / scale), Image.SCALE_SMOOTH), 0,
                0, null);
        //压缩保存
        //boolean ff=ImageIO.write(buffImg, "PNG", new File(desPath));
        // 输出 文件 到指定的地址
        FileOutputStream out = new FileOutputStream(desPath);
        try {
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(buffImg);
            param.setQuality(1, true);
            encoder.encode(buffImg, param);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
    }
 	
 	// 给图片加文字水印,结束。
		//给视频加水印的方式建议先用文字生成图片。






  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Android上使用OpenCV给图片添加文字水印可以通过以下步骤实现: 1. 导入OpenCV库:首先需要在Android项目中导入OpenCV库文件,可以从OpenCV官方网站下载或者使用Gradle依赖方式导入。 2. 图片加载:使用Android提供的方式加载需要加水印图片,例如使用BitmapFactory.decodeResource()方法加载本地资源图片,或者使用第三方库加载网络图片。 3. 创建OpenCV Mat对象:使用OpenCV库提供的Mat类,将加载的图片转为Mat对象用于后续操作。可以使用Imgcodecs.imread()方法将Bitmap转为Mat。 4. 添加文字水印:使用OpenCV提供的绘制文本的方法将文字水印添加到Mat对象中。可以使用Imgproc.putText()方法指定水印的位置、文本内容、颜色、字体大小等参数。 5. 转换为Bitmap:将带有水印的Mat对象转换为Bitmap对象。可以使用Bitmap.createBitmap()方法将Mat转为Bitmap。 6. 保存图片:可以选择将带有水印的Bitmap保存到本地存储器或者上传到服务器。使用Bitmap.compress()方法可以将Bitmap对象转为文件输出流,然后保存到指定路径。 需要注意的是,在添加文字水印之前,可能需要对图片进行一些预处理,例如调整大小、旋转、裁剪等操作,可以使用OpenCV提供的相关方法。 以上是使用OpenCV在Android上给图片文字水印的简要步骤说明,具体实现可以参考OpenCV官方文档和相关示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值