如何使用Java快速地给图片转码和生成缩略图(Thumbnailator和webp |
您所在的位置:网站首页 › 图片格式的文件缩略图怎么弄出来 › 如何使用Java快速地给图片转码和生成缩略图(Thumbnailator和webp |
文章简介
本文中介绍,如何使用Java优雅处理图片;包括:主流图片格式转码、图片压缩(缩略图生成)等。主要用到的外部工具包: Google Thumbnailatorwebp-imageio-core本文同步博客图文( ´▽`):https://www.mintimate.cn/2021/01/19/JavaDealWithImage 同时,同步发布在腾讯云社区:https://cloud.tencent.com/developer/article/1779344 在线演示搭建了一个在线演示地址:https://tool.mintimate.cn/processIMG 和以前一样,我们觉得有用、有必要录个视频的内容,我们还是会花时间做个视频: B站视频:视频原链接,望投币嗷:https://www.bilibili.com/video/BV1nT4y1K7E6 腾讯云社区视频:视频链接地址,望点赞嗷:https://cloud.tencent.com/developer/video/10496 图片转码/生成缩略图 原理本次博客使用的Thumbnailator包,实际上是封装好的类和方法,基于Java的Image I/O API、Java 2D API等API接口实现。所以,因为基于Java Image I/O API,所以支持的图片格式有限,但是已经满足绝大多数情况。 一般支持的格式如下: Read:JPEG 2000, JPG, tiff, bmp, PCX, gif, WBMP, PNG, RAW, JPEG, PNM, tif, TIFF, wbmp, jpeg, jbig2, jpg, JPEG2000, BMP, pcx, GIF, png, raw, JBIG2, pnm, TIF, jpeg2000, jpeg 2000Write:JPEG 2000, JPG, tiff, bmp, PCX, gif, WBMP, PNG, RAW, JPEG, PNM, tif, TIFF, wbmp, jpeg, jpg, JPEG2000, BMP, pcx, GIF, png, raw, pnm, TIF, jpeg2000, jpeg 2000所以,像Apple的HEIC格式,是不支持使用Thumbnailator进行处理的。 如何安装首先添加lib包,如果你是Maven工程,或者使用Maven管理的项目,添加依赖: net.coobird thumbnailator [0.4, 0.5)上面的依赖项定义是获取0.4.x版本范围内的Thumbnailator的最新可用版本。如果需要特定版本的Thumbnailator,则将[0.4,0.5)替换为特定版本号,例如0.4.13 如果你不是Maven工程,可以下载Thumbnailator的最新版本,如何手动添加lib包,最新版本Thumbnailator下载:https://github.com/coobird/thumbnailator/releases/latest 如何使用Thumbnailator的使用十分简单,原本你需要使用Java的Image I/O API、BufferedImages和Graphics2D来处理图片,Thumbnailator直接封装上述操作。简单的使用演示: Thumbnails.of(new File("path/to/directory").listFiles()) .size(640, 480) .outputFormat("jpg") .toFiles(Rename.PREFIX_DOT_THUMBNAIL); 原图片地址:path/to/directory输出图片大小:640*480输出图片格式:jpgIO流输出地址(输出图片):Rename.PREFIX_DOT_THUMBNAIL 图片转码演示代码: Thumbnails.of(originalImage).scale(scale) .outputFormat("jpg") .outputQuality(compression) .toFile(thumbnailImage);其中: scale是图片尺寸等比缩放,为float类型。outputFormat是输出图片的类型,注意:默认不支持webp,如果需要使用webp,需要提前安装webp-imageio-core,可以看看下文如何使Java支持Webp。outputQuality是输出图片的质量,即:清晰度/分辨率。 使用原图片生成缩略图演示代码: Thumbnails.of(new File("original.jpg")) .size(160, 160) .toFile(new File("thumbnail.jpg"));其中,原图片文件,可以使用字符串String来代替地址: Thumbnails.of("original.jpg") .size(160, 160) .toFile("thumbnail.jpg");通常,缩略图输出体积已经很小,但是还是可以使用.outputQualit来降低图片质量(分辨率)。 旋转图片很简单;添加.rotate即可。如: Thumbnails.of(new File("original.jpg")) .rotate(90) .toFile(new File("image-with-watermark.jpg")); 添加水印添加水印也十分简单,添加.watermark即可: Thumbnails.of(new File("original.jpg")) .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("watermark.png")), 0.5f) .toFile(new File("image-with-watermark.jpg")); 实操演示我在我网站上使用上述包,搭建了一个在线演示地址:https://image.mintimate.cn/ 前端传送图片到后台,我们后台可以对文件扩展名进行判断: String thumbnailImageName=originalImage.getName(); //缩略图输出名 String thumbnailImagePath; //缩略图输出地址 switch (format){ case "JPG": thumbnailImagePath=System.getProperty("user.dir") + "/file/Output/" + thumbnailImageName.substring(0,thumbnailImageName.lastIndexOf("."))+".jpg"; break; case "PNG": thumbnailImagePath=System.getProperty("user.dir") + "/file/Output/" + thumbnailImageName.substring(0,thumbnailImageName.lastIndexOf("."))+".png"; break; case "WEBP": thumbnailImagePath=System.getProperty("user.dir") + "/file/Output/" + thumbnailImageName.substring(0,thumbnailImageName.lastIndexOf("."))+".webp"; break; case "BMP": thumbnailImagePath=System.getProperty("user.dir") + "/file/Output/" + thumbnailImageName.substring(0,thumbnailImageName.lastIndexOf("."))+".bmp"; break; default: thumbnailImagePath=System.getProperty("user.dir") + "/file/Output/" + thumbnailImageName; break; } 创建空白缩略图文件虽然Thumbnailator可以直接自动根据String创建对应文件对象,但是为了更方便我们自己控制,我们手动创建: File thumbnailImage = new File(thumbnailImagePath); // 判断路径是否存在,如果不存在则创建 if (!thumbnailImage.getParentFile().exists()) { thumbnailImage.getParentFile().mkdirs(); } 转码图片 try { switch (format){ case "JPG": Thumbnails.of(originalImage).scale(scale) .addFilter(new ThumbnailsImgFilter()) .outputFormat("jpg") .outputQuality(compression) .toFile(thumbnailImage); break; case "PNG": Thumbnails.of(originalImage).scale(scale) .outputFormat("png") .outputQuality(compression) .toFile(thumbnailImage); break; case "WEBP": Thumbnails.of(originalImage).scale(scale) .imageType(ThumbnailParameter.DEFAULT_IMAGE_TYPE) .outputFormat("webp") .outputQuality(compression) .toFile(thumbnailImage); break; case "BMP": Thumbnails.of(originalImage).scale(scale) .addFilter(new ThumbnailsImgFilter()) .outputFormat("bmp") .outputQuality(compression) .toFile(thumbnailImage); break; default: Thumbnails.of(originalImage).scale(scale) .imageType(ThumbnailParameter.DEFAULT_IMAGE_TYPE) .outputQuality(compression) .toFile(thumbnailImage); break; } } catch (IOException e) { e.printStackTrace(); }因为,我是使用Springboot快速构建,我其实是创建了一个配置规则addFilter,可以使PNG透明图片转为JPG时,透明背景渲染为白色。(单纯为了好看……)。实现细节: import net.coobird.thumbnailator.filters.ImageFilter; import java.awt.*; import java.awt.image.BufferedImage; public class ThumbnailsImgFilter implements ImageFilter { @Override public BufferedImage apply(BufferedImage bufferedImage) { int w = bufferedImage.getWidth(); int h = bufferedImage.getHeight(); BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D graphic = newImage.createGraphics(); graphic.setColor(Color.white);//背景设置为白色 graphic.fillRect(0, 0, w, h); graphic.drawRenderedImage(bufferedImage, null); graphic.dispose(); return newImage; } }这样,就可以成功转码图片了(运用恰当,还可以压缩图片( ;´Д`)): 根据Wiki百科:WebP(发音:weppy])是一种同时提供了有损压缩与无损压缩(可逆压缩)的图片文件格式,派生自影像编码格式,被认为是WebM多媒体格式的姊妹项目,是由Google在购买On2 Technologies后发展出来,以BSD授权条款发布。 而Webp具有的优势,显而易见: 更优的图像数据压缩算法更小的图片体积肉眼识别无差异的图像质量无损和有损的压缩模式Alpha 透明以及动画的特性 简单地说,它可以像PNG格式一样,保存无损画质,并保持图片透明特性;同时,可以像JPG一样,压缩图片。Webp在同等情况下,文件体积比PNG小,甚至比JPG还小。 Java如何支持Webp格式因为Webp,实际上是Google开发的,所以Java IO流设计之初就不支持Webp格式。所以根据系统的不同,需要安装对应的依赖包: /natives /linux_32 libxxx[-vvv].so /linux_64 libxxx[-vvv].so /osx_32 libxxx[-vvv].dylib /osx_64 libxxx[-vvv].dylib /osx_arm64 libxxx[-vvv].dylib /windows_32 xxx[-vvv].dll /windows_64 xxx[-vvv].dll /aix_32 libxxx[-vvv].so libxxx[-vvv].a /aix_64 libxxx[-vvv].so libxxx[-vvv].a可以参考项目:https://github.com/scijava/native-lib-loader 当然,你也可以直接用大神整合好的lib包,比如:webp-imageio-core;下文就详解如何使用。 webp-imageio-core使用因为webp-imageio-core并没有发布到Maven中央仓库,所以使用Maven骨架用户需要自己添加lib依赖 首先下载webp-imageio-core的jar发布包,下载地址:https://github.com/nintha/webp-imageio-core/releases 之后添加自定义: com.github.nintha webp-imageio-core {version} system ${pom.basedir}/libs/webp-imageio-core-{version}.jar比如:我的项目,添加本地lib: 最简单的使用……其实是再加入上文所提到的Thumbnailator依赖包,便可以使用Thumbnailator直接处理图片IO流。 单独使用,我们可以用最传统的方法处理: 图片转WEBP: public static void main(String args[]){ String srcFile = System.getProperty("user.dir") + "/file/Input/"+"Input.png" //原图地址 String webpFile = System.getProperty("user.dir") + "/file/Output/"+"Output.png" //输出地址 encodingToWebp(srcFile, webpFile); } public static void encodingToWebp(String srcFile, String webpFile) { encodingToWebp(new File(srcFile),new File(webpFile) ); } /** * @param: srcFile * @param: webpFile * @description: 将文件编码为WEBP格式 * @author: Mintimate */ public static void encodingToWebp(File srcFile, File webpFile) { try { // Obtain an image to encode from somewhere BufferedImage image = ImageIO.read(srcFile); // Obtain a WebP ImageWriter instance ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next(); // Configure encoding parameters WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale()); writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); writeParam.setCompressionType(writeParam.getCompressionTypes()[WebPWriteParam.LOSSLESS_COMPRESSION]); // Configure the output on the ImageWriter writer.setOutput(new FileImageOutputStream(webpFile)); // Encode writer.write(null, new IIOImage(image, null, null), writeParam); //释放reader writer.dispose(); //关闭文件流 fileImageOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } 最后感兴趣可以关注B站:Mintimate; 如果想进一步处理图片,需要基于系统工具包了: 比如:ImageMagick ImageMagick其实是真正全功能图片处理,但是Java调用前,系统需要预先安装ImageMagick,且Mac、Linux和Windows上调用方法有差异,有机会给大家介绍( ̀⌄ ́) |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |