Java图片处理Thumbnailator

news/2024/9/21 12:30:12/文章来源:https://www.cnblogs.com/fswhq/p/17729487.html
原文链接:https://zhuanlan.zhihu.com/p/604121848

 

Thumbnailator是Google开源的优秀图片处理的第三方Java类库,比JDK自带的库要好用的多。

官网Github地址

Maven依赖

目前最新版本是0.4.19

<dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.19</version>
</dependency>

图片处理步骤

Thumbnailtor处理图片的步骤可以看我绘制的下图来说明。

 

主要分为三个步骤。

构建Thumbnails.Builder

要使用thumbnailtor,主要使用Thumbnails类,该类采用建造者模式设计,类中提供了很多返回Builder的静态方法。

 

正如上图所示,Thumbnails提供了通过字符串图片地址、File对象、URI对象等方式创建Thumbnails对象的方式。

of方法

of方法提供了多种参数,当然参数虽然不同,功能却是相同的。并且of支持多个参数,可以同时处理多个图片,不过要特别注意,处理多个图片的时候,输出方法也要使用支持输出多个图片的方法。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;public class ThumbnailsOfDemo {public static void main(String[] args) throws IOException {// 参数是本地文件路径,支持多参数
        Thumbnails.of("input/logo.png").scale(1D).toFile("output/o1.png");// File类型的参数,支持多参数
        Thumbnails.of(new File("input/logo.png")).scale(1D).toFile("output/o2.png");// BufferedImage类型参数
        BufferedImage bufferedImage = ImageIO.read(new File("input/logo.png"));Thumbnails.of(bufferedImage).scale(1D).toFile("output/o3.png");// FileInputStream类型
        File file = new File("input/logo.png");FileInputStream fis = new FileInputStream(file);Thumbnails.of(fis).scale(1D).toFile("output/o4.png");// 网络图片
        Thumbnails.of(new URL("https://programtalk-1256529903.cos.ap-beijing.myqcloud.com/202302061502561.png")).scale(1D).toFile("output/o4.png");}
}

scale代表缩放,toFile是输出图片的方法,先不要管,后面会讲到。代码执行完毕后,会生成五个图片。

fromFilenames方法

Thumbnails.fromFilenames(Iterable<String> files)方法支持接入多个图片,也就是说能处理多个图片。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.name.Rename;import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;public class ThumbnailsFromFilenamesDemo {/**
     * 使用FromFiles处理多个图片。
     */public static void main(String[] args) throws IOException {// 参数是本地文件路径,支持多参数
        File file = new File("input"); // input文件夹下有多个图片
        File[] files = file.listFiles();assert files != null;List<String> filenames = Arrays.stream(files).map(File::getPath).toList();Thumbnails.fromFilenames(filenames).scale(1D)// 这里必须使用`toFiles`,因为处理的是多图
                .toFiles(new File("output"), Rename.SUFFIX_HYPHEN_THUMBNAIL);}
}

toFiles的用法后面会讲解。

fromFiles方法

Thumbnails.fromFiles方法(Iterable<File> files)方法支持接入多个图片,也就是说能处理多个图片。不同于fromFilenames的是它的参数是Iterable<File>类型。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.name.Rename;import java.io.File;
import java.io.IOException;
import java.util.Arrays;public class ThumbnailsFromFilesDemo {/**
     * 使用fromFiles处理多个图片。
     */public static void main(String[] args) throws IOException {File file = new File("input");File[] files = file.listFiles();assert files != null;Thumbnails.fromFiles(Arrays.asList(files)).scale(1D)// 这里必须使用`toFiles`,因为处理的是多图
                .toFiles(new File("output"), Rename.SUFFIX_HYPHEN_THUMBNAIL);}
}

fromURLs方法

Thumbnails.fromURLs用于批量处理网络图片。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;public class ThumbnailsFromURLsDemo {/**
     * 使用fromURLs处理多个图片。
     */public static void main(String[] args) throws IOException {Thumbnails.fromURLs(List.of(new URL("https://programtalk-1256529903.cos.ap-beijing.myqcloud.com/202302061502561.png"), new URL("https://itlab1024-1256529903.cos.ap-beijing.myqcloud.com/202301311404082.png"))).scale(1D).toFiles(List.of(new File("output/fromURLs1.jpg"), new File("output/fromURLs2.jpg")));}
}

