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

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

您可以查看http://web.archive.org/web/20080324030029/http://blog.codebeach.com/2008/02/watermarking-images-in-java-的“绘制水印”部分。 servlet.html

或者您可以使用GIF4J库http://www.gif4j.com/java-gif4j-pro-gif-image-watermark.htm#gifimagewatermarkapply

在Thumbnailator中 ,可以使用Caption图像filter为现有图像添加文本标题:

 // 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为中心绘制,使用Monospaced字体,黑色前景色,14 pt。

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

 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的开发人员。

我最近有类似的需求,发现这篇文章相当有用: 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 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/获得一个很好的样本。

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

使用此代码,它可以工作..在这里,图像用作水印,位于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(); } } } 

首先在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(""); out.println(""); out.println("Servlet upload"); out.println(""); out.println(""); out.println("

No file uploaded

"); out.println(""); out.println(""); 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(""); out.println(""); out.println("Servlet upload"); out.println(""); out.println(""); out.println("

Watermark :

"); out.println("Select a file to upload:
"); out.println("
"); out.println("
"); out.println(""); out.println("

"); 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("

Uploaded File :

"); 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("

Watermarked File :

"); } } out.println(""); out.println(""); }catch(Exception ex) { System.out.println(ex); out.println("
"+ex.getMessage()+"
"); } }

}

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

 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!"); } 

}