Java工具-实现无损png转换jpg格式

目录

1、背景说明

2、通过代码实现格式转换

3、无损转化

4、说明

读取 PNG 图像:

创建空的 JPG 图像:

绘制 PNG 图像到 JPG 图像:

设置 JPG 图片压缩质量:

写入 JPG 文件并关闭流:

5、jpg转png


1、背景说明

在项目中遇到一个情况,在使用海康NVR在线管理平台中,名单库管理模块,需要上传人员照片,进行人脸库构建。但是上传照片限制使用jpg、jpeg等格式,并且不支持png格式。

1、首先想到通过直接修改文件后缀名,尝试后,再次上传。提醒格式不支持

2、通过代码实现格式转换

利用hutool工具中的ImgUtil工具类 ,通过如下代码实现转化。

转换后图片大小减少,内容有损

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;public static void png2jpg(String source, String dest) throws IOException {Path p1 = Paths.get(source);Files.list(p1).forEach(p -> {String filename = p.toFile().getName();if(filename.endsWith("jpg") || filename.endsWith("jpeg")){return ;}String newFile = dest + "/" + filename.substring(0, filename.indexOf(".") ) + ".jpg";ImgUtil.convert(p.toFile(), new File(newFile));});}

3、无损转化

使用原生BufferedImage、Graphics,直接绘制图片,并且保持图片1:1 不压缩

代码如下:

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;public class PngToJpgConverter {public static void main(String[] args) throws IOException {png2jpg("E:\\workspace\dest","E:\\workspace\\dest2");}public static void png2jpg(String source, String dest) throws IOException {Path p1 = Paths.get(source);Files.list(p1).forEach(p -> {String filename = p.toFile().getName();if(filename.endsWith("jpg") || filename.endsWith("jpeg")){return ;}String newFile = dest + "/" + filename.substring(0, filename.indexOf(".") ) + ".jpg";convert(p.toFile().getAbsolutePath(), newFile);});}// 原始文件绝对路径、新文件绝对路径public static void convert(String inputImagePath, String outputImagePath){try {// 读取 PNG 图像BufferedImage pngImage = ImageIO.read(new File(inputImagePath));// 创建空的 JPG 图像,使用相同的宽度、高度和 RGB 颜色模型BufferedImage jpgImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);// 将 PNG 图像绘制到 JPG 图像jpgImage.createGraphics().drawImage(pngImage, 0, 0, null);// 设置 JPG 图片压缩质量File outputFile = new File(outputImagePath);ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next();ImageOutputStream ios = ImageIO.createImageOutputStream(outputFile);jpgWriter.setOutput(ios);ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam();jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);jpgWriteParam.setCompressionQuality(1.0f); // 1.0f 表示最高质量// 写入 JPG 文件jpgWriter.write(null, new javax.imageio.IIOImage(jpgImage, null, null), jpgWriteParam);// 关闭流ios.close();jpgWriter.dispose();System.out.println("PNG image has been converted to JPG successfully.");} catch (IOException e) {e.printStackTrace();}}
}

4、说明

  1. 读取 PNG 图像

    BufferedImage pngImage = ImageIO.read(new File(inputImagePath));

    使用 ImageIO.read 方法读取 PNG 图像。

  2. 创建空的 JPG 图像

    BufferedImage jpgImage = new BufferedImage( pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);

    创建一个空的 JPG 图像,指定相同的宽度和高度,并使用 RGB 颜色模型。

  3. 绘制 PNG 图像到 JPG 图像

    jpgImage.createGraphics().drawImage(pngImage, 0, 0, null);

    使用 Graphics 对象将 PNG 图像绘制到 JPG 图像中。

  4. 设置 JPG 图片压缩质量

    ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next(); ImageOutputStream ios = ImageIO.createImageOutputStream(outputFile); jpgWriter.setOutput(ios); ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam(); jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); jpgWriteParam.setCompressionQuality(1.0f); // 1.0f 表示最高质量

    使用 ImageWriterImageWriteParam 来设置 JPG 的压缩质量,其中 1.0f 表示最高质量。

  5. 写入 JPG 文件并关闭流

    jpgWriter.write(null, new javax.imageio.IIOImage(jpgImage, null, null), jpgWriteParam); ios.close(); jpgWriter.dispose();

    将 JPG 图像写入文件,并关闭流和释放资源。

