`
dragonsoar
  • 浏览: 204004 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

纯java,不依赖于第三方jar的图片处理类

阅读更多

 

 

@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图片添加水印

  • 大小: 319.3 KB
  • 大小: 190.4 KB
  • 大小: 50.1 KB
  • 大小: 680.8 KB
分享到:
评论
7 楼 sparkwyj 2015-06-26  
lz ,请问 怎么解决 压缩png 后变大的问题?
QQ:55900394
6 楼 ahua186186 2014-09-10  
还有一种图片格式:tif
5 楼 dragonsoar 2013-01-21  
java_user 写道
纯java的真的不行,图片稍微多点JVM就会挂掉,推荐使用graphicmagick

过于太大的是不行,调了JVM参数也要控大小
4 楼 java_user 2013-01-21  
纯java的真的不行,图片稍微多点JVM就会挂掉,推荐使用graphicmagick
3 楼 yonge812 2013-01-08  
好的,QQ:654166020  我怎么联系你?
2 楼 dragonsoar 2013-01-06  
正常,会大一点点,不会很大。联系我,帮你解决
1 楼 yonge812 2013-01-04  
压缩png格式的图片,发现size变大了..

相关推荐

    JavaPDF操作类库API_Free Spire.PDF for Java_5.1.0

    无需依赖任何其他第三方插件,完全独立运行。 5.该压缩包包含的内容:samples文件夹中包含了多个操作PDF文档功能的java代码示例DEMO;lib文件夹下包含了用于在java程序中的Spire.Pdf.jar文件,在项目程序中调用接口...

    java开源包5

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    JAVA上百实例源码以及开源项目

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    JAVA上百实例源码以及开源项目源代码

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    Java平台Excel文档处理类库API-Free Spire.XLS for Java

    1.功能:该API为适用于Java平台下,通过后端程序代码调用API接口操作Excel文档。通过方法可实现如下功能: 1.1 文档格式转换:Excel转PDF/图片/...无需依赖任何其他第三方插件,完全独立运行。

    java开源包11

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包6

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包9

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包4

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包101

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包8

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包10

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包1

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包3

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    高效,小巧的开源JAVA WEB 开发框架-Nutz (源码,开发文档)

    不依赖任何第三方 Jar 包,从而便于程序员建立开发环境,部署,甚至重新编译 Nutz 的源代码。 不幸的是在第一版,我还是依赖了 Javassist 可以很好的和各种主流框架和类库等协同工作 你可以组合 Nutz.Dao + Spring ...

    java开源包2

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包7

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    Java资源包01

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

Global site tag (gtag.js) - Google Analytics