JAVA 自带图片处理, 不支持gif, png 会变黑, 需要处理
/** * 添加图片水印 * 水印固定为 @xxxxxx 角标 * @param srcFile * @return */ public static File addWaterMark(File srcFile) { OutputStream os = null; try { // 源图片 String formatName = FileType.getSuffixByFilename(srcFile.getName()).substring(1); if (!FileType.JPG.equalsIgnoreCase(formatName)) { // 暂不支持其他类型的图片 return srcFile; } Image srcImg = ImageIO.read(srcFile); BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB); int srcImgWidth = buffImg.getWidth(); // 图片宽 int srcImgHeight = buffImg.getHeight(); // 图片高 // 1、得到画笔对象 Graphics2D g = buffImg.createGraphics(); // 2、设置对线段的锯齿状边缘处理 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // 3、画原图 g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,1.0f)); // 4、水印图片的路径 水印图片一般为gif或者png的,这样可设置透明度 InputStream in = getImageStream(iconPath); if (in == null) { log.warn("iconPath 获取网络图片失败: " + iconPath); return srcFile; } // 5、得到Image对象 BufferedImage imgIconBufferedImage = ImageIO.read(in); ImageIcon imgIcon = new ImageIcon(imgIconBufferedImage); // 标准尺寸边距是 20px 标准图片大小 750 比例缩放 int margin = scale(10, srcImgWidth); int width = scale(imgIcon.getIconWidth(), srcImgWidth); int height = scale(imgIcon.getIconHeight(), srcImgWidth); int positionX = srcImgWidth - width - margin ; int positionY = srcImgHeight - height - margin ; // 6、水印图片的位置 g.drawImage(imgIconBufferedImage, positionX, positionY, width, height,null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); // 7、释放资源 g.dispose(); // 8、生成图片 os = new FileOutputStream(srcFile.getAbsolutePath()); ImageIO.write(buffImg, formatName, os); } catch (Exception e) { log.error("Exception" , e); } finally { try { if (null != os) { os.close(); } } catch (Exception e) { log.error("close Exception" , e); } } return srcFile; }
获取网络图片流
/** * 获取网络图片流 * * @param url * @return */ public static InputStream getImageStream(String url) { try { HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setReadTimeout(5000); connection.setConnectTimeout(5000); connection.setRequestMethod("GET"); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream inputStream = connection.getInputStream(); return inputStream; } } catch (IOException e) { log.error("获取网络图片出现异常,图片路径为:" + url, e); } return null; }
缩放图片
private static int scale(int w, int srcImgWidth) { return (w * srcImgWidth) / standardWidth; }
ThumbnailsUtils 方式, 支持jpg, png 代码更整洁
maven 引入
<dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.8</version> </dependency>
public static void addImageWaterMark(File srcFile, BufferedImage waterMarkImgBuff, String formatName, int positionX, int positionY, int width, int height, String outPath) { OutputStream os = null; try { BufferedImage srcBuff = ImageIO.read(srcFile); int srcWidth = srcBuff.getWidth(null); int srcHeight = srcBuff.getHeight(null); Position position = new Coordinate(positionX, positionY); // 水印图片 BufferedImage waterImage = Thumbnails.of(waterMarkImgBuff) .size(width, height) .outputQuality(1) .asBufferedImage(); Thumbnails.Builder fullImageBuilder = Thumbnails.of(srcBuff) .size(srcWidth, srcHeight) .outputFormat(formatName) .watermark(position, waterImage, 1); BufferedImage fullImageBuff = null; if ("png".equalsIgnoreCase(formatName)) { fullImageBuff = fullImageBuilder.outputQuality(1).imageType(BufferedImage.TYPE_INT_ARGB).asBufferedImage(); } else { fullImageBuff = fullImageBuilder.outputQuality(1).asBufferedImage(); } // 生成图片 os = new FileOutputStream(outPath); ImageIO.write(fullImageBuff, formatName, os); } catch (IOException e) { log.error("addImageWaterMark Exception", e); } finally { try { if (null != os) { os.close(); } } catch (Exception e) { log.error("close Exception", e); } } }
AnimatedGifUtils 处理 GIF 图片
maven 引入
<dependency> <groupId>com.madgag</groupId> <artifactId>animated-gif-lib</artifactId> <version>1.4</version> </dependency>
public static void addImageWaterMark(File srcFile, BufferedImage waterMarkImgBuff, int positionX, int positionY, int width, int height, String outPath) { try { InputStream inputStream = new FileInputStream(srcFile.getAbsolutePath()); GifDecoder decoder = new GifDecoder(); //读入gif数据流 decoder.read(inputStream); //读取帧数 int frameCount = decoder.getFrameCount(); AnimatedGifEncoder encoder = new AnimatedGifEncoder(); encoder.start(outPath); encoder.setRepeat(0); Graphics2D g = null; /** * 对GIF进行拆分 * 每一帧进行文字处理 * 组装 */ for (int i = 0; i < frameCount; i++) { //初始化图像 g = (Graphics2D) decoder.getFrame(i).getGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawImage(waterMarkImgBuff, positionX, positionY, width, height, null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); g.dispose(); //组装每一帧 encoder.addFrame(decoder.getFrame(i)); //设置每帧的切换时间 if (i != frameCount - 1) { encoder.setDelay(decoder.getDelay(i)); } } encoder.finish(); } catch (Exception e) { log.error("addImageWaterMark Exception", e); } }
封装整合处理, 感觉有点丑, 后续再优化
public static File addImageWaterMark(File srcFile, File targetFile) { try { // 源图片 图片格式 String formatName = FileType.getSuffixByFilename(srcFile.getName()).substring(1); Image srcImg = ImageIO.read(srcFile); int srcImgWidth = srcImg.getWidth(null); // 图片宽 int srcImgHeight = srcImg.getHeight(null); // 图片高 InputStream in = ImageUtils.getImageStream(waterMarkUrl); if (in == null) { log.warn("iconPath 获取网络图片失败: " + waterMarkUrl); return srcFile; } BufferedImage waterMarkImgBuff = ImageIO.read(in); // 计算水印图片的位置 图片的宽 高 int margin = scale(10, srcImgWidth); int width = scale(waterMarkImgBuff.getWidth(), srcImgWidth); int height = scale(waterMarkImgBuff.getHeight(), srcImgWidth); int positionX = srcImgWidth - width - margin; int positionY = srcImgHeight - height - margin; if ("jpg".equalsIgnoreCase(formatName) || "png".equalsIgnoreCase(formatName)) { ThumbnailsUtils.addImageWaterMark(srcFile, waterMarkImgBuff, formatName, positionX, positionY, width, height, targetFile.getAbsolutePath()); } else if ("gif".equalsIgnoreCase(formatName)) { AnimatedGifUtils.addImageWaterMark(srcFile, waterMarkImgBuff, positionX, positionY, width, height, targetFile.getAbsolutePath()); } } catch (Exception e) { log.error("addImageWaterMark Exception", e); } return srcFile; }
测试
public static void main(String[] args) { String fileImgPath1 = "D:\\temp\\" + 1 + ".jpg"; String targetImgPath1 = "D:\\temp\\" + 1 + "-水印.jpg"; addImageWaterMark(new File(fileImgPath1), new File(targetImgPath1)); String fileImgPath2 = "D:\\temp\\" + 2 + ".jpg"; String targetImgPath2 = "D:\\temp\\" + 2 + "-水印.jpg"; addImageWaterMark(new File(fileImgPath2), new File(targetImgPath2)); String fileImgPath3 = "D:\\temp\\" + 3 + ".png"; String targetImgPath3 = "D:\\temp\\" + 3 + "-水印.png"; addImageWaterMark(new File(fileImgPath3), new File(targetImgPath3)); String fileImgPath4 = "D:\\temp\\" + 4 + ".png"; String targetImgPath4 = "D:\\temp\\" + 4 + "-水印.png"; addImageWaterMark(new File(fileImgPath4), new File(targetImgPath4)); String fileImgPath5 = "D:\\temp\\" + 5 + ".gif"; String targetImgPath5 = "D:\\temp\\" + 5 + "-水印.gif"; addImageWaterMark(new File(fileImgPath5), new File(targetImgPath5)); String fileImgPath6 = "D:\\temp\\" + 6 + ".gif"; String targetImgPath6 = "D:\\temp\\" + 6 + "-水印.gif"; addImageWaterMark(new File(fileImgPath6), new File(targetImgPath6)); }
效果图
收藏不点赞等于白嫖不付钱!!!
来源:oschina
链接:https://my.oschina.net/zz006/blog/4278278