java转webp

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xu_san_duo/article/details/79085718

java转换图片格式,生成webp图片文件

公司最近的新项目,有移动端,所以需要对普通图片进行压缩,减少图片的大小。这样既能较少用户耗费的流量,又能提高用户浏览速度,而且图片质量基本上和压缩前保持不变,有利于提升用户体验。

  • webp简介
  • webp环境配置
  • webp转换工具类
  • 可能出现的异常
  • 图片上传controller demo
  • jar包上传到nexus私服

webp简介

  • WebP是谷歌的图片格式,java 类库imageio 是不支持此种格式的。目前除了在线转换以及工具以外,第三方类库转webp格式大致有:
  • linux:Google libwebp 既是类库也可以在命令行调用
  • Python:Python Image Library(PIL)及其分支 https://pypi.python.org/pypi/PIL 不太了解
  • Java:luciad/webp-imageio https://bitbucket.org/luciad/webp-imageio/src windows / linux亲测可用

webp环境配置

  • 本例使用的webp的环境
    • Windows 10 专业版,Windows 7 x86 ,Windows 7 x64
    • Linux server244 3.10.0-514.21.1.el7.x86_64 #1 SMP Thu May 25 17:04:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
  • 环境配置所需资源下载:webp开发工具包(java)
  • 这里使用的webp-imageio这个包,需要根据操作系统和jdk位数,来编译一些环境配置文件(通常使用cmake编译,这个我不是很懂),但是我怀疑最终是通过修改native方法来实现的。
  • 配置环境:将对应的dll或者os文件,放到安装的jdk的bin下面(java.library.path下),比如我的电脑里如下图:
  • 注意:.dll文件是windows用的,.os文件是linux的。当然,资源包里还准备的有macos的

这里写图片描述

  • linux下:建议写一个Test.java,然后敲命令javac Test编译,再敲命令java Test运行编译后的文件,就能输出当前系统下的java.library.path
public class Test{

    public static void main(String[] args) {
        String a = System.getProperty("java.library.path");
        System.out.println(a);
    }
}
例如我的是:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
然后把对应的.os文件放在/usr/java/packages/lib/amd64里面(没有这个文件夹就自己新建个)

webp工具类

  • 配好环境后,应该就可以直接跑工具类的main方法了
import javax.imageio.ImageIO;

import java.awt.image.BufferedImage;
import java.io.*;

import java.net.URL;

/**
 * Description: 普通格式图片转换为webp格式图片 工具类
 *  耗时稍长,建议异步调用
 *
 * @author XU SAN DUO
 * Date: 2018/1/11 15:13
 * @version 1.0
 */
public class ImageToWebpUtil {

    public static final String WEBP = "webp";
    public static final String WEBP_SUFFIX = ".webp";

    /**
     * 1. 传入图片文件路径,返回file对象
     * @param imgFilePath 图片文件路径(比如转换图片为F:/1.png 那么转换后的webp文件为:F:/1.png.webp)
     * @return
     */
    public static File toWebpFile(String imgFilePath){
        File imgFile = new File(imgFilePath);
        File webpFile = new File(imgFilePath + WEBP_SUFFIX);
        try {
            BufferedImage bufferedImage = ImageIO.read(imgFile);
            ImageIO.write(bufferedImage, WEBP, webpFile);
        }catch (Exception e){
            e.printStackTrace();
        }
        return webpFile;
    }

    /**
     * 2. 传入图片url,返回file对象
     * @param imgUrlPath 图片路径url
     * @param webpFilePath 生成的webp文件路径
     * @return
     */
    public static File toWebpFile(String imgUrlPath, String webpFilePath){
        File webpFile = new File(webpFilePath);
        try {
            BufferedImage bufferedImage = ImageIO.read(new URL(imgUrlPath));
            ImageIO.write(bufferedImage, WEBP, webpFile);
        }catch (Exception e){
            e.printStackTrace();
        }
        return webpFile;
    }

