import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import javax.imageio.ImageIO;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
* 根据图片路径压缩图片至额定大小
* @param picUrl 需要压缩的图片路径
* @param scale 压缩比例 不能大于1,默认0.5
* @param quality 压缩品质介于0.1~1.0之间,默认0.75
* @param imgSize 图片大小压缩上限
* @param img 二次压缩图片对象
* @return
* @throws IOException
*/
public static byte[] imageCompress(String picUrl, float scale, float quality, long imgSize, Image img) throws IOException{
Image image = null;
if(img == null){//第一次是读取image
//根据图片路径获取图片转为字节输入流
URL url = new URL(picUrl);
URLConnection uc = url.openConnection();
InputStream in = uc.getInputStream();
//字节输入流转为要输出流
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = in.read(buff)) > 0) {
swapStream.write(buff, 0, rc);
}
byte[] imagSize = swapStream.toByteArray();
// System.out.println("图片实际大小:"+imagSize.length);
//如果图片本身大小已在限额内则直接返回图片字节输出流
if(imagSize.length <= imgSize)
return imagSize;
else
image = javax.imageio.ImageIO.read(url);
}
else{//第二次开始不读图片,直接把第一次的图片压缩
image = img;
}
//图片本身大小已超过限额,则根据比率从尺寸上降低
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
imageWidth = (int)(scale*imageWidth);
imageHeight = (int)(scale*imageHeight);
image = image.getScaledInstance(imageWidth, imageHeight, Image.SCALE_AREA_AVERAGING);
// Make a BufferedImage from the Image.
BufferedImage mBufferedImage = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = mBufferedImage.createGraphics();
g2.drawImage(image, 0, 0,imageWidth, imageHeight, Color.white,null);
g2.dispose();
float[] kernelData2 = {
-0.125f, -0.125f, -0.125f,
-0.125f,2, -0.125f,
-0.125f,-0.125f, -0.125f};
Kernel kernel = new Kernel(3, 3, kernelData2);
ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
mBufferedImage = cOp.filter(mBufferedImage, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(mBufferedImage);
// System.out.println(quality);
//降低图像品质(不是降低DPI)
param.setQuality(quality, true);//
encoder.setJPEGEncodeParam(param);
encoder.encode(mBufferedImage);
byte[] comImage = out.toByteArray();
// System.out.println(comImage.length);
if(comImage.length > imgSize){//如果图像压缩后大小还是超过限额则继续降低压缩比率降低品质
scale = scale - 0.10f;
quality = quality - 0.10f;
imageCompress(picUrl, scale, quality, imgSize, image);
}
return comImage;
}
/**
* 压缩图片到指定品质和比例
* @param picUrl 需要压缩的图片路径
* @param fileName 要压缩的图片名称
* @param toFileName 压缩后的图片名称
* @param scale 压缩比例 不能大于1,默认0.5
* @param quality 压缩品质介于0.1~1.0之间
*/
@SuppressWarnings("unused")
private static void imageCompress(String picUrl, String fileName,String toFileName,
float scale, float quality){
try {
long start = System.currentTimeMillis();
Image image = javax.imageio.ImageIO.read(new File(picUrl + fileName));
int imageWidth = image.getWidth(null);
int imageHeight = image.getHeight(null);
imageWidth = (int)(scale*imageWidth);
imageHeight = (int)(scale*imageHeight);
image = image.getScaledInstance(imageWidth, imageHeight, Image.SCALE_AREA_AVERAGING);
// Make a BufferedImage from the Image.
BufferedImage mBufferedImage = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = mBufferedImage.createGraphics();
g2.drawImage(image, 0, 0,imageWidth, imageHeight, Color.white,null);
g2.dispose();
float[] kernelData2 = {
-0.125f, -0.125f, -0.125f,
-0.125f,2, -0.125f,
-0.125f,-0.125f, -0.125f };
Kernel kernel = new Kernel(3, 3, kernelData2);
ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
mBufferedImage = cOp.filter(mBufferedImage, null);
FileOutputStream out = new FileOutputStream(picUrl + toFileName);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(mBufferedImage);
param.setQuality(quality, true);//默认0.75
encoder.setJPEGEncodeParam(param);
encoder.encode(mBufferedImage);
out.close();
long end = System.currentTimeMillis();
System.out.println("图片:"+fileName+",压缩时间:"+(end - start) + "ms");
}catch (FileNotFoundException fnfe){
fnfe.printStackTrace();
}catch (IOException ioe){
ioe.printStackTrace();
}catch(Exception ex){
ex.printStackTrace();
}
}
调用实例
public static void main(String[] args){
PicUtil.imageCompress("D:\\", "background_new.png", "background_new2.png", 0.9f, 0.9f);
}
分享到:
相关推荐
而images文件夹则通常包含与文档相关的图片,如产品实物图、结构示意图、接线图等,这些图像信息对理解和使用产品至关重要,因为它们直观地展示了产品的外观和工作原理。 综合以上信息,我们可以推测这篇文档可能...
这通常发生在用户需要通过电子邮件或其他方式传输大型文件时,为了减小文件大小而进行的额外压缩。在Windows或Mac操作系统中,可以通过解压软件(如WinRAR、7-Zip或Zip解压工具)来打开这样的双重压缩文件。 描述中...
2.5MM通常指的是连接器的尺寸规格,这在电子硬件领域是很常见的参数,用于标识接口的大小。5264可能是产品的型号或者特定的系列代码,它通常是制造商为了区分不同种类或功能的设备而设定的。条形连接器,也称为线束...
5.93M 的大小表明这是一个内容丰富的文件,包含了详细的产品图片、说明和技术数据。 **详细知识点:** 1. **低压配电系统**:低压配电系统是建筑电力供应的核心部分,用于将高压电网的电能转换成适合建筑物内部...
视频录像图像质量有多种等级可调,以改变存储文件大小,方便不同场合应用。 视频移动报警录像功能,报警录像灵敏度、预录像时间、延迟录像时间可调,支持声音 报警输出。 智能检索,可按摄像镜头年/月/日/时间...
图片未给出,但根据描述,需要识别哪种剪刀在正常使用时会是费力杠杆。 2. 滑轮组的机械效率:第二个选择题涉及到滑轮组的机械效率,机械效率是指有用功与总功的比率。若G1=G2,说明提升的重量相同,但甲和乙的滑轮...
人力资源管理软件支持照片的打印(照片对象标识 emp_pict,类型为图片)(感谢Lucky Cat) 员工编辑和管理体现工龄和年龄(打印标识对应age、work_age、work_age_c)(感谢hui~星辉~) 一个岗位允许对应多个部门...