fromImages方法

Thumbnails.fromImages批量处理BufferedImage类型的图片。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.List;public class ThumbnailsFromImagesDemo {/**
     * 使用fromImages处理多个图片。
     */public static void main(String[] args) throws IOException {Thumbnails.fromImages(List.of(ImageIO.read(new URL("https://programtalk-1256529903.cos.ap-beijing.myqcloud.com/202302061502561.png")), ImageIO.read(new URL("https://itlab1024-1256529903.cos.ap-beijing.myqcloud.com/202301311404082.png")))).scale(1D).toFiles(List.of(new File("output/fromImages1.jpg"), new File("output/fromImages2.jpg")));}
}

fromInputStreams方法

Thumbnails.fromInputStreams批量处理InputStream类型的图片。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;public class ThumbnailsFromInputStreamsDemo {/**
     * 使用fromInputStreams处理多个图片。
     */public static void main(String[] args) throws IOException {Thumbnails.fromInputStreams(List.of(new FileInputStream("input/logo.png"), new FileInputStream("input/logo.png"))).scale(1D).toFiles(List.of(new File("output/fromInputStreams.jpg"), new File("output/fromInputStreams.jpg")));}
}

图片处理

讲解图片处理前,先准备一张图片(wx.png)。图片属性信息如下:

 

image-20230206163350487

 

图片尺寸

基本说明

图片尺寸控制可以通过widthheightsize, forceSizescale方法控制。

widthheightsize方法会默认保证原始图片比例(可以通过设置keepAspectRatio(false)取消,如果取消则等价于forceSize方法。),因为收到原始图片宽高比例的限制,即便设置了宽高可能也不会引起图片的尺寸(像素)变化(可能会导致图片大小变化)。

forceSize则会强制保证宽高,可能会导致图片拉伸。

scale是设置图片宽高比例,不大于1的数参数。

有以下异常情况要注意:

  • 调用widthheight方法后不能再使用size或者scale方法,否则会抛出异常。
  • 调用size方法后不能再使用scale方法,否则会抛出异常。
  • 调用scale方法后不能调用size、 scalekeepAspectRatio(boolean) 方法,否则会抛出异常。

代码示例

原图是宽=1710,高=624,宽高比≈2.74,那么目标的宽度是100,高度就会被计算为100 / 2.74 ≈ 36

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.IOException;public class ThumbnailsSizeDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/wx.png").size(100, 100).toFile("output/o1.png");}
}

处理完毕后图片信息如下:

 

size处理结果

 

可以看到确实是100X36的分辨率。

如果想不保证宽高比例,可以使用forceSize方法。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.IOException;public class ThumbnailsSizeDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/wx.png").forceSize(100, 100).toFile("output/o1.png");}
}

效果如下:

 

forceSize

 

通过scale,设置宽高比例来修改尺寸。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.IOException;public class ThumbnailsSizeDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/wx.png").scale(0.8).toFile("output/o1.png");}
}

代码中设置了scale=0.8

效果图如下:

 

scale

 

图片旋转

可以通过rotate(double angle),来旋转图片,参数是度,比如30代表30度。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.IOException;public class ThumbnailsRotateDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/wx.png").rotate(30) // 旋转30度
                // 此处size必须设置
                .size(100, 10).toFile("output/o1.png");}
}

 

image-20230206175947372

 

图片水印

通过watermark设置水印,有多个多态方法。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;public class ThumbnailsWatermarkDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/wx.png")// 水印放到右下角
                .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("input/watermark.png")), 0.5f).scale(1.74).toFile("output/o1.png");}
}

 

 

输出图片

输出格式

outputFormat(String format)方法用于设置输出文件格式。支持的格式可以通过ImageIO.getWriterFormatNames()获取。

