java 压缩图片(只缩小体积,不更改图片尺寸)

1.情景展示

  在调用腾讯身份证OCR接口的时候,由于要求图片大小只能限制在1MB以内,这样,就必须使用到图片压缩技术。

2.代码展示

 /**
 * 图片处理工具类
 * @explain
 * @author Marydon
 * @creationTime 2019年9月3日上午10:14:17
 * @version 1.0
 * @since
 * @email marydon20170307@163.com
 */
public class ImgUtils {
    /**
     * 压缩图片(通过降低图片质量)
     * @explain 压缩图片,通过压缩图片质量,保持原图大小
     * @param quality 
     *       图片质量(0-1)
     * @return byte[]
     *      压缩后的图片(jpg) 
     * @throws
     */
    public static byte [] compressPicByQuality( byte [] imgByte,  float quality) {
        byte [] imgBytes =  null ;
        try {
            ByteArrayInputStream byteInput =  new ByteArrayInputStream(imgByte);
            BufferedImage image = ImageIO.read(byteInput);

            // 如果图片空,返回空
            if (image ==  null ) {
                return null ;
            }
            // 得到指定Format图片的writer(迭代器)
            Iterator iter = ImageIO.getImageWritersByFormatName( "jpeg" );
            // 得到writer
            ImageWriter writer = (ImageWriter) iter.next();
            // 得到指定writer的输出参数设置(ImageWriteParam )
            ImageWriteParam iwp = writer.getDefaultWriteParam();
            // 设置可否压缩
            iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
             // 设置压缩质量参数
            iwp.setCompressionQuality(quality);

            iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);

            ColorModel colorModel = ColorModel.getRGBdefault();
            // 指定压缩时使用的色彩模式
            iwp.setDestinationType(
                    new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel( 16 ,  16 )));

            // 开始打包图片,写入byte[]
            // 取得内存输出流
            ByteArrayOutputStream byteArrayOutputStream =  new ByteArrayOutputStream();
            IIOImage iIamge =  new IIOImage(image,  null ,  null );

            // 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput
            // 通过ImageIo中的静态方法,得到byteArrayOutputStream的ImageOutput
            writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream));
            writer.write( null , iIamge, iwp);
            imgBytes = byteArrayOutputStream.toByteArray();
        }  catch (IOException e) {
            System.out.println( "write errro" );
            e.printStackTrace();
        }
        return imgBytes;
    }
}

3.其它代码

  import org.apache.commons.codec.binary.Base64;

String imgBase64 =  "" ;
try {
    // 图片大小超过1MB
    if (file.getSize()/ 1024 >  1024 ) {
        byte [] imgBytes = ImgUtils.compressPicByQuality(file.getBytes(), 0 .1F);
        imgBase64 = Base64.encodeBase64String(imgBytes);
    }  else {
        imgBase64 = Base64.encodeBase64String(file.getBytes());
    }
}  catch (IOException e1) {
    e1.printStackTrace();
}

  说明:

  生成的base64图片没有图片格式头,即:data:image/jpeg;base64,

4.增加前端代码

 /**
 * 拍照或选择图片
 */
this .uploadPicture =  function () {
    // js 获取文件对象
    var fileObj = document.getElementById( "file" ).files[0];
    if ( null == fileObj) {
        alert( "图像上传失败,请重试!" );
    }
    // TODO 显示遮罩
   
    // 创建form表单
    var formFile =  new FormData();
    //加入文件对象
    formFile.append( "file" , fileObj);
    // 创建XMLHttpRequest 对象
    var xhr =  new XMLHttpRequest();
    xhr.open( "post" , baseUrl +  "/weixin/facein/upImg3.do" ,  true );
    xhr.onload =  function () {
        var resData = JSON.parse( this .responseText)
        // 将返回数据转换成JSON对象
        var json = eval( '(' + resData.data2 +  ')' );
        // 身份证识别成功
        if (json.ret == 0) {
            // TODO 将所需数据填充到页面
           
        }  else {
            alert( "识别失败,请重试!" + json.msg);
        }
        document.getElementById( "file" ).value =  "" ;
        // TODO 隐藏遮罩
    };
    // 调用腾讯接口
    xhr.send(formFile);
};

2024年2月25日21:46:01

图片压缩想要缩小体积的方式有且只有两种。

一种是:降低品质(可以理解为清晰度,就是咱们常说的画质),一种是缩小尺寸(分辨率)。

当品质降到足够低时还是无法满足的话,那在此基础上就要缩小图片尺寸啦。

以PS为例

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐:

posted @ 2019-09-08 15:57  Marydon  阅读(6415)  评论(2编辑  收藏  举报