奔跑的小哥 2015-06-09 07:23 采纳率: 66.7%
浏览 1766
已采纳

怎么用java图片加文字水印ne

要一个完整的例子,传入的参数最好是
源文件 byte[] 文字内容

返回的是加水印之后的 byte[]

最好有注释,谢谢了

Exception in thread "main" sun.misc.ServiceConfigurationError: javax.imageio.spi.ImageReaderSpi: Provider it.geosolutions.imageio.stream.input.spi.FileImageInputStreamExtImplSpi not a subtype at sun.misc.Service.fail(Service.java:129) at sun.misc.Service.access$000(Service.java:111) at sun.misc.Service$LazyIterator.next(Service.java:278) at javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(IIORegistry.java:190) at javax.imageio.spi.IIORegistry.(IIORegistry.java:121) at javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:142) at javax.imageio.ImageIO.(ImageIO.java:48) at com.xiaoliu.mobile.WaterMarker.changeImg2Byte(WaterMarker.java:64) at com.xiaoliu.mobile.WaterMarker.main(WaterMarker.java:36)


  • 写回答

4条回答 默认 最新

  • JonsonJiao 2015-06-09 08:59
    关注

    以下是根据byte[]对象来进行文字水印的添加,主要涉及的就是图像对象如何与byte[]数组转换的问题,还是使用图像画笔进行的水印添加,水印文字添加在图像的正中央。
    可根据需要修改水印字体样式和透明度。代码如下:

    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import javax.imageio.ImageIO;
    
    /**
     * 文字水印
     * 参考 http://sjsky.iteye.com/blog/1154390
     * 参考
     */
    public class ImageMarkLogoByText {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            String srcImgPath = "d:/01.jpg";
            String logoText = "[ 测试文字水印 http://ask.csdn.net]";
            String targerPath = "d:/img_mark_text.jpg";
    
            // 现在已知的是图片路径,所以需要自己转换成byte数组,如果你有byte数组直接使用下面的方法
            byte[] srcImgByte = changeImg2Byte(srcImgPath);
    
            // 给图片添加水印,需要传入文字和图片的byte数组,返回结果是加了水印的图片byte[]对象
            byte[] resultByte = ImageMarkLogoByText
                    .markByText(logoText, srcImgByte);
    
            // 为了便于查看,下面对结果进行了输出
            BufferedImage resultImage = changeByte2Img(resultByte);
            try {
                ImageIO.write(resultImage, "JPG", new FileOutputStream(targerPath));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        /**
         * 根据传入的图像文件路径读取图像,并存入到byte数组中。
         * 
         * @param srcImgPath
         * @return
         */
        private static byte[] changeImg2Byte(String srcImgPath) {
            // TODO Auto-generated method stub
            try {
                BufferedImage image = ImageIO.read(new File(srcImgPath));
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(image, "jpg", out);
                byte[] b = out.toByteArray();
                return b;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 给图片添加文字水印
         * 
         * @param logoText
         * @param srcByteImg
         */
        public static byte[] markByText(String logoText, byte[] srcByteImg) {
            InputStream is = null;
            ByteArrayOutputStream os = null;
            try {
    
                // 获取image对象,没有他做不了绘制
                BufferedImage buffImg = changeByte2Img(srcByteImg);
    
                // 得到画笔对象
                Graphics2D g = buffImg.createGraphics();
    
                // 设置对线段的锯齿状边缘处理
                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    
                int width = buffImg.getWidth(null);
                int height = buffImg.getHeight(null);
                g.drawImage(buffImg.getScaledInstance(width, height,
                        Image.SCALE_SMOOTH), 0, 0, null);
    
                // 设置颜色
                g.setColor(Color.red);
    
                // 设置 Font
                g.setFont(new Font("宋体", Font.BOLD, 30));
                FontMetrics fontMetrics = g.getFontMetrics();
                int logoWidth = fontMetrics.stringWidth(logoText);
                // 设置水印的透明度
                float alpha = 0.5f;
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                        alpha));
    
                // 第一参数->设置的内容,后面两个参数->文字左上角在图片上的坐标位置(x,y),简单点设置文字在中心,竖直方向有些偏差 .
                g.drawString(logoText, (width - logoWidth) / 2, height / 2
                        +fontMetrics.getAscent()/2 - fontMetrics.getDescent()/2);
    
                g.dispose();
    
                // 生成图片
                os = new ByteArrayOutputStream();
                ImageIO.write(buffImg, "JPG", os);
                System.out.println("图片完成添加文字印章。。。。。。");
                // 返回图片的byte数组
                return os.toByteArray();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != is)
                        is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    if (null != os)
                        os.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
        /**
         * 根据传入的图像byte数组转换成图像
         * 
         * @param srcByteImg
         * @return
         */
        private static BufferedImage changeByte2Img(byte[] srcByteImg) {
            // TODO Auto-generated method stub
            ByteArrayInputStream in = new ByteArrayInputStream(srcByteImg);
            try {
                BufferedImage image = ImageIO.read(in);
                return image;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    }
    

    原始图像:

    图片说明

    结果图像:

    图片说明

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 运筹学中在线排序的时间在线排序的在线LPT算法
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试,帮帮忙吧