我这里打印的格式列表是JPG jpg tiff bmp BMP gif GIF WBMP png PNG JPEG tif TIF TIFF jpeg wbmp

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import javax.imageio.ImageIO;
import java.io.IOException;public class ThumbnailsOutputFormatDemo {public static void main(String[] args) throws IOException {String[] writerFormatNames = ImageIO.getWriterFormatNames();for (String writerFormatName : writerFormatNames) {System.out.print(writerFormatName + " "); // JPG jpg tiff bmp BMP gif GIF WBMP png PNG JPEG tif TIF TIFF jpeg wbmp
        }Thumbnails.of("input/wx.png").scale(1.75)// 如果不设置默认跟原图片一致
                .outputFormat("JPG")// 设置质量
                .outputQuality(1F).toFile("output/o1");}
}

输出结果:

 

outputFormat

 

输出质量

通过outputQuality(float quality)设置输出质量,参数介于0和1之间,支持小数,数字越小质量越差。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.IOException;public class ThumbnailsOutputQualityDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/wx.png").scale(1.75)// 设置质量
                .outputQuality(1F).toFile("output/o1");}
}

输出到文件

单文件

使用toFile方法,将处理后的文件输出到指定文件,参数是文件路径,不是必须要指定文件后缀。

toFile要求文件读入的时候必须是单个源,例如如果是Thumbnails.of("input/logo.jpg","input/logo2.jpg"),使用toFile输出会抛出异常。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import javax.imageio.ImageIO;
import java.io.IOException;public class ThumbnailsToFileDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/logo.jpg").scale(1.75)// 默认如果文件已经存在,则不覆盖,可以设置allowOverwrite=true。
                .allowOverwrite(true)// 可以不指定文件后缀,默认是png
                .toFile("output/logo-new");}
}

默认如果文件已经存在,则不覆盖,可以设置allowOverwrite=true。

多文件

批量接入的文件处理完毕后,可以通过toFiles输出到指定目录下。

toFiles有三种多态方法

public void toFiles(File destinationDir, Rename rename) throws IOException // ①
public void toFiles(Rename rename) throws IOException // ②
public void toFiles(Iterable<File> iterable) throws IOException { // ③

①:第一个参数是文件夹路径,第二个参数是文件名处理类型。

NO_CHANGE:文件名不修改。

PREFIX_DOT_THUMBNAIL:追加 thumbnail.到文件名的开头。例如,给定 picture.jpg,结果为thumbnail.picture.jpg

SUFFIX_DOT_THUMBNAIL.thumbnail追加到文件扩展名之前的文件名。例如,给定 picture.jpg,结果为 picture.thumbnail.jpg

SUFFIX_HYPHEN_THUMBNAIL-thumbnail追加到文件扩展名之前的文件名。例如,给定 picture.jpg,结果为 picture-thumbnail.jpg

②:此方法是①的简化,等价于①中的第一个参数destinationDir为空。

③:参数是Iterable类型,也就是说可以给每个文件设置输出文件名。

代码示例如下:

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.name.Rename;import java.io.File;
import java.io.IOException;
import java.util.List;public class ThumbnailsToFilesDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/logo.jpg", "input/logo.png").scale(1.75)// 默认如果文件已经存在,则不覆盖,可以设置allowOverwrite=true。
                .allowOverwrite(true)// 可以不指定文件后缀,默认是png
                //.toFiles(new File("output"), Rename.NO_CHANGE);
                //.toFiles(Rename.NO_CHANGE);
                .toFiles(List.of(new File("output/1"), new File("output/2")));}
}

输出到输出流

单流

toOutputStream是将一个文件输出到输出流中。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;public class ThumbnailsToOutputStreamDemo {public static void main(String[] args) throws IOException {OutputStream os = new FileOutputStream("output/logo.png");Thumbnails.of("input/logo.jpg").scale(1.75).toOutputStream(os);}
}

多流

toOutputStreams是将一个文件输出到多个输出流中。

