Android平台RTMP推送|轻量级RTSP服务|GB28181设备接入模块之实时快照保存JPG还是PNG?

JPG还是PNG?

JPG和PNG是两种常见的图片文件格式,在压缩方式、图像质量、透明效果和可编辑性等方面存在显著差异。

  • 压缩方式:JPG是一种有损压缩格式,通过丢弃图像数据来减小文件大小,因此可能会损失一些图像细节和质量。而PNG使用的是无损压缩格式,它不会丢失任何原始图像数据,从而保持了图像的完整性和质量。
  • 图像质量:由于压缩方式的不同,JPG在压缩后会牺牲一部分图像数据,因此在图像质量上可能存在损失,例如可能会出现锯齿状边缘或颜色失真。相比之下,PNG的无损压缩可以保证原图像数据的完整性,其256个透明层次的设定可以使图片边缘平滑融合,从而消除图片锯齿边缘。
  • 透明效果:PNG支持透明度,可以用作背景透明的图片,而JPG则不支持透明效果。因此,如果你需要制作半透明的图像或者需要背景透明的图片,PNG是一个更好的选择。
  • 可编辑性:JPG是一种不可编辑的图片格式,一旦被保存为JPG格式,就无法进行修改。而PNG是一种可编辑的图片格式,可以通过图像编辑软件(如Photoshop)进行修改、编辑和重新保存。例如,你可以改变PNG图片中的文字样式、线条等元素。

Android推流端的截图设计

大牛直播SDK早期在做Android平台RTMP推流和轻量级RTSP服务模块的时候,截图考虑到PNG的特性,直接保存png图片,随着GB28181-2022规范的实施,规范里面有明确要求,需要支持JPG编码,为此我们针对截图这块,做了如下的调整(对应:实时快照):

原接口:

	 /*** 请使用新的CaptureImage接口, 这个接口只能保存PNG图片, 不推荐使用* Save current image during publishing stream(实时快照)** @param imageName: image name, which including fully path, "/sdcard/daniuliveimage/daniu.png", etc.** @return {0} if successful*/public native int SmartPublisherSaveCurImage(long handle,  String imageName);

值得注意的是,原接口如果需要截图,还需要调用SmartPublisherSaveImageFlag()。

新的接口,我们设计如下:

	/*** 新的截图接口, 支持JPEG和PNG两种格式* @param compress_format: 压缩格式, 0:JPEG格式, 1:PNG格式, 其他返回错误* @param quality: 取值范围:[0, 100], 值越大图像质量越好, 仅对JPEG格式有效, 若是PNG格式,请填100* @param file_name: 图像文件名, 例如:/dirxxx/test20231113100739.jpeg, /dirxxx/test20231113100739.png* @param user_data_string: 用户自定义字符串* @return {0} if successful*/public native int CaptureImage(long handle, int compress_format, int quality, String file_name, String user_data_string);

如何调用?

