import java.awt.Color
import java.awt.Graphics2D
import java.awt.Image
import java.awt.geom.AffineTransform
import java.awt.image.AffineTransformOp
import java.awt.image.BufferedImage
import java.io.File
import java.io.IOException
import java.nio.Buffer
import javax.imageio.ImageIO
import javax.imageio.stream.ImageOutputStream
/**
*
* @author CSDN 没有梦想-何必远方
*/
public class ImgUtils {
/**
* 缩放图片方法
*
* @param srcImageFile
* 要缩放的图片路径
* @param result
* 缩放后的图片路径
* @param height
* 目标高度像素
* @param width
* 目标宽度像素
* @param bb
* 是否补白
*/
public final static void scale(String srcImageFile, String result,
int height, int width, boolean bb) {
try {
double ratio = 0.0 // 缩放比例
File f = new File(srcImageFile)
BufferedImage bi = ImageIO.read(f)
Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH)// bi.SCALE_SMOOTH
// 选择图像平滑度比缩放速度具有更高优先级的图像缩放算法。
// 计算比例
if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
double ratioHeight = (new Integer(height)).doubleValue()
/ bi.getHeight()
double ratioWhidth = (new Integer(width)).doubleValue()
/ bi.getWidth()
if (ratioHeight > ratioWhidth) {
ratio = ratioHeight
} else {
ratio = ratioWhidth
}
AffineTransformOp op = new AffineTransformOp(AffineTransform// 仿射转换
.getScaleInstance(ratio, ratio), null)// 返回表示剪切变换的变换
itemp = op.filter(bi, null)// 转换源 BufferedImage 并将结果存储在目标
// BufferedImage 中。
}
if (bb) {// 补白
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB)// 构造一个类型为预定义图像类型之一的
// BufferedImage。
Graphics2D g = image.createGraphics()// 创建一个
// Graphics2D,可以将它绘制到此
// BufferedImage 中。
g.setColor(Color.white)// 控制颜色
g.fillRect(0, 0, width, height)// 使用 Graphics2D 上下文的设置,填充 Shape
// 的内部区域。
if (width == itemp.getWidth(null))
g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
itemp.getWidth(null), itemp.getHeight(null),
Color.white, null)
else
g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
itemp.getWidth(null), itemp.getHeight(null),
Color.white, null)
g.dispose()
itemp = image
}
ImageIO.write((BufferedImage) itemp, "JPEG", new File(result)) // 输出压缩图片
} catch (IOException e) {
e.printStackTrace()
}
}
/**
* 裁剪图片方法
*
* @param bufferedImage
* 图像源
* @param startX
* 裁剪开始x坐标
* @param startY
* 裁剪开始y坐标
* @param endX
* 裁剪结束x坐标
* @param endY
* 裁剪结束y坐标
* @return
*/
public static BufferedImage cropImage(BufferedImage bufferedImage,
int startX, int startY, int endX, int endY) {
int width = bufferedImage.getWidth()
int height = bufferedImage.getHeight()
if (startX == -1) {
startX = 0
}
if (startY == -1) {
startY = 0
}
if (endX == -1) {
endX = width - 1
}
if (endY == -1) {
endY = height - 1
}
BufferedImage result = new BufferedImage(endX - startX, endY - startY,
4)
for (int x = startX x < endX ++x) {
for (int y = startY y < endY ++y) {
int rgb = bufferedImage.getRGB(x, y)
result.setRGB(x - startX, y - startY, rgb)
}
}
return result
}
public static void main(String[] args) throws IOException {
File input = new File("input.jpg")
BufferedImage img = ImageIO.read(input)
cropImage(img, 10, 10, 20, 20)
File output = new File("output.jpg")
ImageIO.write(img, "jpg", output)
}
}
getSubimage方法是进行图片裁剪。
举例:
public static void main(String[] args) {
try {
//从特定文件载入
BufferedImage bi = ImageIO.read(new File("c:\\test.png"))
bi.getSubimage(0, 0, 10, 10)//前两个值是坐标位置X、Y,后两个是长和宽
} catch (IOException e) {
e.printStackTrace()
}
}
以下是进行的图片压缩,涉及到多个工具类。
/**
* 图片工具类
* 压缩图片大小
* @author Cyw
* @version 1.0
*/
public class ZIPImage {
private File file = null
private String outPutFilePath
private String inPutFilePath
private String inPutFileName
private boolean autoBuildFileName
private String outPutFileName
private int outPutFileWidth = 100// 默认输出图片宽
private int outPutFileHeight = 100// 默认输出图片高
private static boolean isScaleZoom = true// 是否按比例缩放
public ZIPImage() {
outPutFilePath = ""
inPutFilePath = ""
inPutFileName = ""
autoBuildFileName = true
outPutFileName = ""
}
/**
*
* @param ipfp
* 源文件夹路径
* @param ipfn
* 源文件名
* @param opfp
* 目标文件路径
* @param opfn
* 目标文件名
*/
public ZIPImage(String ipfp, String ipfn, String opfp, String opfn) {
outPutFilePath = opfp
inPutFilePath = ipfp
inPutFileName = ipfn
autoBuildFileName = true
outPutFileName = opfn
}
/**
*
* @param ipfp
* 源文件夹路径
* @param ipfn
* 源文件名
* @param opfp
* 目标文件路径
* @param opfn
* 目标文件名
* @param aBFN
* 是否自动生成目标文件名
*/
public ZIPImage(String ipfp, String ipfn, String opfp, String opfn,
boolean aBFN) {
outPutFilePath = opfp
inPutFilePath = ipfp
inPutFileName = ipfn
autoBuildFileName = aBFN
outPutFileName = opfn
}
public boolean isAutoBuildFileName() {
return autoBuildFileName
}
public void setAutoBuildFileName(boolean autoBuildFileName) {
this.autoBuildFileName = autoBuildFileName
}
public String getInPutFilePath() {
return inPutFilePath
}
public void setInPutFilePath(String inPutFilePath) {
this.inPutFilePath = inPutFilePath
}
public String getOutPutFileName() {
return outPutFileName
}
public void setOutPutFileName(String outPutFileName) {
this.outPutFileName = outPutFileName
}
public String getOutPutFilePath() {
return outPutFilePath
}
public void setOutPutFilePath(String outPutFilePath) {
this.outPutFilePath = outPutFilePath
}
public int getOutPutFileHeight() {
return outPutFileHeight
}
public void setOutPutFileHeight(int outPutFileHeight) {
this.outPutFileHeight = outPutFileHeight
}
public int getOutPutFileWidth() {
return outPutFileWidth
}
public void setOutPutFileWidth(int outPutFileWidth) {
this.outPutFileWidth = outPutFileWidth
}
public boolean isScaleZoom() {
return isScaleZoom
}
public void setScaleZoom(boolean isScaleZoom) {
this.isScaleZoom = isScaleZoom
}
public String getInPutFileName() {
return inPutFileName
}
public void setInPutFileName(String inPutFileName) {
this.inPutFileName = inPutFileName
}
/**
* 压缩图片大小
*
* @return boolean
*/
public boolean compressImage() {
boolean flag = false
try {
if (inPutFilePath.trim().equals("")) {
throw new NullPointerException("源文件夹路径不存在。")
}
if (inPutFileName.trim().equals("")) {
throw new NullPointerException("图片文件路径不存在。")
}
if (outPutFilePath.trim().equals("")) {
throw new NullPointerException("目标文件夹路径地址为空。")
} else {
if (!ZIPImage.mddir(outPutFilePath)) {
throw new FileNotFoundException(outPutFilePath
+ " 文件夹创建失败!")
}
}
if (this.autoBuildFileName) { // 自动生成文件名
String tempFile[] = getFileNameAndExtName(inPutFileName)
outPutFileName = tempFile[0] + "_cyw." + tempFile[1]
compressPic()
} else {
if (outPutFileName.trim().equals("")) {
throw new NullPointerException("目标文件名为空。")
}
compressPic()
}
} catch (Exception e) {
flag = false
e.printStackTrace()
return flag
}
return flag
}
// 图片处理
private void compressPic() throws Exception {
try {
// 获得源文件
file = new File(inPutFilePath + inPutFileName)
if (!file.exists()) {
throw new FileNotFoundException(inPutFilePath + inPutFileName
+ " 文件不存在!")
}
Image img = ImageIO.read(file)
// 判断图片格式是否正确
if (img.getWidth(null) == -1) {
throw new Exception("文件不可读!")
} else {
int newWidth
int newHeight
// 判断是否是等比缩放
if (ZIPImage.isScaleZoom == true) {
// 为等比缩放计算输出的图片宽度及高度
double rate1 = ((double) img.getWidth(null))
/ (double) outPutFileWidth + 0.1
double rate2 = ((double) img.getHeight(null))
/ (double) outPutFileHeight + 0.1
// 根据缩放比率大的进行缩放控制
double rate = rate1 >rate2 ? rate1 : rate2
newWidth = (int) (((double) img.getWidth(null)) / rate)
newHeight = (int) (((double) img.getHeight(null)) / rate)
} else {
newWidth = outPutFileWidth// 输出的图片宽度
newHeight = outPutFileHeight// 输出的图片高度
}
BufferedImage tag = new BufferedImage((int) newWidth,
(int) newHeight, BufferedImage.TYPE_INT_RGB)
/*
* Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
*/
tag.getGraphics().drawImage(
img.getScaledInstance(newWidth, newHeight,
Image.SCALE_SMOOTH), 0, 0, null)
FileOutputStream out = new FileOutputStream(outPutFilePath
+ outPutFileName)
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out)
encoder.encode(tag)
out.close()
}
} catch (IOException ex) {
ex.printStackTrace()
}
}
/**
* 创建文件夹目录
*
* @param filePath
* @return
* @throws Exception
*/
@SuppressWarnings("unused")
private static boolean mddir(String filePath) throws Exception {
boolean flag = false
File f = new File(filePath)
if (!f.exists()) {
flag = f.mkdirs()
} else {
flag = true
}
return flag
}
/**
* 获得文件名和扩展名
*
* @param fullFileName
* @return
* @throws Exception
*/
private String[] getFileNameAndExtName(String fullFileName)
throws Exception {
String[] fileNames = new String[2]
if (fullFileName.indexOf(".") == -1) {
throw new Exception("源文件名不正确!")
} else {
fileNames[0] = fullFileName.substring(0, fullFileName
.lastIndexOf("."))
fileNames[1] = fullFileName
.substring(fullFileName.lastIndexOf(".") + 1)
}
return fileNames
}
public Image getSourceImage() throws IOException{
//获得源文件
file = new File(inPutFilePath + inPutFileName)
if (!file.exists()) {
throw new FileNotFoundException(inPutFilePath + inPutFileName
+ " 文件不存在!")
}
Image img = ImageIO.read(file)
return img
}
/*
* 获得图片大小
* @path :图片路径
*/
public long getPicSize(String path) {
File file = new File(path)
return file.length()
}
}
//下面是测试程序
package com.sun.util.cyw
import java.awt.Image
import java.io.IOException
public class ImageTest {
public static void main(String[] args) throws IOException {
ZIPImage zip=new ZIPImage("d:\\","1.jpg","d:\\test\\","处理后的图片.jpg",false)
zip.setOutPutFileWidth(1000)
zip.setOutPutFileHeight(1000)
Image image=zip.getSourceImage()
long size=zip.getPicSize("d:\\1.jpg")
System.out.println("处理前的图片大小 width:"+image.getWidth(null))
System.out.println("处理前的图片大小 height:"+image.getHeight(null))
System.out.println("处理前的图片容量:"+ size +" bit")
zip.compressImage()
}
}
BufferedImage类有一个getSubimage()方法,以下来自APIpublic BufferedImage getSubimage(int x,
int y,
int w,
int h)
返回由指定矩形区域定义的子图像。返回的 BufferedImage 与源图像共享相同的数据数组。
参数:
x - 指定矩形区域左上角的 X 坐标
y - 指定矩形区域左上角的 Y 坐标
w - 指定矩形区域的宽度
h - 指定矩形区域的高度
返回:
BufferedImage,它是此 BufferedImage 的子图像。
抛出:
RasterFormatException - 如果指定区域不包含在此 BufferedImage 中。