`
dragonsoar
  • 浏览: 205380 次
  • 性别: 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变大了..

相关推荐

    在可执行jar中载入第三方jar的几个解决方法

    4. **使用`java.util.ServiceLoader`**:对于依赖于服务提供者接口(SPI)的情况,可以利用`ServiceLoader`来加载第三方JAR提供的服务。`ServiceLoader`会遍历指定的META-INF/services/目录下的文件,根据文件内容...

    打包第三方Jar插件

    总之,"打包第三方Jar插件"涉及Java项目中依赖管理、构建路径设置、类加载机制、项目打包等多个方面。通过理解并熟练运用这些知识点,可以提高开发效率,减少错误,保证项目的稳定性和可维护性。在实际操作中,结合...

    java发送该邮件源码可支持第三方调用jar

    总的来说,这个Java邮件发送源码及jar包为开发者提供了一个高效、灵活的邮件发送解决方案,支持第三方调用和HTML格式邮件,是构建企业级应用时处理邮件功能的好帮手。无论是发送通知、验证码还是其他业务需求,都...

    Java 日志工具 LogUtil 源码 不依赖第三方jar包

    Java日志工具LogUtil是Java开发中常见的自定义日志工具类,它的主要特点是不依赖任何第三方的日志框架,如Log4j、Logback或SLF4J等。这种独立性使得开发者在某些特定场景下,例如轻量级应用、嵌入式系统或者对依赖...

    基于java通过第三方jar包sigar的支持,完成对服务器系统的参数监控,包括CPU、内存、硬盘以及网络流量的实时监控.zip

    本项目就是基于Java利用第三方jar包Sigar(System Information Gatherer and Reporter)来实现服务器系统的实时参数监控,涵盖了CPU、内存、硬盘以及网络流量四大关键指标。 首先,让我们深入理解Sigar库。Sigar是...

    maven批量导入第三方jar包至本地库工具

    在Java开发中,Maven是一个广泛使用的构建工具,它依赖于中央仓库中的各种jar包来构建项目。然而,有时候我们可能需要使用一些不在中央仓库中的第三方库,这就需要我们将这些jar包手动导入到Maven的本地库。"maven...

    hadoop源码的第三方jar包

    在这个压缩包中,包含了一些用于支持Hadoop 2.2版本开发的第三方jar包,这些jar包对于理解Hadoop的内部工作原理以及进行自定义开发具有重要意义。 1. **hadoop-hdfs-bkjournal-2.1.0-beta.jar**:这是Hadoop HDFS...

    eclipse 第三方jar包配置.txt

    本文将详细介绍一种不依赖于Eclipse内置buildpath功能的方法来配置第三方JAR包。 #### 二、Eclipse项目结构简介 在深入讨论如何配置第三方JAR包之前,我们需要先了解Eclipse项目的几个关键概念: 1. **项目路径**...

    jl-1.0.1.jar.zip_jl0.4.jar下载_jl1.0.1.jar_jl1.0.jar下载_第三方Jar包

    “第三方jar包”标签表示这些`.jar`文件不是来自官方Java平台或者标准库,而是由独立开发者或公司创建并维护的。第三方库可以提供各种功能,例如网络通信、数据库连接、图形处理等,它们能帮助开发者快速实现特定...

    创建jar并引入第三方包

    总的来说,创建包含第三方库的JAR文件是Java开发中的常规操作,理解不同的打包策略有助于根据具体需求做出最佳选择。无论是在MyEclipse还是Eclipse中,都可以通过上述步骤有效地整合和打包你的项目及其依赖。

    JFOA包含第三方jar包

    标题“JFOA包含第三方jar包”指出,我们正在讨论的是一个与JFOA(可能是某个Java框架或库的缩写)相关的项目,其中整合了第三方的jar包资源。这些jar包是软件开发中常用的二进制库,它们包含了预编译的Java类,供...

    myeclipse打包jar文件包含第三方jar包(文档+工具)

    `FatJar`是一个第三方插件,适用于`Eclipse`和`MyEclipse`,它的主要功能是帮助开发者将所有项目依赖的库文件(即第三方JAR包)打包进最终的可执行JAR中。这样,当用户运行这个单一的JAR文件时,不需要额外配置类...

    第三方jar实现邮件发送

    ### 第三方JAR实现邮件发送 #### 概述 在Java Web开发中,邮件发送是一项常见但又必不可少的功能。无论是用户注册验证、找回密码还是通知提醒等场景,邮件服务都扮演着重要的角色。本文将详细介绍如何通过引入第三...

    Java在制作jar包时引用第三方jar包的方法

    如果应用程序依赖于第三方库,那么在打包成JAR时也必须将这些依赖的第三方JAR包包含进去。在不恰当引用第三方JAR包的情况下,可能会遇到类找不到的错误。为了正确引用第三方JAR包,需要了解Java类加载器的工作机制...

    Android将Activity打成jar包供第三方调用

    需要注意的是,由于jar包不包含Android资源,所以如果Activity依赖于项目的资源(如布局文件、图片等),这可能导致运行时错误。在这种情况下,可能需要考虑使用aar格式或者提供一种方式让第三方应用传递必要的资源...

    Android将Activity 或者说Library打成jar包供第三方调用(解决资源文件不能打包的问题)

    Android的资源系统依赖于Android的构建工具链(如Gradle)和R类,这些在jar包中是不可用的。 2. **使用AAR格式**:AAR(Android Archive)文件格式是专门为Android库设计的,它允许包含资源文件。但是,如果只需要...

    JSONObject java解析json需要的jar包和依赖包

    下面我们将详细介绍如何在Java项目中使用`JSONObject`,包括所需的jar包和依赖。 1. **引入依赖** 要使用`JSONObject`,首先需要将对应的jar包添加到项目的类路径中。在传统的Java项目中,你可以直接下载`org.json...

    JAVA发送手机短信依赖JAR包

    在Java开发中,有时我们需要实现向手机发送短信的功能,这通常涉及到第三方服务提供商提供的API接口。在这种场景下,"JAVA发送手机短信依赖JAR包"就是实现这一功能的关键。这个JAR包包含了发送短信所需的类库和方法...

    eclipse 代码折叠第三方jar folding

    默认情况下,Eclipse对Java源代码提供内置的支持,但若想对第三方JAR文件中的代码实现相同效果,就需要进行额外的配置。 Eclipse的代码折叠功能是通过插件机制实现的。对于JAR文件,由于它们通常包含编译后的字节码...

Global site tag (gtag.js) - Google Analytics