<Rust><iced><resvg>基于rust使用iced构建GUI实例:使用resvg库实现svg转png
前言
本文是使用rust库resvg来将svg图片转为png图片。
环境配置
系统:windows
平台:visual studio code
语言:rust
库:resvg
代码分析
resvg是一个基于rust的svg渲染库,其官方地址:
An SVG rendering library
resvg库的核心是svg的渲染,但本文暂且不关注如何渲染svg,本文关注如何将svg转为png格式,官方有提供演示代码。
本文参考官方示例,将代码稍作修改,并结合rust的文件库rfd,编写一个简单的程序,可以导入svg图片,然后转为png图片,并保存。
首先看一下核心的转换代码:
官方代码:
fn main() {let args: Vec<String> = std::env::args().collect();if args.len() != 3 {println!("Usage:\n\tminimal <in-svg> <out-png>");return;}let tree = {let mut opt = usvg::Options::default();// Get file's absolute directory.opt.resources_dir = std::fs::canonicalize(&args[1]).ok().and_then(|p| p.parent().map(|p| p.to_path_buf()));opt.fontdb_mut().load_system_fonts();let svg_data = std::fs::read(&args[1]).unwrap();usvg::Tree::from_data(&svg_data, &opt).unwrap()};let pixmap_size = tree.size().to_int_size();let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();resvg::render(&tree, tiny_skia::Transform::default(), &mut pixmap.as_mut());pixmap.save_png(&args[2]).unwrap();
}
本地使用时,简单封装成一个函数,如下:
///
/// svg转png
///
pub fn svgtopng(svgpath: &str,destimgpath: &str,
)
{let mut opt=resvg::usvg::Options::default();opt.resources_dir=std::fs::canonicalize(svgpath).ok().and_then(|p| p.parent().map(|p| p.to_path_buf()));opt.fontdb_mut().load_system_fonts();let svgdata=std::fs::read(svgpath).unwrap();let tree=resvg::usvg::Tree::from_data(&svgdata,&opt).unwrap();let pixmap_size = tree.size().to_int_size();let mut pixmap = resvg::tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();resvg::render(&tree, resvg::tiny_skia::Transform::default(), &mut pixmap.as_mut());pixmap.save_png(destimgpath).unwrap();
}
转换的程序就好了,然后我们结合rust的GUI库iced来编写一个简单的带UI的转换程序,所以,我们还需要添加iced库,看一下toml文件:
[package]
name = "gui-serial"
version = "0.1.0"
edition = "2021"[dependencies]iced={version="0.12.1"}
iced_widget={version="0.12.3",features=[]}
serialport="4.3.0"
clap="4.5.7"image="0.25.1"resvg={version="0.42.0",features=[]}
关于iced以及rfd库的使用,此处不再赘述,可以参考本人的另外的博文:
Rust UI开发(三):iced如何打开图片(对话框)并在窗口显示图片?
我直接把主程序的代码贴在这:
use std::{io::{self,Write}, process::CommandArgs};use eximg::codecs::png;
use imgtoicon::image_to_icon;
use resvg::usvg::filter::Merge;
use serialport::{DataBits,StopBits,Parity};
//use clap::{value_parser, Arg, ArgAction, Command};
mod ser;
mod imgtoicon;
mod resvgpro;
use iced::{Application, Command, Element, Font, Renderer, Settings, Subscription};
use iced_widget::{container,button,text,column,row,svg,image};use rfd::FileDialog;extern crate resvg;
extern crate image as eximg;#[derive(Debug,Clone)]
enum Message{Cvt,Open,Save,
}
struct Serial{portname:String,baudrate:u32,databits:DataBits,stopbits:StopBits,parity:Parity,timeout:u64,openfile:String,destfile:String,
}
fn main() ->iced::Result {let myicon=imgtoicon::image_to_icon("..\\gui-serial\\img\\mainicon4.png");let myfont="微软雅黑";Serial::run(Settings{id:Some("mw".to_string()),window:iced::window::Settings{size:iced::Size{width:800.0,height:600.0},min_size:Some(iced::Size { width: 200.0, height: 200.0 }),max_size:Some(iced::Size { width: 1000.0, height: 800.0 }),position:iced::window::Position::Specific(iced::Point::new(100.0,100.0)),icon:Some(myicon),level:iced::window::Level::Normal,..Default::default()},default_font:Font::with_name(myfont),..Default::default()})}impl Application for Serial{type Executor = iced::executor::Default;type Message = Message;type Flags = ();type Theme = iced::Theme;fn new(flags: Self::Flags) -> (Self, Command<Self::Message>) {(Self{portname:String::from("COM1"),baudrate:9600,databits:DataBits::Eight,stopbits:StopBits::One,parity:Parity::None,timeout:1000,openfile:String::from(""),destfile:String::from(""),},Command::none())}fn title(&self) -> String {String::from("串口调试工具-rs")}fn update(&mut self, message: Self::Message) -> Command<Self::Message> {match message{Message::Cvt=>{resvgpro::svgtopng(&self.openfile,&self.destfile)}Message::Open=>{if let Some(file)=FileDialog::new().set_title("打开文件").add_filter("svg", &["svg"]).pick_file(){self.openfile=file.display().to_string();}else{println!("打开文件失败")};}Message::Save=>{if let Some(file)=FileDialog::new().set_title("保存文件").add_filter("png", &["png"]).save_file(){let filestr=file.display().to_string();resvgpro::svgtopng(&self.openfile, &filestr);self.destfile=filestr;}else{println!("保存文件失败")};}}Command::none()}fn subscription(&self) -> Subscription<Self::Message> {Subscription::none()}fn view(&self) -> Element<'_, Self::Message, Self::Theme, crate::Renderer> {//let btn1=button("转换").on_press(Message::Cvt);let btn2=button("打开").on_press(Message::Open);let btn3=button("转换并保存").on_press(Message::Save);let svghandle=svg::Handle::from_path(&self.openfile);let pnghandle=image::Handle::from_path(&self.destfile);let col1=column![btn2,text(format!("打开文件路径:{}",&self.openfile)).size(15),btn3,text(format!("保存文件路径:{}",&self.destfile)).size(15),//btn1,row![svg(svghandle).content_fit(iced::ContentFit::Contain).width(300),image(pnghandle).content_fit(iced::ContentFit::Contain).width(300),].padding(5).spacing(20),].padding(5).spacing(5);let cont=container(col1).padding(5);cont.into()}
}
实例演示:
相关文章:

<Rust><iced><resvg>基于rust使用iced构建GUI实例:使用resvg库实现svg转png
前言 本文是使用rust库resvg来将svg图片转为png图片。 环境配置 系统:windows 平台:visual studio code 语言:rust 库:resvg 代码分析 resvg是一个基于rust的svg渲染库,其官方地址: An SVG rendering li…...
面试突击:Java 中的泛型
本文已收录于:https://github.com/danmuking/all-in-one(持续更新) 前言 哈喽,大家好,我是 DanMu。今天想和大家聊聊 Java 中的泛型。 什么是泛型? Java 泛型(Generics) 是 JDK 5…...

3_2、MFC常用控件用法:组合框、滚动条和图片控件
MFC控件用法 1、组合框1.1 简介1.2 创建CComboBox类的主要成员函数 1.3 实例 2、滚动条控件2.1 简介2.2 创建CScrollBar类的主要成员函数 2.3 实例 3、图片控件3.1 简介3.2 创建图片控件静态加载图片图片控件动态加载图片 1、组合框 1.1 简介 组合框其实就是把一个编辑框和一…...

如何使用gprof对程序进行性能分析
如何使用gprof对程序进行性能分析 目录 1 gprof概述 2 gprof原理简述 3 gprof使用 3.1 gprof使用简述 3.2 gprof使用示例 4 小结 1 gprof概述 gprof 是 一个 GNU 的程序性能分析工具,可以用于分析C\C程序的执行性能。gprof工具可以统计出各个函数的调用次数、执…...

四川汇聚荣科技有限公司靠谱吗?
在如今这个信息爆炸的时代,了解一家公司是否靠谱对于消费者和合作伙伴来说至关重要。四川汇聚荣科技有限公司作为一家位于中国西部地区的企业,自然也受到了人们的关注。那么,这家公司究竟如何呢?接下来,我们将从多个角度进行深入…...

可灵王炸更新,图生视频、视频续写,最长可达3分钟!Runway 不香了 ...
现在视频大模型有多卷? Runway 刚在6月17号 发布Gen3 ,坐上王座没几天; 可灵就在6月21日中午,重新夺回了王座!发布了图生视频功能,视频续写功能! 一张图概括: 二师兄和团队老师第一…...
oracle中使用临时表GLOBAL TEMPORARY TABLE
需要在存储过程中返回一个临时结果集,这个结果集又是多个语句通过循环查询出来的,这时候就想到了将结果插入到临时表中,然后返回临时表的数据的思路,于是有了以下操作: 1.创建临时表 -- Create table create global …...

Gradio入门—快速开始
目录 安装构建您的第一个演示分享您的演示核心 Gradio 课程聊天机器人gr.ChatInterface自定义演示gr.BlocksGradio Python 和 JavaScript 生态系统 Gradio 是一个开源 Python 软件包,可让您快速为机器学习模型、API 或任何任意 Python 函数构建演示或 Web 应用程序。…...

AOP应用之系统操作日志
本文演示下如何使用AOP,去实现系统操作日志功能。 实现步骤 引入AOP包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.6.6</version></de…...

海外云手机自动化管理,高效省力解决方案
不论是企业还是个人,对于海外社媒的营销都是需要自动化管理的,因为自动化管理不仅省时省力,而且还节约成本; 海外云手机的自动化管理意味着什么?那就是企业无需再投入大量的人力和时间去逐一操作和监控每一台设备。 通…...
后仿真中的 《specify/endspecify block》之(5)使用specify进行时序仿真
前面我们学习了specify...endspecify 具体是什么东西。今天,我们使用specify block 中定义的延时,来进行一次仿真。看看到底是背后如何运转的呢。 一 基本例子 一个用 specify 指定延迟的与门逻辑描述如下: module and_gate(output Z,input A, B);assign Z = A & …...

win10/11磁盘管理
win10/11磁盘管理 合并磁盘分区的前提是你的两个磁盘区域是相邻的,比如如下: 如果需要吧这个磁盘进行分解,你可以选择压缩一部分磁盘或者是直接删除卷 我这里的话,因为压缩出来的卷和C盘好像是不相邻的(我之前做过&…...
【昇思初学入门】第四天打卡
数据变换Transforms 心得体会 MindSpore提供了丰富的数据变换工具,针对图像数据可以使用如Rescale、Normalize和HWC2CHW等,且使用Compose类允许我们定义一个变换序列,并将它们作为一个整体应用到数据上。 composed transforms.Compose([v…...

禁用/屏蔽 Chrome 默认快捷键
Chrome 有一些内置的快捷键,但是它并没有像其他软件一样提供管理快捷键的界面。在某些时候,当我们因为个人需求希望禁用 Chrome 某些快捷键时,又无从下手。 好在有开发者开发了 Chrome 插件,可以禁用 Chrome 快捷键的插件&#x…...

移动端+PC端应用模式的智慧城管综合执法办案平台源码,案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析
城市管理综合执法管理平台实现执法办案、业务全流程在线办理,依托移动端PC端的“两端”应用模式,保障能够通过信息化手段进行日常的执法办案工作,强化执法监督功能。提供了案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析等功能&a…...
AI音乐大模型时代:版权归属与创意产业的新生长点
AI在创造还是毁掉音乐? 简介:最近一个月,轮番上线的音乐大模型,一举将素人生产音乐的门槛降到了最低,并掀起了音乐圈会不会被AI彻底颠覆的讨论。短暂的兴奋后,AI产品的版权归属于谁,创意产业要…...
C++函数作为参数
C++函数作为参数 在C++中,函数作为另一个函数的参数是非常常见的做法,特别是在处理回调函数和泛型编程时。我们展示了如何在C++中将函数作为参数传递给另一个函数,包括普通函数、std::function 和 std::bind、lambda表达式以及类成员函数。每种方法都有其独特的优势,可以根…...

考前刷题练手感(北航期末往年数据结构编程题)
本次因为是考前一天极速刷题,所以没有讲解,若有问题可私信。 目录 一、 查找同时空人员二、 老鼠回家-无回路三、函数调⽤关系四、东二食堂模拟五、栈帧 一、 查找同时空人员 【问题描述】 假设一共有6个手机基站,都具有记录手机连接基站状…...

Android记录9--实现转盘效果
自定义View /2013.10.16_TurnPlate_Demo/src/com/wwj/turnplate/TurnPlateView.java package com.wwj.turnplate; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; im…...

【Oracle APEX开发小技巧1】转换类型实现显示小数点前的 0 以 及常见类型转换
在 apex 交互式式网格中,有一数值类型为 NUMBER,保留小数点后两位的项,在 展示时小数点前的 0 不显示。 效果如下: 转换前: m.WEIGHT_COEFFICIENT 解决方案: 将 NUMBER(20,2…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...