純java、サードパーティjarに依存しないピクチャ処理クラス

11115 ワード

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

		}

	}

}


回転:  http://dragonsoar.iteye.com/blog/1631330