import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import org.apache.commons.lang.StringUtils;
/**
*
* File Name : ImageUtil.java
*
* @Description : Image 工具类</br>主要用于按指定大小截图
*/
public class ImageUtil
{
/**
* Description : <Detail Description for method>
*
* @param args
*
*/
public static void main(String[] args)
{
try
{
compressImage(
new File("F://20110406//in//201103280004570089c.jpg"),
new File("F://20110406//out//201103280004570089c.jpg"),
0.5f);
saveAndCutImage(new File(
"F://20110406//in//201103280004570089c.jpg"), new File(
"F://20110406//out//201103280004570089c.jpg"), 561, 411,
false);
saveAndCutImage(new File(
"F://20110406//in//201103280004570089c.jpg"), new File(
"F://20110406//out//201103280004570089c(448_290).jpg"),
448, 290, true);
} catch (Exception e)
{
e.printStackTrace();
}
}
/**
*
* Description : 按比例缩放图片
*
* @param source
* 要缩放的给定图片源
* @param targetW
* 给定宽度
* @param targetH
* 给定高度
* @return
*
*/
public static BufferedImage resize(BufferedImage source, int targetW,
int targetH, boolean proportion)
{
int type = source.getType();
BufferedImage target;
double sw = (double) targetW / source.getWidth();
double sh = (double) targetH / source.getHeight();
// 是否需要按比例缩放,若为false则按照给定的大小,这样会变形
if (proportion)
{
if (sw > sh)
{
sh = sw;
targetH = (int) (sh * source.getHeight());
} else
{
sw = sh;
targetW = (int) (sw * source.getWidth());
}
}
if (type == BufferedImage.TYPE_CUSTOM)
{
ColorModel cm = source.getColorModel();
WritableRaster raster = cm.createCompatibleWritableRaster(targetW,
targetH);
boolean alphaPremultiplied = cm.isAlphaPremultiplied();
target = new BufferedImage(cm, raster, alphaPremultiplied, null);
} else
{
target = new BufferedImage(targetW, targetH, type);
}
Graphics2D g = target.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawRenderedImage(source, AffineTransform.getScaleInstance(sw, sh));
g.dispose();
return target;
}
/**
*
* Description : 按给定大小保存截图
*
* @param inFilePath
* 图片源
* @param outFilePath
* 输出文件
* @param width
* 宽度
* @param hight
* 高度
* @param proportion
* 是否需要等比例缩放
* @throws Exception
*
*/
public static void saveAndCutImage(File inFile, File outFile, int width,
int hight, boolean proportion) throws Exception
{
saveAndCutImage(inFile, outFile, width, hight, proportion, 1f);
}
/**
*
* Description : 按给定大小保存截图
*
* @param inFilePath
* 图片源
* @param outFilePath
* 输出文件
* @param width
* 宽度
* @param hight
* 高度
* @param proportion
* 是否需要等比例缩放
* @param quality
* 压缩质量
* @throws Exception
*
*/
public static void saveAndCutImage(File inFile, File outFile, int width,
int hight, boolean proportion, float quality) throws Exception
{
InputStream in = new FileInputStream(inFile);
File saveFile = outFile;
BufferedImage srcImage = ImageIO.read(in);
if (width > 0 || hight > 0)
{
// 原图的大小
int sw = srcImage.getWidth();
int sh = srcImage.getHeight();
// 如果原图像的大小小于要缩放的图像大小,直接将要缩放的图像复制过去
if (sw > width && sh > hight)
{
srcImage = resize(srcImage, width, hight, proportion);
} else
{
compressImage(srcImage, saveFile, quality);
if (saveFile.length() > inFile.length())
{
String fileName = saveFile.getName();
String formatName = "";
int pos = fileName.lastIndexOf('.');
if (pos > -1)
{
formatName = fileName.substring(pos + 1).toLowerCase();
}
ImageIO.write(srcImage, formatName, outFile);
}
return;
}
}
// 缩放后的图像的宽和高
int w = srcImage.getWidth();
int h = srcImage.getHeight();
// 如果缩放后的图像和要求的图像宽度一样,就对缩放的图像的高度进行截取
if (w == width)
{
// 计算X轴坐标
int x = 0;
int y = h / 2 - hight / 2;
saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile,
quality);
}
// 否则如果是缩放后的图像的高度和要求的图像高度一样,就对缩放后的图像的宽度进行截取
else if (h == hight)
{
// 计算X轴坐标
int x = w / 2 - width / 2;
int y = 0;
saveSubImage(srcImage, new Rectangle(x, y, width, hight), saveFile,
quality);
}
in.close();
}
/**
*
* Description : 截图
*
* @param image
* 需要截图的图片源
* @param subImageBounds
* 子图范围
* @param subImageFile
* 子图文件
* @param quality
* 压缩质量
* @throws IOException
*
*/
private static void saveSubImage(BufferedImage image,
Rectangle subImageBounds, File subImageFile, float quality)
throws IOException
{
if (subImageBounds.x < 0 || subImageBounds.y < 0
|| subImageBounds.width - subImageBounds.x > image.getWidth()
|| subImageBounds.height - subImageBounds.y > image.getHeight())
{
System.out.println("Bad subimage bounds");
return;
}
BufferedImage subImage = image.getSubimage(subImageBounds.x,
subImageBounds.y, subImageBounds.width, subImageBounds.height);
compressImage(subImage, subImageFile, quality);
}
/**
*
* Description : 压缩图片 只对输出为jpeg类型的图片进行压缩,其它输出类型图片不进行压缩处理
*
* @param inFile
* 输入图片文件
* @param outFile
* 输出图片文件
* @param quality
* 压缩质量
* @throws IOException
*
*/
public static void compressImage(File inFile, File outFile, float quality)
throws Exception
{
boolean needCompressFlag = true;
String inFileName = inFile.getName();
String inFormatName = "";
int pos = inFileName.lastIndexOf('.');
if (pos > -1)
{
inFormatName = inFileName.substring(pos + 1).toLowerCase();
}
if (StringUtils.isBlank(inFormatName))
{
throw new IllegalArgumentException("输入图片文件必须要有后缀名!");
}
String outFileName = outFile.getName();
String outFormatName = "";
pos = outFileName.lastIndexOf('.');
if (pos > -1)
{
outFormatName = outFileName.substring(pos + 1).toLowerCase();
}
if (StringUtils.isBlank(outFormatName))
{
throw new IllegalArgumentException("输出图片文件必须要有后缀名!");
}
boolean jpgFlag = "jpg".equals(outFormatName)
|| "jpeg".equals(outFormatName);
// 相同文件类型,但输出不是jpg,直接图片复制
if (outFormatName.equals(inFormatName) && !jpgFlag)
{
FileUtil.copy(inFile, outFile);
return;
}
InputStream in = new FileInputStream(inFile);
BufferedImage inImage = ImageIO.read(in);
if (jpgFlag)
{
int sw = inImage.getWidth();
int sh = inImage.getHeight();
long inSize = inFile.length();
needCompressFlag = ((sw * sh * 0.21) < inSize);
if (needCompressFlag)
{
compressImage(inImage, outFile, quality);
if (outFile.length() > inSize)
{
needCompressFlag = false;
}
}
}
if (!needCompressFlag)
{
ImageIO.write(inImage, outFormatName, outFile);
}
in.close();
}
/**
*
* Description : 压缩图片 只对输出为jpeg类型的图片进行压缩,其它输出类型图片不进行压缩处理
*
* @param image
* 图片源
* @param imageFile
* 输出图片文件
* @param quality
* 压缩质量
* @throws IOException
*
*/
private static void compressImage(BufferedImage image, File imageFile,
float quality) throws IOException
{
String fileName = imageFile.getName();
String formatName = "";
int pos = fileName.lastIndexOf('.');
if (pos > -1)
{
formatName = fileName.substring(pos + 1).toLowerCase();
}
if (StringUtils.isBlank(formatName))
{
throw new IllegalArgumentException("输出图片文件必须要有后缀名!");
}
boolean jpg = ("jpg".equals(formatName) || "jpeg".equals(formatName));
boolean needCompressFlag = 1.0f > quality;
if (needCompressFlag && jpg)
{
ImageWriter writer = null;
ImageTypeSpecifier type = ImageTypeSpecifier
.createFromRenderedImage(image);
Iterator<ImageWriter> iter = ImageIO.getImageWriters(type, "jpg");
if (iter.hasNext())
{
writer = (ImageWriter) iter.next();
}
if (writer == null)
{
ImageIO.write(image, formatName, imageFile);
return;
}
IIOImage iioImage = new IIOImage(image, null, null);
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
ImageOutputStream outputStream = ImageIO
.createImageOutputStream(imageFile);
writer.setOutput(outputStream);
writer.write(null, iioImage, param);
writer.dispose();
outputStream.flush();
outputStream.close();
return;
}
ImageIO.write(image, formatName, imageFile);
}
}
图片处理工具类
最新推荐文章于 2022-03-06 22:52:46 发布