5、jpg转png

 try {
            // 读取 JPG 图像
            BufferedImage jpgImage = ImageIO.read(new File(inputImagePath));

            // 创建空的 PNG 图像,使用相同的宽度、高度和颜色模型
            BufferedImage pngImage = new BufferedImage(
                jpgImage.getWidth(), jpgImage.getHeight(), BufferedImage.TYPE_INT_ARGB);

            // 将 JPG 图像绘制到 PNG 图像
            pngImage.createGraphics().drawImage(jpgImage, 0, 0, null);

            // 写入 PNG 文件
            ImageIO.write(pngImage, "png", new File(outputImagePath));

            System.out.println("JPG image has been converted to PNG successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }

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

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

相关文章

最新开源:英伟达Nemotron-4 340B,哔哩哔哩Index-1.9B,谷歌RecurrentGemma-9B...

文章目录 1. 英伟达开源Nemotron-4 340B2. 哔哩哔哩开源轻量级模型 Index-1.9B3. 微软开源混合模型 Samba4. 谷歌开源 RecurrentGemma-9B,性能与Gemma相同5. Stable Diffusion 3 Medium:“最强文生图开源 AI 模型” 1. 英伟达开源Nemotron-4 340B 当地时…

C++初学者指南第一步---6.枚举和枚举类

C初学者指南第一步—6.枚举和枚举类 文章目录 C初学者指南第一步---6.枚举和枚举类1.作用域的枚举(enum class类型)(C11)2.无作用域的枚举(enum类型)3.枚举类的基础类型4.自定义枚举类映射5.和基础类型的互相转换 1.作用域的枚举(enum class类…

C++ std::forward()

在线调试网站&#xff1a; https://wandbox.org/ #include <iostream> #include <thread> #include <mutex> void func(int &&args) {std::cout << args << std::endl; }int main () {int a 10;func(20); …

idea 如何查看项目启动的端口号

方式一&#xff1a;查看Run/Debug Configurations: 打开IntelliJ IDEA&#xff0c;点击菜单栏的Run&#xff0c;然后选择Edit Configurations...&#xff0c;或者直接使用快捷键&#xff08;通常是Shift Alt F10然后选择Edit Configurations&#xff09;。 在打开的Run/Debug…

Python武器库开发-武器库篇之链接提取器(六十)

Python武器库开发-武器库篇之链接提取器&#xff08;六十&#xff09; 链接提取器介绍 链接提取器&#xff08;Link Extractor&#xff09;是一种用于从网页中提取链接的工具。它可以从网页的源代码中识别出所有的链接&#xff0c;并将这些链接提取出来。链接提取器可以用于各…

gitlab问题记录

You wont be able to pull or push project code via SSH until you add an SSH key to you 解决方案&#xff1a;https://blog.csdn.net/gufenchen/article/details/95663284

PHP框架详解-symfony框架

Symfony框架是一款面向PHP开发的开源框架&#xff0c;用于开发Web应用和RESTful API。它的目标是提高开发效率、可维护性和可扩展性。本文将详细介绍Symfony框架的核心概念、基本用法和高级特性。 第一部分&#xff1a;入门篇 简介&#xff1a;介绍Symfony框架的背景、特点和…

Python第二语言(十二、SQL入门和实战)

目录 1. Python中使用MySQL 1.1 pymysql第三方库使用MySQL 1.2 连接MySQL 1.3 操作数据库&#xff0c;创建表 1.4 执行查询数据库语句 2. python中MySQL的插入语句 2.1 commit提交 2.2 自动提交 3. pymysql案例 3.1 数据内容 3.2 DDL定义 3.3 实现步骤 3.4 文件操…

赶紧收藏!2024 年最常见 20道设计模式面试题(四)

上一篇地址&#xff1a;赶紧收藏&#xff01;2024 年最常见 20道设计模式面试题&#xff08;三&#xff09;-CSDN博客 七、结构型模式&#xff1a;请解释适配器模式和装饰器模式的区别。 适配器模式&#xff08;Adapter Pattern&#xff09;和装饰器模式&#xff08;Decorato…

用python克隆了前男友的声音

声音克隆开源项目推荐&#xff1a;MockingBird 项目简介 MockingBird 是一个由开源社区开发的声音克隆项目&#xff0c;托管在 GitHub 上。该项目旨在通过深度学习技术实现高质量的声音克隆&#xff0c;使用户能够合成任意人的声音&#xff0c;并生成自然、流畅的语音输出。M…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 单词大师(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f…

多版本GCC安装及切换

目录 1 背景2 安装3 配置4 切换4.1 切换到版本94.2 切换到版本10 1 背景 最近在研究C20中的协程需要安装GCC版本10。用到GCC多版本切换&#xff0c;记录步骤。 2 安装 运行如下命令安装两个版本编译器: sudo apt install gcc-9 g-9 sudo apt install gcc-10 g-103 配置 使…

010-基于Sklearn的机器学习入门:聚类(上)

本节及后续章节将介绍深度学习中的几种聚类算法&#xff0c;所选方法都在Sklearn库中聚类模块有具体实现。本节为上篇&#xff0c;将介绍几种相对基础的聚类算法&#xff0c;包括K-均值算法和均值漂移算法。 目录 10.1 聚类概述 10.1.1 聚类的种类 10.1.2 Sklearn聚类子模…

shell脚本使用

判断程序有没有运行 &#xff0c;没有则启动程序 #!/bin/sh# 替换为你要检查的程序名称 program_name"xxx"# 使用pgrep命令查找程序的进程ID pid$(pgrep -f "$program_name")# 如果没有找到进程ID&#xff0c;说明程序没有运行&#xff0c;启动程序 if [ …

搭建zookeeper、Kafka集群

搭建zookeeper、Kafka集群 1、绘制kafka的存储结构、副本机制2、搭建zookeeper集群3、搭建kafka集群4、使用kafka创建名为自己姓名汉语拼音的topic5、查看topic的分区和副本策略 1、绘制kafka的存储结构、副本机制 2、搭建zookeeper集群 实验环境准备&#xff1a; 3台服务器&…

封装一个工具类,拒绝重复代码!

一、介绍 为了简化开发过程并提高代码的可维护性&#xff0c;我们可以创建一个统一的工具类来处理这些需求。 在本文中&#xff0c;我将介绍如何使用SpringBoot创建一个返回多级菜单、多级评论、多级部门、多级分类的统一工具类。 介绍数据库字段设计 数据库设计 「主要是…

在C语言中,可以使用strtol函数来将字符串中的16进制数转换为10进制整数

在C语言中&#xff0c;可以使用strtol函数来将字符串中的16进制数转换为10进制整数&#xff0c;进而转换为MAC地址的字节表示。以下是一个将字符串形式的MAC地址转换为16进制表示的例子&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.…

npm install cnpm -g 报错4048

npm install cnpm -g 报错4048 设置淘宝镜像&#xff1a; 报错如下&#xff1a; 其他博主提供的方法都尝试了&#xff0c;比如管理员权限打开终端&#xff0c;删除.npmrc文件&#xff0c;清除缓存npm cache clean -f等都试了无效&#xff0c;最后怀疑是npm和cnpm版本不对应&…

数据库面试题-Redis

数据库面试题-Redis 1、Redis是什么?2、为什么要使用Redis?3、说说Redis和Memcache的异同?4、说说Redis的线程模型?5、为什么Redis是单线程模型效率也能那么高?6、为什么Redis需要把所有数据放到内存中?7、说说Redis 的同步机制?8、Redis中pipeline有什么好处,为什么要…

Springboot全局异常处理和统一返回结果

①统一返回结果 package com.ioc.exception;import lombok.Data;import java.io.Serializable;/*** 后端统一返回结果* param <T>*/ Data //使用泛型对Result返回类进行了封装 public class Result<T> implements Serializable {private Integer code; //编码&…