    /**
     * 3. 传入图片文件路径,返回InputStream
     * @param imgFilePath 图片文件路径(比如转换图片为F:/1.png 那么转换后的webp文件为:F:/1.png.webp)
     * @return
     */
    public static InputStream toWebpStream(String imgFilePath){
        File imgFile = new File(imgFilePath);
        File webpFile = new File(imgFilePath + WEBP_SUFFIX);
        FileInputStream fis = null;
        try {
            BufferedImage bufferedImage = ImageIO.read(imgFile);
            ImageIO.write(bufferedImage, WEBP, webpFile);
            fis = new FileInputStream(webpFile);
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return fis;
    }

    /**
     * 4. 传入图片url,返回InputStream
     * @param imgUrlPath 图片路径url
     * @param webpFilePath 生成的webp文件路径
     * @return
     */
    public static InputStream toWebpStream(String imgUrlPath, String webpFilePath){
        File webpFile = new File(webpFilePath);
        FileInputStream fis = null;
        try {
            BufferedImage bufferedImage = ImageIO.read(new URL(imgUrlPath));
            ImageIO.write(bufferedImage, WEBP, webpFile);
            fis = new FileInputStream(webpFile);
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return fis;
    }

    // 测试
    public static void main(String[] args) {
        long start = System.currentTimeMillis();


        // 1. test 传入图片文件路径,返回file对象
//        String imgFilePath = "F:/test.png";
//        File result = toWebpFile(imgFilePath);

        // 2. test 传入图片url,返回file对象
        String imgUrlPath = "http://pic151.nipic.com/file/20171228/22164794_210348306033_2.jpg";
        String webpFilePath = "F:/xiche.jpg.webp";
        File result = toWebpFile(imgUrlPath,webpFilePath);

        // 3. test 传入图片文件路径,返回InputStream
//        String imgFilePath = "F:/test.png";
//        InputStream result = toWebpStream(imgFilePath);

        // 4. test 传入图片url,返回InputStream
//        String imgUrlPath = "http://pic151.nipic.com/file/20171228/22164794_210348306033_2.jpg";
//        String webpFilePath = "F:/xiche.jpg.webp";
//        InputStream result = toWebpStream(imgUrlPath,webpFilePath);


        long end = System.currentTimeMillis();
        System.out.println("用时:"+(end - start) + "  ms ; return ---->");
        System.out.print(result);
    }

}

可能出现的异常

  • java.lang.UnsatisfiedLinkError: no webp-imageio in java.library.path,说明环境没有配置好,解决办法:请重新仔细看一下上面说的环境配置
  • java.lang.NoClassDefFoundError: Could not initialize class com.luciad.imageio.webp.WebPWriteParam,虽然把对应的配置文件放在指定位置,但是是在应用程序启动之后放进去的,解决办法:重启你的application

图片上传controller demo

  • 这只是一个简易示例。(用的阿里的oss)
/**
 *
 * 文件上传
 * @param file 图片对象
 * @param fileUrl 要存放的ossKey
 * return
 */
@ApiOperation(value = "上传图片", httpMethod = "POST", notes = "上传图片")
@RequestMapping(value = "/uploadImg", method = RequestMethod.POST)
@ResponseBody
public ResultVO<Object> uploadImg(MultipartFile file, String fileUrl) {

    ResultVO<Object> result = new ResultVO<>();
    String logoUrlFileUrl = "";
    try {
        if (!file.isEmpty()) {
            logoUrlFileUrl += OSSFileOptUtils.uploadFile3(file, fileUrl, evnType);
            result.setData(logoUrlFileUrl);
            result.setStatus(ResultStatusEnum.OK.getValue());
            result.setMessage("上传图片成功");

            final String imgUrl = OssConstant.img_url_prefix + logoUrlFileUrl;
            final String webpKey = logoUrlFileUrl.substring(1) + ImageToWebpUtil.WEBP_SUFFIX;
            final String webpFilePath = this.webpFolder + file.getOriginalFilename() 
                + ImageToWebpUtil.WEBP_SUFFIX;
            new Thread(new Runnable(){
                @Override
                public void run() {
                    File webp = ImageToWebpUtil.toWebpFile(imgUrl,webpFilePath);
                    OSSFileOptUtils.uploadFile(OssConstant.shanghai_bucket_name,webpKey,webp,1);
                    log.info("【已上传webp文件:"+webpKey+"】");
                }
            }).start();
        }
    } catch (Exception e) {
        e.printStackTrace();
        result.setStatus(ResultStatusEnum.ERROR.getValue());
        result.setMessage("上传图片失败!");
        log.error("上传失败", e);
    }
    return result;
}

jar包上传到nexus私服

  • 这个webp的作者目前还没有把它上传到maven repository,而我们实际开发中,公司里一般都有自己搭建的nexus私服。所以这里就再啰嗦一点,写一下如何上传webp.jar到nexus私服
  • 仅介绍命令行上传

    • 安装nexus私服,略。但是要记住 ++id++ 和 ++url++

      <distributionManagement>
          <repository>
              <id>nexus-releases</id>
              <url>http://192.168.0.240:8081/repository/maven-releases/</url>
          </repository>
          <snapshotRepository>
              <id>nexus-snapshots</id>
              <url>http://192.168.0.240:8081/repository/maven-snapshots/</url>
          </snapshotRepository>
      </distributionManagement>
    • 假如现在有一个java项目,配置了maven。那么,需要在项目所依赖的maven的setting.xml中添加对这个nexus的配置:id,username,password一定要正确

      <server> 
          <id>nexus-releases</id> 
          <username>admin</username> 
          <password>admin123</password> 
      </server>
      <server> 
          <id>nexus-snapshots</id> 
          <username>admin</username> 
          <password>admin123</password> 
      </server>
    • 进入到项目根目录下,执行命令:(参数应该一看就懂)

    • 为什么要到项目根目录下执行:因为项目引用了setting.xml,而里面配置了username和password。这样就相当于有了权限
      mvn deploy:deploy-file -DgroupId=com.luciad.imageio -DartifactId=webp -Dversion=0.4.2 -Dpackaging=jar -Dfile=E:/a/webp-imageio-0.4.2.jar -Durl=http://192.168.0.240:8081/repository/maven-releases/ -DrepositoryId=nexus-releases
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页