废话不多说,直接上代码:

    private SimpleDateFormat capture_image_date_format_;class ButtonCaptureImageListener implements OnClickListener {@SuppressLint("SimpleDateFormat")public void onClick(View v) {if(isPushingRtmp || isRecording || isRTSPPublisherRunning || isPushingRtsp){if (null == capture_image_date_format_)capture_image_date_format_ = new SimpleDateFormat("yyyyMMddHHmmssSSS");String timeStamp = capture_image_date_format_.format(new Date());String imageFileName = timeStamp;    //创建以时间命名的文件名称String imagePath = imageSavePath + "/" + imageFileName;int quality;boolean is_jpeg = true;if (is_jpeg) {imagePath += ".jpeg";quality = 100;}else {imagePath += ".png";quality = 100;}int capture_ret = libPublisher.CaptureImage(publisherHandle,is_jpeg?0:1, quality, imagePath, "test_user_data");Log.i(TAG, "capture_image ret:" + capture_ret + ", file:" + imagePath);}else{Log.e(TAG, "快照失败,请确保在推送、录像或内置RTSP服务发布状态..");}}}

截图成功,对应的event回调如下:

    class EventHandeV2 implements NTSmartEventCallbackV2 {@Overridepublic void onNTSmartEventCallbackV2(long handle, int id, long param1, long param2, String param3, String param4, Object param5) {Log.i(TAG, "EventHandeV2: handle=" + handle + " id:" + id);String publisher_event = "";switch (id) {.....case NTSmartEventID.EVENT_DANIULIVE_ERC_PUBLISHER_CAPTURE_IMAGE:publisher_event = "快照: " + param1 + " 路径:" + param3;if (0 == param1) {rename_image_file_name(param3, param2);publisher_event = publisher_event + "截取快照成功.." + ", 用户数据:" + param4;} elsepublisher_event = publisher_event + "截取快照失败..";break;....}}

如果需要对截图后的文件重命名(比如gb28181,我们会把截图时间返上来),便于统一管理,参考代码如下:

    private void rename_image_file_name(String file_name, long file_date_time_ms) {if (null == file_name || file_name.isEmpty()|| file_date_time_ms < 1 || null == capture_image_date_format_)return;try {java.io.File file = new File(file_name);if (!file.exists() || !file.isFile() || !file.canRead() || file.length() < 1)return;String file_name_extension = null;int index = file_name.lastIndexOf('.');if (index > -1)file_name_extension = file_name.substring(index + 1);Date file_date = new Date(file_date_time_ms);String new_file_name = capture_image_date_format_.format(file_date);if (file_name_extension != null && !file_name_extension.isEmpty())new_file_name += "." + file_name_extension;java.io.File new_file = new java.io.File(file.getParent(), new_file_name);if (file.renameTo(new_file))Log.i(TAG, "rename image file name ok, file_name:" + file_name + ", new:"+ new_file_name);elseLog.e(TAG, "rename image file name failed, file_name:" + file_name);} catch (Exception e) {Log.e(TAG, "rename_image_file_name Exception:", e);}}

总结

Android平台RTMP推送、轻量级RTSP还是GB28181设备对接模块,选择哪种图片格式主要取决于具体的使用需求。如果你需要压缩图像文件并且不关心原始图像的完整性,JPG可能是一个更好的选择。而如果你需要保持原始图像的完整性和质量,或者需要制作背景透明的图片,那么PNG可能是更好的选择。

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

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

相关文章

【AIGC】IP-Adapter:文本兼容图像提示适配器,用于文本到图像扩散模型

前言 IPAdapter能够通过图像给Stable Diffusion模型以内容提示&#xff0c;让其生成参考该图像画风&#xff0c;可以免去Lora的训练&#xff0c;达到参考画风人物的生成效果。 摘要 通过文本提示词生成的图像&#xff0c;往往需要设置复杂的提示词&#xff0c;通常设计提示词变…

系列十一、Spring Security登录接口兼容JSON格式登录

一、Spring Security登录接口兼容JSON格式登录 1.1、概述 前后端分离中&#xff0c;前端和后端的数据交互通常是JSON格式&#xff0c;而Spring Security的登录接口默认支持的是form-data或者x-www-form-urlencoded的&#xff0c;如下所示&#xff1a; 那么如何让Spring Securi…

Centos常用命令整理,常用的比较全了

目 录 1、更改文件拥有者 2、修改权限 3、修改⽂件⽇期 4、链接⽂件 5、⽇期操作 6、显⽰⽇历 7、显⽰⽂件头部 8、显⽰⽂件尾部 9、显⽰⽤户标识 10、查看当前登录的⽤户 11、显⽰都谁登录到机器上 12、显⽰当前终端上的⽤户名 13、寻找⽂件…

Open3D 反算点云缩放系数(21)

Open3D 反算点云缩放系数(21) 一、算法介绍二、算法实现1.方法12.方法2(通用)一、算法介绍 上一章按照指定的系数,对点云进行了等比例缩放,这里输入缩放后的两块点云,反算二者之间的缩放系数。 二、算法实现 已知使用的俩点云是1/2的缩放关系,用于验证计算结果是否…

redis五大基础数据类型的操作指令及示例

前言 近期回顾了Redis方面的技术&#xff0c;本文就redis的5大基础数据类型的指令做了一个总结并附上示例 一、Redis是什么&#xff1f; Redis是一种开源的内存数据库&#xff0c;它被用作缓存、消息代理和键值存储。它支持多种数据结构&#xff0c;如字符串、哈希、列表、集…

【数据结构】串,数组,广义表 | 笔记整理 | C/C++实现

文章目录 前言一、串1.1、串的定义1.2、案例引入1.3、串的类型定义和存储结构1.4、串的模式匹配算法1.4.1、BF算法1.4.2、KMP算法 二、数组2.1、数组的定义2.2、数组的抽象数据类型定义2.3、数组的顺序存储2.4、特殊矩阵的压缩存储 三、广义表四、病毒案例 前言 参考视频&…

Spring Security实现详解

一、WebSecurityConfigurerAdapter 总配置类&#xff1a; 1、介绍&#xff1a;配置类 2、主要方法&#xff1a; &#xff08;1&#xff09;configure&#xff08;HttpSecurity http&#xff09; protected void configure(HttpSecurity http) throws Exception {this.logge…

【C++】wxWidgets库实现窗体程序

一、安装wxWidgets库 在Debian系统上使用wxWidgets库来创建一个基本的窗体程序&#xff0c;首先需要确保已经安装了wxWidgets相关的库和开发工具。下面是安装wxWidgets的步骤&#xff1a; 打开终端&#xff0c;使用下述命令安装wxWidgets库及其开发文件&#xff1a; sudo ap…

etcd官方docker镜像及dockerfile问题处理

解决下我之前etcd使用docker镜像启动的坑 1、问题镜像docker-file&#xff1a; 这个dockerfile看着看不出来问题&#xff0c;但如果有人真的执行我之前两篇文章的文件&#xff0c;就会有问题&#xff0c;什么问题呢&#xff0c;无法连接到etcd&#xff0c;由于我是刚装上dock…

11k+star 开源笔记应用真香 centos部署教程

leanote binary installation on Mac and Linux (En) life edited this page on Jul 21, 2017 10 revisions Pages 26 Home How to develop leanote 如何开发leanote How to install leanote on Ubuntu? How to Upgrade Leanote Install Mongodb leanote api leanote …

js页面输出的方式

JavaScript 可以通过以下方式在页面中输出内容&#xff1a; 使用 document.write() 方法&#xff0c;将文本字符串直接写入 HTML 文档中。 document.write("Hello World!");使用 innerHTML 属性&#xff0c;向元素的内部插入 HTML 代码。 document.getElementById(&…

开源监控服务一瞥:Prometheus、Grafana、Zabbix、Nagios、Icinga和Open-Falcon

前言 随着信息技术的发展&#xff0c;监控服务在维护系统稳定性和性能方面变得越来越重要。本文将比较一些流行的开源监控服务&#xff0c;以帮助你选择适合你需求的解决方案。 监控服务对比 监控服务特点优势不足性能扩展性安全性Prometheus- 多维度数据模型- 监控容器化环…

MySQL之导入、导出远程备份

一、Navicat工具导入、导出 1.1 导入 第一步&#xff1a; 右键&#xff0c;点击运行SQL文件 第二步&#xff1a; 选择要运行的SQL&#xff0c;点击开始 第三步&#xff1a; 关闭即可 1.2 导出 第一步&#xff1a; 右键选择&#xff0c;导出向导 第二步&#xff1a; 选择SQL脚…

1.3MATLAB变量及其操作

变量 变量是内存单元的一个抽象&#xff0c;在MATLAB中&#xff0c;变量以字母开头&#xff0c;后接数字下划线构成&#xff0c;MATLAB中变量名最多占据 63 个字符。变量区分大小写标准函数及命令一般使用小写字母 赋值语句 变量 表达式(;)表达式(;)总结&#xff1a;加分号&…

C++ 实现游戏(例如MC)键位显示

效果&#xff1a; 是不是有那味儿了&#xff1f; 显示AWSD&#xff0c;空格&#xff0c;Shift和左右键的按键情况以及左右键的CPS。 彩虹色轮廓&#xff0c;黑白填充。具有任务栏图标&#xff0c;可以随时关闭字体是Minecraft AE Pixel&#xff0c;如果你没有装&#xff08;大…

约瑟夫环问题解决

链表 struct List {int data;struct List* next; }创建链表 单链表 实现 struct List* listCreate() {int data;struct List* head NULL;struct List* pre NULL;struct List* current NULL;while(scanf("%d",&data) && data ! -1){current (stru…

使用numpy处理图片——灰阶影像

大纲 载入图像灰阶处理lightnessaverageluminosity 灰阶&#xff08;Gray scale&#xff09;影像是每个像素只有一个采样颜色的图像。 载入图像 import numpy as np import PIL.Image as Imageimg Image.open(lena.png) data np.array(img)灰阶处理 我们有三种方法来生成这…

Linux中常使用的命令之ls、cd、pwd、mkdir、rmdir

ls: 列出目录 cd&#xff1a;切换目录 pwd&#xff1a;显示目前的目录 mkdir&#xff1a;创建一个新的目录 -m &#xff1a;配置文件的权限-p &#xff1a;帮助你直接将所需要的目录(包含上一级目录)递归创建起来&#xff01; rmdir&#xff1a;删除一个空的目录 注意这…

基本数据结构 | 并查集

基本介绍 并查集主要实现两个操作&#xff1a; 合并两个集合查询某个元素的祖宗节点 并查集的两个优化&#xff1a; 路径压缩&#xff1a; O ( l o g n ) O(logn) O(logn)按秩合并&#xff1a; O ( l o g n ) O(logn) O(logn)&#xff0c;代码比较复杂&#xff0c;一般不单…

基于springboot时间管理系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括时间管理系统的网络应用&#xff0c;在外国时间管理系统已经是很普遍的方式&#xff0c;不过国内的管理系统可能还处于起步阶段。时间管理系统具有时间管理功能的选择。时间管…