package cn.programtalk;import net.coobird.thumbnailator.Thumbnails;import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;public class ThumbnailsToOutputStreamsDemo {public static void main(String[] args) throws IOException {Thumbnails.of("input/logo.jpg", "input/logo.png").scale(1.75)// 这里文件后缀最好指定,写入到磁盘的文件没有文件后缀。.toOutputStreams(List.of(new FileOutputStream("output/1.jpg"), new FileOutputStream("output/2.png")));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/775710.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

局域网这客户端连接MySQL数据库,含(CMT X进阶屏连接MySQL数据库)

1:首先安装MySQL服务器,服务器端安装的是Server version: 8.0.37 MySQL Community Server - GPL版本 2. 修改MySQL配置文件允许远程访问找到并编辑MySQL配置文件my.ini,该文件通常位于C:\ProgramData\MySQL\MySQL Server <version>\my.ini。 使用文本编辑器(VsCode)…

EtherCAT主站重启及状态检测

VARxReset: BOOL;xReset_R:R_TRIG;xETC_StateOK:BOOL; END_VAR(*注:FB 实例声明 当设备仅有 1 个 EtherCAT 主站时,实例化名称应该是 ETHERCAT;如汇川 AM600/AM400 系列 当设备有 2 个 EtherCAT 主站时,实例化名称应该是 ETHERCAT_C 或者 ETHERCAT_D;如汇川 AC800 系列等*…

接口结果判断(Jemeter断言)

操作 与CSV结合起来跑多组用例减少手动测试 补充:CSV文件不仅可以写请求参数而且可以写响应结果 展示效果

fastapi 的uvicorn配置日志

目前从flask框架转fastapi,之前flask框架日志很好用。这次学习了fastapi的日志使用,第一种是自定义日志,这个不讲了,自己封装就好,第二种是使用uvicorn自带日志, Uvicorn 是 fastapi 框架的默认ASGI服务器,它提供了强大的异步能力和高性能。一、配置输出格式化 uvicorn …

MySQL 学习笔记 进阶(锁 下,InnoDB引擎 上)

锁锁-表级锁-表锁介绍表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM,InnoDB,BDB等存储引擎中。 对于表级锁,主要分为以下三类:表锁 元数据锁(meta data lock,MDL) 意向锁表锁对于表锁,分为两类:表共享读锁(read lock) 表…

伙伴匹配系统踩坑日记1

伙伴匹配系统踩坑日记1 前端初始化 文档参考https://cn.vitejs.dev/guide/输入指令后报错解决方法参考https://blog.csdn.net/qq_26018335/article/details/126201219 yarn安装默认在c盘所以其global和cache配置在c盘,输入以下指令查看默认配置在哪个盘 yarn global dir只要在…

OpenAI 向部分用户开放 GPT-4o 高级语音模式;AI 视频生成工具 Vidu 全球上线丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑的个人观点…

如何设计可扩展的RPC协议

如何设计可扩展且向后兼容的RPC协议 为什么不直接用现成的HTTP协议? RPC的职责是负责应用间的通信,所以性能要求相对更高。而HTTP协议的数据包相对于请求数据本身要大很多,有很多冗余内容(如换行回车等),会影响性能。另外HTTP协议是无状态的协议,每次请求都要重新建立连接…

DataX - [02] 安装部署

题记部分 一、安装部署 (1)下载DataX:http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz wget http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz(2)解压到合适的目录:tar -zxvf datax.tar.gz -C /home/ecs-user/module/(3)进入b…

部署STONE-CRM中小企业的客户关系管理系统

Gitee地址 https://gitee.com/xpliu2166/stone-crm?skip_mobile=true环境查看# cat /etc/redhat-release Rocky Linux release 9.3 (Blue Onyx) # uname -a Linux Rocky9StoneCrm003080 5.14.0-362.18.1.el9_3.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Sun Feb 11 13:49:23 UTC 20…

全新小体积RK3562核心板,解锁神秘技能!

RK3562小体积金手指系列核心板基于瑞芯微四核Cortex-A53+Cortex-M0处理器设计,工作主频高达2GHz,最高搭载4GB高速LPDDR4、32GB eMMC。该核心板拥有204 Pin脚,尺寸仅为67.6mm *45mm,支持千兆网、USB3.0、串口、PCIE、HDMI等丰富外设资源,非常适合于高性能、高性价比的工业应…