@ALL
本人因为工作需要,开发了一个工具处理类,功能如下:
1. jpg, png, gif --> jpg (并支持压缩)
2. jpg, png, gif --> 支持原图格式压缩
3. 支持水印添加,并且可以动态的调整位置显示在右下角
4. 本人是在开源代码的基础上,拿过来改一改调一调搞的;最大的好处有6个基础类,1个工具类,不依赖于第三方jar包
率果还是比较乐观的,目前基本的功能都有了也比较不错(自认为)
啥也不说了,上代码吧:
package org.summercool.util; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.imageio.ImageIO; import org.summercool.image.AnimatedGifEncoder; import org.summercool.image.GifDecoder; import org.summercool.image.Scalr; import org.summercool.image.Scalr.Method; import org.summercool.image.Scalr.Mode; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class ImageUtil { static Font FONT = new Font("微软雅黑", Font.BOLD, 18); static final Color COLOR = Color.WHITE; static final Color FONT_COLOR = new Color(255, 255, 255, 150); static final Color FONT_SHADOW_COLOR = new Color(170, 170, 170, 77); public static boolean isJpg(String str) { return isEndWid(str, "jpg"); } public static boolean isPng(String str) { return isEndWid(str, "png"); } public static boolean isGif(String str) { return isEndWid(str, "gif"); } private static boolean isEndWid(String str, String ext) { if (str == null || "".equals(str.trim())) { return false; } int position = str.lastIndexOf("."); if (position == -1 || (position == str.length() - 1)) { return false; } String suffix = str.substring(position + 1); if (ext.equalsIgnoreCase(suffix)) { return true; } else { return false; } } public static boolean isJpg(InputStream in) throws IOException { InputStream iis = in; if (!in.markSupported()) { throw new IllegalArgumentException("Input stream must support mark"); } iis.mark(30); // If the first two bytes are a JPEG SOI marker, it's probably // a JPEG file. If they aren't, it definitely isn't a JPEG file. try { int byte1 = iis.read(); int byte2 = iis.read(); if ((byte1 == 0xFF) && (byte2 == 0xD8)) { return true; } } finally { iis.reset(); } return false; } public static boolean isPng(InputStream in) throws IOException { if (!in.markSupported()) { throw new IllegalArgumentException("Input stream must support mark"); } byte[] b = new byte[8]; try { in.mark(30); in.read(b); } finally { in.reset(); } return (b[0] == (byte) 137 && b[1] == (byte) 80 && b[2] == (byte) 78 && b[3] == (byte) 71 && b[4] == (byte) 13 && b[5] == (byte) 10 && b[6] == (byte) 26 && b[7] == (byte) 10); } public static boolean isGif(InputStream in) throws IOException { if (!in.markSupported()) { throw new IllegalArgumentException("Input stream must support mark"); } byte[] b = new byte[6]; try { in.mark(30); in.read(b); } finally { in.reset(); } return b[0] == 'G' && b[1] == 'I' && b[2] == 'F' && b[3] == '8' && (b[4] == '7' || b[4] == '9') && b[5] == 'a'; } /** * 压缩图片 * * @param in * @param out * @param maxWidth * @param maxHeight * @param type * 1: jpg 2: png 4: gif 3: jpg+png 5: jpg+gif 6: png+gif 7: * jpg+png+gif * @throws IOException */ public static void resize(InputStream in, OutputStream out, int maxWidth, int maxHeight, int type, float quality, String[] watermark, Font font, Color fontColor) throws IOException { if (!(type >= 1 && type <= 7)) { throw new IOException("can not support type: " + type + ", type must be in [1-7] "); } if (type == 1) { if (!isJpg(in)) { throw new IOException("image format is not jpg "); } resizeJpg(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (type == 2) { if (!isPng(in)) { throw new IOException("image format is not png "); } resizePng(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (type == 3) { if (isJpg(in)) { resizeJpg(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (isPng(in)) { resizePng(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } throw new IOException("image format is not jpg or png "); } else if (type == 4) { if (!isGif(in)) { throw new IOException("image format is not gif "); } resizeGif(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (type == 5) { if (isJpg(in)) { resizeJpg(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (isGif(in)) { resizeGif(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } throw new IOException("image format is not jpg or gif "); } else if (type == 6) { if (isPng(in)) { resizePng(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (isGif(in)) { resizeGif(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } throw new IOException("image format is not png or gif "); } else if (type == 7) { if (isJpg(in)) { resizeJpg(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (isPng(in)) { resizePng(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } else if (isGif(in)) { resizeGif(in, out, maxWidth, maxHeight, quality, watermark, font, fontColor); return; } throw new IOException("image format is not jpg or png or gif "); } } public static void resizeJpg(InputStream in, OutputStream out, int maxWidth, int maxHeight, float quality, String[] watermark, Font font, Color fontColor) throws IOException { checkParams(in, out, maxWidth, maxHeight, quality); // BufferedImage image = ImageIO.read(in); image = Scalr.resize(image, Method.AUTOMATIC, Mode.AUTOMATIC, maxWidth, maxHeight); // create new image with right size/format BufferedImage bufferedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); // 因为有的图片背景是透明色,所以用白色填充 FIXED g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1)); g.fillRect(0, 0, image.getWidth(), image.getHeight()); g.drawImage(image, 0, 0, null); image = bufferedImage; // if (watermark != null && watermark.length > 0) { makeWatermark(watermark, image, font, fontColor); } // JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image); param.setQuality(quality, false); encoder.setJPEGEncodeParam(param); encoder.encode(image); } public static void resizePng(InputStream in, OutputStream out, int maxWidth, int maxHeight, float quality, String[] watermark, Font font, Color fontColor) throws IOException { checkParams(in, out, maxWidth, maxHeight, quality); // BufferedImage image = ImageIO.read(in); image = Scalr.resize(image, Method.AUTOMATIC, Mode.AUTOMATIC, maxWidth, maxHeight); if (watermark != null && watermark.length > 0) { makeWatermark(watermark, image, font, fontColor); } ImageIO.write(image, "png", out); } public static void resizeGif(InputStream in, OutputStream out, int maxWidth, int maxHeight, float quality, String[] watermark, Font font, Color fontColor) throws IOException { checkParams(in, out, maxWidth, maxHeight, quality); // GifDecoder gd = new GifDecoder(); int status = gd.read(in); if (status != GifDecoder.STATUS_OK) { return; } // AnimatedGifEncoder ge = new AnimatedGifEncoder(); ge.start(out); ge.setRepeat(0); for (int i = 0; i < gd.getFrameCount(); i++) { BufferedImage frame = gd.getFrame(i); BufferedImage rescaled = Scalr.resize(frame, Method.AUTOMATIC, Mode.AUTOMATIC, maxWidth, maxHeight); if (watermark != null && watermark.length > 0) { makeWatermark(watermark, rescaled, font, fontColor); } // int delay = gd.getDelay(i); ge.setDelay(delay); ge.addFrame(rescaled); } ge.finish(); } private static void makeWatermark(String[] text, BufferedImage image, Font font, Color fontColor) { Graphics2D graphics = image.createGraphics(); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if (font != null) { graphics.setFont(font); } else { graphics.setFont(FONT); } if (fontColor == null) { fontColor = COLOR; } // graphics.setColor(fontColor); for (int i = 0; i < text.length; i++) { if ("".equals(text[i].trim())) { continue; } FontRenderContext context = graphics.getFontRenderContext(); Rectangle2D fontRectangle = font.getStringBounds(text[i], context); int sw = (int) fontRectangle.getWidth(); int sh = (int) fontRectangle.getHeight(); if (text.length - i == 1) { graphics.drawString(text[i], image.getWidth() - sw - 6, image.getHeight() - 8); } else { graphics.drawString(text[i], image.getWidth() - sw - 6, image.getHeight() - sh * (text.length - 1) - 8); } } graphics.dispose(); } private static void checkParams(InputStream in, OutputStream out, int maxWidth, int maxHeight, float quality) throws IOException { if (in == null) { throw new IOException("InputStream can not be null "); } if (out == null) { throw new IOException("OutputStream can not be null "); } if (maxWidth < 1 || maxHeight < 1) { throw new IOException("maxWidth or maxHeight can not be less than 1 "); } if (quality < 0f || quality > 1f) { throw new IOException("quality must be in [0-1] "); } } public static void main(String[] args) throws IOException { FileInputStream in = new FileInputStream(new File("D:/gif/f1.jpg")); FileOutputStream out = new FileOutputStream(new File("D:/gif/f1_b.jpg")); try { resizeJpg(in, out, 640, 640, 0.85f, new String[] {"@王少-_-","weibo.com/dragonsoar"}, FONT, FONT_COLOR); } catch (Exception e) { e.printStackTrace(); } finally { out.close(); in.close(); } } }
1. jpg、png、gif压缩
1.1.1 jpg原图(320K):
1.1.2 jpg等比压缩(191K,精度设置成0.85f,肉眼看不出精度损失,效率还是不错的):
1.2 png压缩 (同上)
1.3 gif压缩(同上)
2. png to jpg(略)
3. gif to jpg(略)
4. 添加水印
4.1 jpg图片添加水印
4.2 gif图片添加水印
相关推荐
4. **使用`java.util.ServiceLoader`**:对于依赖于服务提供者接口(SPI)的情况,可以利用`ServiceLoader`来加载第三方JAR提供的服务。`ServiceLoader`会遍历指定的META-INF/services/目录下的文件,根据文件内容...
总之,"打包第三方Jar插件"涉及Java项目中依赖管理、构建路径设置、类加载机制、项目打包等多个方面。通过理解并熟练运用这些知识点,可以提高开发效率,减少错误,保证项目的稳定性和可维护性。在实际操作中,结合...
总的来说,这个Java邮件发送源码及jar包为开发者提供了一个高效、灵活的邮件发送解决方案,支持第三方调用和HTML格式邮件,是构建企业级应用时处理邮件功能的好帮手。无论是发送通知、验证码还是其他业务需求,都...
Java日志工具LogUtil是Java开发中常见的自定义日志工具类,它的主要特点是不依赖任何第三方的日志框架,如Log4j、Logback或SLF4J等。这种独立性使得开发者在某些特定场景下,例如轻量级应用、嵌入式系统或者对依赖...
本项目就是基于Java利用第三方jar包Sigar(System Information Gatherer and Reporter)来实现服务器系统的实时参数监控,涵盖了CPU、内存、硬盘以及网络流量四大关键指标。 首先,让我们深入理解Sigar库。Sigar是...
在Java开发中,Maven是一个广泛使用的构建工具,它依赖于中央仓库中的各种jar包来构建项目。然而,有时候我们可能需要使用一些不在中央仓库中的第三方库,这就需要我们将这些jar包手动导入到Maven的本地库。"maven...
在这个压缩包中,包含了一些用于支持Hadoop 2.2版本开发的第三方jar包,这些jar包对于理解Hadoop的内部工作原理以及进行自定义开发具有重要意义。 1. **hadoop-hdfs-bkjournal-2.1.0-beta.jar**:这是Hadoop HDFS...
本文将详细介绍一种不依赖于Eclipse内置buildpath功能的方法来配置第三方JAR包。 #### 二、Eclipse项目结构简介 在深入讨论如何配置第三方JAR包之前,我们需要先了解Eclipse项目的几个关键概念: 1. **项目路径**...
“第三方jar包”标签表示这些`.jar`文件不是来自官方Java平台或者标准库,而是由独立开发者或公司创建并维护的。第三方库可以提供各种功能,例如网络通信、数据库连接、图形处理等,它们能帮助开发者快速实现特定...
总的来说,创建包含第三方库的JAR文件是Java开发中的常规操作,理解不同的打包策略有助于根据具体需求做出最佳选择。无论是在MyEclipse还是Eclipse中,都可以通过上述步骤有效地整合和打包你的项目及其依赖。
标题“JFOA包含第三方jar包”指出,我们正在讨论的是一个与JFOA(可能是某个Java框架或库的缩写)相关的项目,其中整合了第三方的jar包资源。这些jar包是软件开发中常用的二进制库,它们包含了预编译的Java类,供...
`FatJar`是一个第三方插件,适用于`Eclipse`和`MyEclipse`,它的主要功能是帮助开发者将所有项目依赖的库文件(即第三方JAR包)打包进最终的可执行JAR中。这样,当用户运行这个单一的JAR文件时,不需要额外配置类...
### 第三方JAR实现邮件发送 #### 概述 在Java Web开发中,邮件发送是一项常见但又必不可少的功能。无论是用户注册验证、找回密码还是通知提醒等场景,邮件服务都扮演着重要的角色。本文将详细介绍如何通过引入第三...
如果应用程序依赖于第三方库,那么在打包成JAR时也必须将这些依赖的第三方JAR包包含进去。在不恰当引用第三方JAR包的情况下,可能会遇到类找不到的错误。为了正确引用第三方JAR包,需要了解Java类加载器的工作机制...
需要注意的是,由于jar包不包含Android资源,所以如果Activity依赖于项目的资源(如布局文件、图片等),这可能导致运行时错误。在这种情况下,可能需要考虑使用aar格式或者提供一种方式让第三方应用传递必要的资源...
Android的资源系统依赖于Android的构建工具链(如Gradle)和R类,这些在jar包中是不可用的。 2. **使用AAR格式**:AAR(Android Archive)文件格式是专门为Android库设计的,它允许包含资源文件。但是,如果只需要...
下面我们将详细介绍如何在Java项目中使用`JSONObject`,包括所需的jar包和依赖。 1. **引入依赖** 要使用`JSONObject`,首先需要将对应的jar包添加到项目的类路径中。在传统的Java项目中,你可以直接下载`org.json...
在Java开发中,有时我们需要实现向手机发送短信的功能,这通常涉及到第三方服务提供商提供的API接口。在这种场景下,"JAVA发送手机短信依赖JAR包"就是实现这一功能的关键。这个JAR包包含了发送短信所需的类库和方法...
默认情况下,Eclipse对Java源代码提供内置的支持,但若想对第三方JAR文件中的代码实现相同效果,就需要进行额外的配置。 Eclipse的代码折叠功能是通过插件机制实现的。对于JAR文件,由于它们通常包含编译后的字节码...