如何在Java中为图像添加水印?

时间:2011-03-28 13:30:25

标签: java image watermark

如何使用Java在图像上创建水印?我需要将用户输入的文本添加到图像上的提供位置。任何示例代码/建议都会有所帮助。

7 个答案:

答案 0 :(得分:9)

Thumbnailator中,可以使用Caption图片过滤器为现有图片添加文字标题:

// Image to add a text caption to.
BufferedImage originalImage = ...;

// Set up the caption properties
String caption = "Hello World";
Font font = new Font("Monospaced", Font.PLAIN, 14);
Color c = Color.black;
Position position = Positions.CENTER;
int insetPixels = 0;

// Apply caption to the image
Caption filter = new Caption(caption, font, c, position, insetPixels);
BufferedImage captionedImage = filter.apply(originalImage);

在上面的代码中,文字Hello World将以originalImage为中心绘制,使用等宽字体,黑色前景色,14 pt。

或者,如果要将水印图像应用于现有图像,可以使用Watermark图像过滤器:

BufferedImage originalImage = ...;
BufferedImage watermarkImage = ...;

Watermark filter = new Watermark(Positions.CENTER, watermarkImage, 0.5f);
BufferedImage watermarkedImage = filter.apply(originalImage);

以上代码会将watermarkImage叠加在originalImage之上,以不透明度50%为中心。

Thumbnailator将在普通的旧Java SE上运行 - 一个不必安装任何第三方库。 (但是,需要使用Sun Java运行时。)

完全披露:我是Thumbnailator的开发者。

答案 1 :(得分:5)

答案 2 :(得分:3)

我最近有类似的需求,发现这篇文章非常有用: http://www.codeyouneed.com/java-watermark-image/

水印方法使用ImgScalr在需要时调整水印大小,并支持在图像的底部/顶部放置文本+水印图像。

为了选择正确的位置,它使用简单的ENUM

public enum PlacementPosition {
    TOPLEFT, TOPCENTER, TOPRIGHT, MIDDLELEFT, MIDDLECENTER, MIDDLERIGHT, BOTTOMLEFT, BOTTOMCENTER, BOTTOMRIGHT
}

整个水印逻辑就是这个方法:

/**
 * Generate a watermarked image.
 * 
 * @param originalImage
 * @param watermarkImage
 * @param position
 * @param watermarkSizeMaxPercentage
 * @return image with watermark
 * @throws IOException
 */
