xiaoliuing
奔跑的小哥
采纳率66.7%
2015-06-09 07:23 阅读 1.7k
已采纳

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

3

要一个完整的例子,传入的参数最好是
源文件 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条回答 默认 最新

  • 已采纳
    tongyi55555 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;
        }
    }
    

    原始图像:

    图片说明

    结果图像:

    图片说明

    点赞 1 评论 复制链接分享
  • devmiao devmiao 2015-06-09 07:26
  • datou431 请叫我头头哥 2015-06-09 07:36

    用过滤器,等我上线给你,不要结问题哦
    package com.jc.ts.services;

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;

    import javax.imageio.ImageIO;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import com.sun.image.codec.jpeg.ImageFormatException;
    import com.sun.image.codec.jpeg.JPEGCodec;
    import com.sun.image.codec.jpeg.JPEGImageEncoder;

    /**
    *添加图片水印的服务类

    • / public class WaterMark { /*
      • @param sizeContext添加水印文字
      • @param request 请求流对象
      • @param request 响应流对象
      • / @SuppressWarnings("deprecation") public static void createMarkSize(String sizeContext,HttpServletRequest request,HttpServletResponse response) { try { String path=request.getRealPath(request.getServletPath()); FileInputStream in=new FileInputStream(path); Image src=ImageIO.read(in); int w=src.getWidth(null); int h=src.getHeight(null); BufferedImage img=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);//构建画板 Graphics g=img.getGraphics();//得到画笔 g.drawImage(src,0,0,w,h,null);//把源图片写入画板 g.setColor(Color.red); g.drawString(sizeContext,10,5); // 添加文字 g.dispose();//生成图片 JPEGImageEncoder e=JPEGCodec.createJPEGEncoder(response.getOutputStream()); e.encode(img); response.getOutputStream().close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ImageFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /*
      • @param localPath 添加水印LOGO路径
      • @param request 请求流对象
      • @param request 响应流对象 **/ @SuppressWarnings("deprecation") public static void createMarkLogo(String localPath,HttpServletRequest request,HttpServletResponse response) { try { FileInputStream file=new FileInputStream(localPath); Image fimg=ImageIO.read(file); int fw=fimg.getWidth(null); int fh=fimg.getHeight(null); String path=request.getRealPath(request.getServletPath()); FileInputStream in=new FileInputStream(path); Image src=ImageIO.read(in); int w=src.getWidth(null); int h=src.getHeight(null); BufferedImage img=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);//构建画板 Graphics g=img.getGraphics();//得到画笔 g.drawImage(src,0,0,w,h,null);//把原图片写入画板 g.drawImage(fimg,w-20,h-15,fw,fh,null);//把水印图片写入画板 g.dispose();//生成图片 JPEGImageEncoder e=JPEGCodec.createJPEGEncoder(response.getOutputStream()); e.encode(img); response.getOutputStream().close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ImageFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    }

      /** 
    * @param localPath 添加水印图片路径
    * @param request 请求流对象
    * @param request 响应流对象
                  * @param width   水印图片的宽度
                  * @param height  水印图片的长度
    **/
    @SuppressWarnings("deprecation")
    

    public static void createMarkLogo(String localPath,HttpServletRequest request,HttpServletResponse response,int width,int height) {
    try {
    FileInputStream file=new FileInputStream(localPath);
    Image fimg=ImageIO.read(file);
    int fw=fimg.getWidth(null);
    int fh=fimg.getHeight(null);
    String path=request.getRealPath(request.getServletPath());
    FileInputStream in=new FileInputStream(path);
    Image src=ImageIO.read(in);
    int w=src.getWidth(null);//w为你过滤图片的宽度
    int h=src.getHeight(null);//h为你过滤图片的长度
    BufferedImage img=new BufferedImage(w+width,h+height,BufferedImage.TYPE_INT_RGB);//构建画板(画板的宽度为两个图片之和)
    Graphics g=img.getGraphics();//得到画笔
    g.drawImage(src,0,0,w,h,null);//把原图片写入画板
    g.drawImage(fimg,width,height,fw,fh,null);//把水印图片写入画板
    g.dispose();//生成图片
    JPEGImageEncoder e=JPEGCodec.createJPEGEncoder(response.getOutputStream());
    e.encode(img);
    response.getOutputStream().close();
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (ImageFormatException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    }

    注意第三个方法的注释地方g.drawImage(fimg,width,height,fw,fh,null);根据参数你在调调(放原图下面的)

    过滤器调用
    package com.jc.ts.filter;

    import java.io.IOException;

    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import com.jc.ts.services.WaterMark;

    public class WaterFilter implements Filter {

    public void destroy() {
    // TODO Auto-generated method stub

    }
    public void doFilter(ServletRequest arg0, ServletResponse arg1,
    FilterChain arg2) throws IOException, ServletException {
    HttpServletRequest request=(HttpServletRequest)arg0;
    HttpServletResponse response=(HttpServletResponse)arg1;
    //WaterMark.createMarkSize("南京ts", request, response);
    //WaterMark.createMarkLogo("D:\workspace\mybook\WebRoot\images\logo\book.jpg", request, response);
    WaterMark.createMarkLogo("D:\workspace\mybook\WebRoot\images\logo\book.jpg", request, response,20,30);
    //注意路径为绝对路径且三个效果不能同时执行

    }

    public void init(FilterConfig arg0) throws ServletException {
    // TODO Auto-generated method stub

    }

    }

    web.xml配置(写在servlet上面)


    This is the description of my J2EE component
    This is the display name of my J2EE component
    WaterFilter
    com.jc.ts.filter.WaterFilter

    希望你能满意。。。。。。

    点赞 评论 复制链接分享
  • sxjiangdongqin 45度向上倾斜 2015-06-10 00:13

    import java.awt.*;
    import java.awt.image.*;
    import java.io.*;
    import javax.swing.*;
    import com.sun.image.codec.jpeg.*;
    public class WaterSet {
    /** //*
    * 给图片添加水印
    *
    * @param filePath
    * 需要添加水印的图片的路径
    * @param markContent
    * 水印的文字
    * @param markContentColor
    * 水印文字的颜色
    * @param qualNum
    * 图片质量
    * @return
    */
    public boolean createMark(String filePath, String markContent,
    Color markContentColor, float qualNum) {
    ImageIcon imgIcon = new ImageIcon(filePath);
    Image theImg = imgIcon.getImage();
    int width = theImg.getWidth(null);
    int height = theImg.getHeight(null);
    BufferedImage bimage = new BufferedImage(width, height,
    BufferedImage.TYPE_INT_RGB);
    Graphics2D g = bimage.createGraphics();
    g.setColor(markContentColor);
    g.setBackground(Color.white);
    g.drawImage(theImg, 0, 0, null);
    g.drawString(markContent, width / 5, height / 5); // 添加水印的文字和设置水印文字出现的内容
    g.dispose();
    try {
    FileOutputStream out = new FileOutputStream(filePath);
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
    param.setQuality(qualNum, true);
    encoder.encode(bimage, param);
    out.close();
    } catch (Exception e) {
    return false;
    }
    return true;
    }
    }

    点赞 评论 复制链接分享

相关推荐