package comm.picture;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.awt.image.renderable.RenderableImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class PicCompressFunc {
JAI需引入JAI_CODE.JAR,  JAI_CODEC.JAR,mlkibwrapper_jai.jar
	/**
	 * 使用java advanced imaging 对图片进行压缩
	 * @param data
	 * @param comWidth
	 * @param comHeight
	 * @return
	 */
	public byte[] compressPicByJAI(byte[] data, int comWidth, int comHeight) {
		ByteArrayOutputStream baos = null;
		try {
			Image image = ImageIO.read(new ByteArrayInputStream(data));
			ParameterBlock pb = new ParameterBlock().add(image);
			// converts s standard java.awt.Image into a rendered image
			RenderedImage renImage = JAI.create("awtImage", pb);
			pb = new ParameterBlock();
			pb.addSource(renImage);
			RenderableImage rendImage = JAI.createRenderable("renderable", pb);
			PlanarImage pi = (PlanarImage) rendImage.createScaledRendering(
					comWidth, comHeight, null);
			baos = new ByteArrayOutputStream();
			JAI.create("encode", pi, baos, "JPEG", null);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (baos != null) {
					baos.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(baos==null){
			return null;
		}
		return baos.toByteArray();
	}

	/**
	 * 根据指定的宽度、高度压缩图片,如果isEqualCompress为true,则采用等比压缩
	 * 
	 * @param data
	 *            压缩前的图片字节数组
	 * @param comWidth
	 *            压缩后的宽度
	 * @param comHeight
	 *            压缩后的高度
	 * @param isEqualCompress
	 *            是否等比压缩
	 * @return
	 */
	public byte[] compressPic(byte[] data, int comWidth, int comHeight,
			boolean isEqualCompress) {

		byte[] comData = null;
		Image image = null;
		ByteArrayOutputStream baos = null;
		try {
			image = ImageIO.read(new ByteArrayInputStream(data));
			if (image != null && image.getWidth(null) > 0) {
				int newWidth = 0;
				int newHeight = 0;
				// 采用等比压缩方式
				if (isEqualCompress) {
					double widRate = (double) image.getWidth(null)
							/ (double) comWidth + 0.1;
					double heightRate = (double) image.getHeight(null)
							/ (double) comHeight + 0.1;
					double rate = widRate > heightRate ? widRate : heightRate;
					newWidth = (int) ((double) image.getWidth(null) / rate);
					newHeight = (int) ((double) image.getHeight(null) / rate);

				} else {
					newWidth = comWidth;
					newHeight = comHeight;
				}
				// 所创建图像的类型——BufferedImage.TYPE_INT_RGB
				BufferedImage bimage = new BufferedImage(newWidth, newHeight,
						BufferedImage.TYPE_INT_RGB);
				// 0,0表示图像左上角的坐标;getScaledInstance()-创建图像的压缩版本,Image.SCALE_SMOOTH-指定图像压缩算法
				bimage.getGraphics().drawImage(
						image.getScaledInstance(newWidth, newHeight,
								Image.SCALE_SMOOTH), 0, 0, null);
				baos = new ByteArrayOutputStream();
				// JPEGImageEncoder可适用于其他图片类型的转换
				JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
				encoder.encode(bimage);
				comData = baos.toByteArray();
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (baos != null) {
				try {
					baos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return comData;
	}

	/**
	 * 在图片上叠加图片水印,byte[]数组处理
	 * 
	 * @param pressImaBytes
	 *            水印图片的字节数组
	 * @param baseImaBytes
	 *            原始图片的字节数组
	 * @param x
	 *            偏移量
	 * @param y
	 *            偏移量
	 * @return 返回BufferedImage对象
	 */
	public static BufferedImage pressImageToImage(byte[] pressImaBytes,
			byte[] baseImaBytes, int x, int y) {
		BufferedImage image = null;
		Graphics graphic = null;
		if (baseImaBytes == null) {
			image = null;
		} else {
			try {
				image = ImageIO.read(new ByteArrayInputStream(baseImaBytes));
				int baseWidth = image.getWidth();
				int baseHeight = image.getHeight();
				graphic = image.createGraphics();
				graphic.drawImage(image, 0, 0, baseWidth, baseHeight, null);
				// 水印图片文件
				BufferedImage tempImage = ImageIO
						.read(new ByteArrayInputStream(pressImaBytes));
				int pressWidth = tempImage.getWidth();
				int pressHeight = tempImage.getHeight();
				// 判断原始图片与水印图片大小,如水印图片>原始图片,不处理
				if ((baseWidth - pressWidth) > 0
						&& (baseHeight - pressHeight) > 0) {
					graphic.drawImage(tempImage, x, y,
							(baseWidth - pressWidth) / 2,
							(baseHeight - pressHeight) / 2, null);
				}
				// 释放此图形的上下文以及它使用的所有系统资源
				graphic.dispose();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return image;
	}

	/**
	 * 在图片上叠加图片水印,文件处理
	 * 
	 * @param pressImaPath
	 *            水印图片文件路径
	 * @param baseImaPath
	 *            原始图片文件路径
	 * @param x
	 *            偏移量
	 * @param y
	 *            偏移量
	 * @return 处理结果,true正常
	 */
	public static boolean pressImageToImage(String pressImaPath,
			String baseImaPath, int x, int y) {
		boolean result = false;
		// 水印图片文件
		File pressImaFile = null;
		// 原始图片文件
		File baseImaFile = null;
		FileInputStream in = null;
		FileInputStream in2 = null;
		FileOutputStream out = null;
		byte[] temp = null;
		byte[] temp2 = null;
		pressImaFile = new File(pressImaPath);
		baseImaFile = new File(baseImaPath);
		// 判断文件存在
		if (pressImaFile.exists() && baseImaFile.exists()) {
			try {
				in = new FileInputStream(pressImaFile);
				int length = in.available();
				temp = new byte[length];
				in.read(temp);

				in2 = new FileInputStream(baseImaFile);
				length = in.available();
				temp2 = new byte[length];
				in.read(temp2);
				// 加水印过程
				BufferedImage image = pressImageToImage(temp, temp2, x, y);
				// 写入原始图片
				out = new FileOutputStream(baseImaFile);
				JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
				encoder.encode(image);
				out.flush();
				result = true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					if (in != null) {
						in.close();
					}
					if (in2 != null) {
						in2.close();
					}
					if (out != null) {
						out.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	/**
	 * 在图片上叠加文字水印,byte数组处理
	 * 
	 * @param pressTextBytes
	 *            添加上的水印文字的byte[]
	 * @param baseImaBytes
	 *            原始图片的byte[]
	 * @param fontName
	 *            字体
	 * @param fontStyle
	 *            字体style
	 * @param color
	 *            颜色
	 * @param fontSize
	 *            字体大小
	 * @param x
	 *            偏移量
	 * @param y
	 *            偏移量
	 * @return BufferedImage
	 */
	public static BufferedImage pressTextToImage(byte[] pressTextBytes,
			byte[] baseImaBytes, String fontName, int fontStyle, String color,
			int fontSize, int x, int y) {
		BufferedImage image = null;
		Graphics graphic = null;
		if (baseImaBytes == null) {
			image = null;
		} else {
			try {
				image = ImageIO.read(new ByteArrayInputStream(baseImaBytes));
				int baseWidth = image.getWidth();
				int baseHeight = image.getHeight();
				graphic = image.createGraphics();
				graphic.drawImage(image, 0, 0, baseWidth, baseHeight, null);

				graphic.setColor(Color.decode(color));
				graphic.setFont(new Font(fontName, fontStyle, fontSize));
				if (x > baseWidth) {
					x = 0;
				}
				if (y > baseHeight) {
					y = 0;
				}
				graphic.drawString(new String(pressTextBytes), x, y);
				// 释放此图形的上下文以及它使用的所有系统资源
				graphic.dispose();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return image;
	}

	/**
	 * 在图片上叠加文字水印,文件处理
	 * 
	 * @param textStr
	 *            水印字符串
	 * @param baseImaPath
	 *            原始图片 文件路径
	 * @param fontName
	 *            字体
	 * @param fontStyle
	 *            字体style
	 * @param color
	 *            颜色
	 * @param fontSize
	 *            字体大小
	 * @param x
	 *            偏移量
	 * @param y
	 *            偏移量
	 * @return
	 */
	public static boolean pressTextToImage(String textStr, String baseImaPath,
			String fontName, int fontStyle, String color, int fontSize, int x,
			int y) {
		boolean result = false;
		File baseImaFile = null;
		FileInputStream in = null;
		FileOutputStream out = null;
		byte[] temp = null;
		baseImaFile = new File(baseImaPath);
		if (baseImaFile != null && baseImaFile.exists()) {
			try {
				in = new FileInputStream(baseImaFile);
				int length = in.available();
				temp = new byte[length];
				in.read(temp);
				// 添加水印处理
				BufferedImage image = pressTextToImage(textStr.getBytes(),
						temp, fontName, fontStyle, color, fontSize, x, y);
				out = new FileOutputStream(baseImaFile);
				JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
				encoder.encode(image);
				out.flush();
				result = true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					if (in != null) {
						in.close();
					}
					if (out != null) {
						out.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	/**
	 * 图片变灰处理
	 * 
	 * @param image
	 *            原始BufferedImage对象
	 * @return 经过变灰处理的BufferedImage对象
	 */
	public static BufferedImage getGrayPic(BufferedImage image) {
		BufferedImage grayImage = null;
		if (image == null) {
			grayImage = null;
		} else {
			int imageWidth = image.getWidth();
			int imageHeight = image.getHeight();
			grayImage = new BufferedImage(imageWidth, imageHeight,
					BufferedImage.TYPE_3BYTE_BGR);
			ColorConvertOp cco = new ColorConvertOp(
					ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
			cco.filter(image, grayImage);
		}
		return grayImage;
	}

	/**
	 * 改变图片大小时调用的通用过程
	 * 
	 * @param newImage
	 *            新BufferedImage对象
	 * @param preImage
	 *            原来的BufferedImage对象
	 * @param graphic
	 *            Graphics对象,用于绘制新图
	 * @param width
	 *            新图片的宽度
	 * @param height
	 *            新图片的高度
	 */
	private static void resizeImageMethod(BufferedImage newImage,
			BufferedImage preImage, Graphics graphic, int width, int height) {
		newImage = new BufferedImage(width, height,
				BufferedImage.TYPE_3BYTE_BGR);
		graphic = newImage.createGraphics();
		graphic.drawImage(preImage, 0, 0, width, height, null);
		graphic.dispose();
	}

	/**
	 * 改变图片大小,按比例---依据指定宽度
	 * 
	 * @param preImage
	 *            原BufferedImage对象
	 * @param referWidth
	 *            宽度参考值
	 * @return 返回BufferedImage的具有新大小值的对象
	 */
	public static BufferedImage resizeImageByWidth(BufferedImage preImage,
			int referWidth) {
		BufferedImage image = null;
		Graphics graphic = null;
		double width = preImage.getWidth();
		double height = preImage.getHeight();
		// 新旧百分比
		double percent = referWidth / width;
		// 新宽度&高度
		int newWidth = (int) (width * percent);
		int newHeight = (int) (height * percent);
		// 绘制新图片
		resizeImageMethod(image, preImage, graphic, newWidth, newHeight);
		return image;
	}

	/**
	 * 改变图片大小,按比例---依据高度
	 * 
	 * @param preImage
	 *            原BufferedImage对象
	 * @param referHeight
	 *            高度参考值
	 * @return 返回BufferedImage的具有新大小值的对象
	 */
	public static BufferedImage resizeImageByHeight(BufferedImage preImage,
			int referHeight) {
		BufferedImage image = null;
		Graphics graphic = null;
		double width = preImage.getWidth();
		double height = preImage.getHeight();
		// 新旧百分比
		double percent = referHeight / height;
		// 新宽度&高度
		int newWidth = (int) (width * percent);
		int newHeight = (int) (height * percent);
		// 绘制新图片
		resizeImageMethod(image, preImage, graphic, newWidth, newHeight);
		return image;
	}

	/**
	 * 对图片文件格式进行转换,byte[]数组处理
	 * 
	 * @param picBytes
	 *            原格式图片bytes
	 * @param format
	 *            转换到的格式
	 * @return 返回新格式图片的bytes
	 */
	public static byte[] changPicFormat(byte[] picBytes, String format) {
		byte[] newPicBytes = null;
		ByteArrayOutputStream out = null;
		if (picBytes == null) {
			newPicBytes = null;
		} else {
			try {
				out = new ByteArrayOutputStream();
				// 内存中图像缓冲
				BufferedImage image = ImageIO.read(new ByteArrayInputStream(
						picBytes));
				// 图片变灰处理
				// image = getGrayPic(image);
				// 改变图片大小
				// image=resizeImage(image, 50);
				ImageIO.write(image, format, out);
				newPicBytes = out.toByteArray();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					if (out != null) {
						out.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
		return newPicBytes;
	}

	/**
	 * 对图片文件格式进行转换,文件处理
	 * 
	 * @param picPath
	 *            原图片文件完整路径
	 * @param newPicPath
	 *            存放新图片文件的完整路径
	 * @param format
	 *            转换到的格式
	 * @return boolean true转换成功
	 */
	public static boolean changePicFormat2(String picPath, String newPicPath,
			String format) {
		// 处理成功标识
		boolean result = false;
		FileInputStream in = null;
		FileOutputStream out = null;
		// 原图片文件
		File picFile = null;
		// 转换格式后图片文件
		File newPicFile = null;
		picFile = new File(picPath);
		if (!picFile.exists()) {
			result = false;
		} else {
			try {
				in = new FileInputStream(picFile);
				int length = in.available();
				byte[] tempBytes = new byte[length];
				in.read(tempBytes);
				byte[] tempBytes2 = changPicFormat(tempBytes, format);
				newPicFile = new File(newPicPath);
				if (newPicFile.exists()) {
					newPicFile.delete();
				}
				out = new FileOutputStream(newPicFile);
				out.write(tempBytes2);
				out.flush();
				result = true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					picFile = null;
					newPicFile = null;
					if (in != null) {
						in.close();
					}
					if (out != null) {
						out.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
		return result;
	}

	/**
	 * 查看库支持的图片格式
	 */
	private void getSupportedPicFormat() {
		String[] readFormats = ImageIO.getReaderMIMETypes();
		String[] writeFormats = ImageIO.getWriterMIMETypes();
		System.out.println("read: " + Arrays.asList(readFormats));
		System.out.println("write: " + Arrays.asList(writeFormats));
	}

}