public static BufferedImage watermark(BufferedImage originalImage,
        BufferedImage watermarkImage, PlacementPosition position,
        double watermarkSizeMaxPercentage) throws IOException {

    int imageWidth = originalImage.getWidth();
    int imageHeight = originalImage.getHeight();

    int watermarkWidth = getWatermarkWidth(originalImage, watermarkImage,
            watermarkSizeMaxPercentage);
    int watermarkHeight = getWatermarkHeight(originalImage, watermarkImage,
            watermarkSizeMaxPercentage);

    // We create a new image because we want to keep the originalImage
    // object intact and not modify it.
    BufferedImage bufferedImage = new BufferedImage(imageWidth,
            imageHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
    g2d.drawImage(originalImage, 0, 0, null);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    int x = 0;
    int y = 0;
    if (position != null) {
        switch (position) {
        case TOPLEFT:
            x = 0;
            y = 0;
            break;
        case TOPCENTER:
            x = (imageWidth / 2) - (watermarkWidth / 2);
            y = 0;
            break;
        case TOPRIGHT:
            x = imageWidth - watermarkWidth;
            y = 0;
            break;

        case MIDDLELEFT:
            x = 0;
            y = (imageHeight / 2) - (watermarkHeight / 2);
            break;
        case MIDDLECENTER:
            x = (imageWidth / 2) - (watermarkWidth / 2);
            y = (imageHeight / 2) - (watermarkHeight / 2);
            break;
        case MIDDLERIGHT:
            x = imageWidth - watermarkWidth;
            y = (imageHeight / 2) - (watermarkHeight / 2);
            break;

        case BOTTOMLEFT:
            x = 0;
            y = imageHeight - watermarkHeight;
            break;
        case BOTTOMCENTER:
            x = (imageWidth / 2) - (watermarkWidth / 2);
            y = imageHeight - watermarkHeight;
            break;
        case BOTTOMRIGHT:
            x = imageWidth - watermarkWidth;
            y = imageHeight - watermarkHeight;
            break;

        default:
            break;
        }
    }

    g2d.drawImage(Scalr.resize(watermarkImage, Method.ULTRA_QUALITY,
            watermarkWidth, watermarkHeight), x, y, null);

    return bufferedImage;

}

计算水印大小的相应方法是:

/**
 * 
 * @param originalImage
 * @param watermarkImage
 * @param maxPercentage
 * @return
 */
private static Pair<Double, Double> calculateWatermarkDimensions(
        BufferedImage originalImage, BufferedImage watermarkImage,
        double maxPercentage) {

    double imageWidth = originalImage.getWidth();
    double imageHeight = originalImage.getHeight();

    double maxWatermarkWidth = imageWidth / 100.0 * maxPercentage;
    double maxWatermarkHeight = imageHeight / 100.0 * maxPercentage;

    double watermarkWidth = watermarkImage.getWidth();
    double watermarkHeight = watermarkImage.getHeight();

    if (watermarkWidth > maxWatermarkWidth) {
        double aspectRatio = watermarkWidth / watermarkHeight;
        watermarkWidth = maxWatermarkWidth;
        watermarkHeight = watermarkWidth / aspectRatio;
    }

    if (watermarkHeight > maxWatermarkHeight) {
        double aspectRatio = watermarkWidth / watermarkHeight;
        watermarkHeight = maxWatermarkHeight;
        watermarkWidth = watermarkHeight / aspectRatio;
    }

    return Pair.of(watermarkWidth, watermarkHeight);
}

/**
 * 
 * @param originalImage
 * @param watermarkImage
 * @param maxPercentage
 * @return
 */
public static int getWatermarkWidth(BufferedImage originalImage,
        BufferedImage watermarkImage, double maxPercentage) {

    return calculateWatermarkDimensions(originalImage, watermarkImage,
            maxPercentage).getLeft().intValue();

}

/**
 * 
 * @param originalImage
 * @param watermarkImage
 * @param maxPercentage
 * @return
 */
public static int getWatermarkHeight(BufferedImage originalImage,
        BufferedImage watermarkImage, double maxPercentage) {

    return calculateWatermarkDimensions(originalImage, watermarkImage,
            maxPercentage).getRight().intValue();

}

再次,http://www.codeyouneed.com/java-watermark-image/获得一个很好的样本的所有学分。

答案 3 :(得分:1)

我用于我的项目IM4Java library - 用于java的imagemagick包装器。有关水印示例,请参阅http://www.imagemagick.org/Usage/annotating/

答案 4 :(得分:1)

使用此代码,它的工作原理.. 这里,图像用作水印并放置在位置10,10

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class WatermarkImage {

  public static void addWatermark(String localImagePath) {

    try {
        BufferedImage image = ImageIO.read(new File(localImagePath));
        BufferedImage overlay = ImageIO.read(new File(".\\data\\watermark\\watermark.png"));

        // create the new image, canvas size is the max. of both image sizes
        int w = Math.max(image.getWidth(), overlay.getWidth());
        int h = Math.max(image.getHeight(), overlay.getHeight());
        BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        // paint both images, preserving the alpha channels
        Graphics g = combined.getGraphics();
        g.drawImage(image, 0, 0, null);
        g.drawImage(overlay, 10, 0, null);

        ImageIO.write(combined, "PNG", new File(localImagePath));
    } catch (IOException e) {
        e.printStackTrace();
    }
  }
}

答案 5 :(得分:1)

以下是在任何图片上添加水印的代码

import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

public class WatermarkImage {

  public static void main(String[] args) {

        File origFile = new File("C:/OrignalImage.jpg");
        ImageIcon icon = new ImageIcon(origFile.getPath());

        // create BufferedImage object of same width and height as of original image
        BufferedImage bufferedImage = new BufferedImage(icon.getIconWidth(),
                    icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);

        // create graphics object and add original image to it
        Graphics graphics = bufferedImage.getGraphics();
        graphics.drawImage(icon.getImage(), 0, 0, null);

        // set font for the watermark text
        graphics.setFont(new Font("Arial", Font.BOLD, 30));

        //unicode characters for (c) is \u00a9
        String watermark = "\u00a9 JavaXp.com";

        // add the watermark text
        graphics.drawString(watermark, 0, icon.getIconHeight() / 2);
        graphics.dispose();

        File newFile = new File("C:/WatermarkedImage.jpg");
        try {
              ImageIO.write(bufferedImage, "jpg", newFile);
        } catch (IOException e) {
              e.printStackTrace();
        }

        System.out.println(newFile.getPath() + " created successfully!");

  }

}

答案 6 :(得分:0)

首先使用

在Windows中的C:\ Imagemagick文件夹中输入Imagemagick

http://www.imagemagick.org/download/binaries/ImageMagick-6.8.8-7-Q16-x86-dll.exe

安装时添加C:\ ImageMagick;在PATH环境变量中

并使用以下代码

    package UploadServlet;

    import java.io.*;
    import java.util.*;

    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;        
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.io.output.*;

    /**
     * Servlet implementation class UploadServlet
     */
    public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#HttpServlet()
 */
 private boolean isMultipart;
 private String filePath;
 private int maxFileSize = 50 * 1024;
 private int maxMemSize = 4 * 1024;
 private File file ;

public UploadServlet() {
    super();
    // TODO Auto-generated constructor stub
}

public void init(){
    // Get the file location where it would be stored.
    filePath = getServletContext().getInitParameter("file-upload"); 
 }
/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
     throw new ServletException("GET method used with " +
                getClass( ).getName( )+": POST method required.");
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    // Check that we have a file upload request
      isMultipart = ServletFileUpload.isMultipartContent(request);
      response.setContentType("text/html");
      java.io.PrintWriter out = response.getWriter( );
      if( !isMultipart ){
         out.println("<html>");
         out.println("<head>");
         out.println("<title>Servlet upload</title>");  
         out.println("</head>");
         out.println("<body>");
         out.println("<p>No file uploaded</p>"); 
         out.println("</body>");
         out.println("</html>");
         return;
      }
      DiskFileItemFactory factory = new DiskFileItemFactory();
      // maximum size that will be stored in memory
      factory.setSizeThreshold(maxMemSize);
      // Location to save data that is larger than maxMemSize.
      factory.setRepository(new File("c:\\temp"));

      // Create a new file upload handler
      ServletFileUpload upload = new ServletFileUpload(factory);
      // maximum file size to be uploaded.
      upload.setSizeMax( maxFileSize );

      try{ 
      // Parse the request to get file items.
      List fileItems = upload.parseRequest(request);

      // Process the uploaded file items
      Iterator i = fileItems.iterator();

      out.println("<html>");
      out.println("<head>");
      out.println("<title>Servlet upload</title>");  
      out.println("</head>");
      out.println("<body>");
      out.println("<h3>Watermark :</h3>");
      out.println("Select a file to upload: <br />");
      out.println("<form action=\"UploadServlet\" method=\"post\" enctype=\"multipart/form-data\">");
      out.println("<input type=\"file\" name=\"file\" size=\"50\" /><br/>");
      out.println("<input type=\"submit\" value=\"Upload File\" />");
      out.println("</form><br/>");
      while ( i.hasNext () ) 
      {
         FileItem fi = (FileItem)i.next();
         if ( !fi.isFormField () )  
         {
            // Get the uploaded file parameters
            String fieldName = fi.getFieldName();
            String fileName = fi.getName();
            //System.out.println("Filename:" + fileName);
            String contentType = fi.getContentType();
            boolean isInMemory = fi.isInMemory();
            long sizeInBytes = fi.getSize();
            // get application path
            String webAppPath = getServletContext().getRealPath("/");
            //System.out.println("Web Application Path :" + webAppPath);

            // Write the file

            file = new File( webAppPath + "ImageTest.jpeg") ;

            fi.write( file ) ;


            out.println("<br/><h3>Uploaded File :</h3><img src=\"ImageTest.jpeg\" height='300px' width='300px' />");

            String command = "";
            command = "convert.exe -draw \"gravity south fill black text 0,0 'Watermark' \" \"" + webAppPath + "ImageTest.jpeg \" \""+ webAppPath +"imageTest_result.jpg \"";
            ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", command);
            Process p = pb.start();
            try {
                Thread.sleep(1000);
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
             out.println("<br/><h3>Watermarked File :</h3><img src=\"imageTest_result.jpg\" height='300px' width='300px' />");

         }

      }
      out.println("</body>");
      out.println("</html>");
   }catch(Exception ex) {
       System.out.println(ex);
       out.println("<br/><font color='red'><b>"+ex.getMessage()+"</b></font><br/>");
   }
}

}