<Rust><iced>基于rust使用iced库构建GUI实例:图片的格式转换程序

前言
本专栏是Rust实例应用。

环境配置
平台:windows
软件:vscode
语言:rust
库:iced、iced_aw

概述
本文是专栏第二篇实例,是一个图像格式转换程序,基于rust图像处理库image以及文件处理库rfd。
UI演示:
在这里插入图片描述

系列博客链接
1、<Rust><iced>基于rust使用iced库构建GUI实例:动态改变主题色

本篇内容:
1、图像格式转换

程序结构介绍

本文涉及到的crate有iced、iced_aw、image、rfd等,详细看toml文件:

[package]
name = "img-convert"
version = "0.1.0"
edition = "2021"

[dependencies]

iced={version ="0.12.1",features = ["svg","canvas","image","multi-window"]}
iced_widget={version = "0.12.3"}
iced_aw={version = "0.9.3",features = ["menu","split","context_menu"]}

image={version = "0.25.1",features = ["ico"]}

rfd={version ="0.14.1"}

本篇涉及到的菜单构建等内容,不再赘述,详细请参看第一篇:
<Rust><iced>基于rust使用iced库构建GUI实例:动态改变主题色
下面主要说一下本篇所涉及的两个功能,一个是图片数据的处理,使用的是image库,一个是文件的对话框,使用的是rfd库。
先说下rfd库来操作文件,首先是文件的打开,获取文件路径:

 if let Some(res)=FileDialog::new()
                                                    .set_title("打开图像")
                                                    .add_filter("所有图像文件", &["png","jpg","jpeg","bmp","ico","tiff","gif"])
                                                    .add_filter("png", &["png"])
                                                    .add_filter("jpeg", &["jpeg","jpeg"])
                                                    .add_filter("bmp", &["bmp"])
                                                    .add_filter("ico", &["ico"])
                                                    .add_filter("tiff", &["tiff"])
                                                    .set_directory("C:\\")
                                                    .pick_file()
                                                    {
                                                        self.imgpath=res.display().to_string();
                                                    };

FileDialog是文件对话框,MessageDialog是消息对话框。都由rfd库实现:

use rfd::{FileDialog,MessageDialog};

本文使用的是单文件打开函数pick_file:

 /// Pick one file
    pub fn pick_file(self) -> Option<PathBuf> {
        FilePickerDialogImpl::pick_file(self)
    }

rfd也可以实现多文件打开、文件夹打开、多文件夹打开等:

/// Pick multiple files
    pub fn pick_files(self) -> Option<Vec<PathBuf>> {
        FilePickerDialogImpl::pick_files(self)
    }

    /// Pick one folder
    pub fn pick_folder(self) -> Option<PathBuf> {
        FolderPickerDialogImpl::pick_folder(self)
    }

    /// Pick multiple folders
    pub fn pick_folders(self) -> Option<Vec<PathBuf>> {
        FolderPickerDialogImpl::pick_folders(self)
    }

当然也包括文件保存路径的获取:

 pub fn save_file(self) -> Option<PathBuf> {
        FileSaveDialogImpl::save_file(self)
    }

可以看到,FileDialog的每个函数返回的都是枚举类型。获取路径时需要对错误进行处理,否则有问题时会崩溃。

实例代码分析

第二个是利用image库对图像进行处理,我们使用rfd库获取了图像的路径之后,如何将图像显示在窗口上呢?使用iced的image部件:

 let imghandle=image::Handle::from_path(&self.imgpath);
 let img1=image(imghandle).content_fit(iced::ContentFit::Fill);

如上,image部件的参数为图像数据,iced中定义为Handle,Handle的获取方式如下:

pub fn from_path
pub fn from_pixels
pub fn from_memory

而图片格式的转换,可以使用image库。需要注意的是,iced自带的image部件与image库的名字重名了,所以一起使用时需要重命名。

extern crate image as eximage;

image库转换图片格式的官方示例如下:
在这里插入图片描述
我们获取了图像的路径,然后使用image库先打开图像,获取其数据类型为DynamicImage,然后利用image的save功能,将打开图片转为另一种格式:

img2.save(destimg).unwrap()

image库支持的图片格式如下:
在这里插入图片描述
不过,实际转换时需要注意,有些图片之间的转换是有条件的,比如从png转jpeg,需要先丢掉图片的透明度,否则会报错。
另外,icon格式对尺寸有限制。

完整代码

imgconvert.rs

use eximage::{ImageBuffer, ImageResult,ImageFormat};
use rfd::MessageDialog;

///
/// 保存为对应格式图片
/// 
pub fn convertimg(srcimg:&str,destimg:&str){

    let src_fmt=get_img_format(srcimg);
    let dest_fmt=get_img_format(destimg);

    let img=eximage::open(srcimg).unwrap();
    let w=img.width();
    let h=img.height();
    println!("图片尺寸:{}*{}",w,h);
    //如果由png转jpeg,需要丢失透明度
    if src_fmt=="png" && dest_fmt=="jpeg"{
        let img2=img.to_rgb8();
        img2.save(destimg).unwrap()
    }else if dest_fmt=="ico"{
        if src_fmt=="jpeg" || src_fmt=="tiff"{
            println!("格式错误!");
            return;
        }else{
        if w>256 || h>256{
            println!("ico图片尺寸不能超过256*256");
            let res=MessageDialog::new().set_title("提示")
                                    .set_level(rfd::MessageLevel::Warning)
                                    .set_description("ico图片尺寸不能超过256*256,继续则为您转换为256,否则将取消转换")
                                    .set_buttons(rfd::MessageButtons::YesNo)                  
                                    .show();
            if res==rfd::MessageDialogResult::Yes{
                let img3=img.resize(128, 128, eximage::imageops::FilterType::Nearest);
                img3.save(destimg).unwrap();
            }else {
                println!("取消转换");
            }
             

        }
            
        else{

            img.save(destimg).unwrap();
            
            
        }
    }
    }
    else {
        img.save(destimg).unwrap()
    }

    
    
}

///
/// 获取图片后缀名
/// 
pub fn get_img_format(path:&str)->String{
    
    let res=path.split('.').last();
    let f1=match res{
        Some(x)=>x.to_string(),
        None=>String::from("")
    };
    return  f1;
}

///
/// 获取图片尺寸
/// 
pub fn get_img_size(path:&str)->(u32,u32){
    
    let img=eximage::open(path).unwrap();
    let w=img.width();
    let h=img.height();
    return (w,h);
}


动态演示

rustGUI图片转换演示

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分数计算 初级题目

今天继续更题。今天的题目是《第五单元 分数的加减法》初级题目。 定位&#xff1a;题目较为初级&#xff0c;适合预习 参考答案&#xff1a;CACCADACAABACBBCDBCB

day54 动态规划 part10 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

300.最长递增子序列 动规五部曲 1.dp[i]的定义 dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度 2.状态转移方程 位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 1 的最大值。 所以&#xff1a;if (nums[i] > nums[j]) dp[i] max(dp[i], dp…

C++ 50 之 继承中的对象模型

继承中的对象模型 在C编译器的内部可以理解为结构体&#xff0c;子类是由父类成员叠加子类新成员而成&#xff1a; #include <iostream> #include <string> using namespace std;class Base03{ public:int m_a; protected:int m_b; private:int m_c; // 哪怕是…

【机器学习】Dify:AI智能体开发平台版本升级

一、引言 关于dify&#xff0c;之前力推过&#xff0c;大家可以跳转 AI智能体研发之路-工程篇&#xff08;二&#xff09;&#xff1a;Dify智能体开发平台一键部署了解&#xff0c;今天主要以dify为例&#xff0c;分享一下如何进行版本升级。 二、版本升级 2.1 原方案 #首次…

《2023-2024中国数据资产发展研究报告》

中国电子信息产业发展研究院发布《2023-2024中国数据资产发展研究报告》&#xff08;下称《报告》&#xff09;&#xff0c;紧跟国家战略部署&#xff0c;调研国内数据资产发展现状&#xff0c;掌握数据价值实现路径&#xff0c;助力释放数字经济新动能。 《报告》从数据资产相…

dotnet new 命令详解

一、简介 dotnet new 命令用于基于指定的模板创建新项目、配置文件、解决方案。 二、常用选项 -o, --output <output>&#xff1a;指定创建项目后放置的目录名 示例&#xff1a; dotnet new console -o MyConsoleApp-n, --name <name>&#xff1a;指定项目的名…

操作系统复习-线程同步

互斥量 两个线程的指令交叉执行互斥量可以保证先后执行称为原子性 原子性是指一系列操作不可被中断的特性这一系列操作要么全部执行完成&#xff0c;要么全部没有执行不存在部分执行部分未执行的情况 互斥锁 互斥量是最简单的线程同步的方法互斥锁&#xff0c;处于两态之一的…

上位机能不能替代PLC实现控制?为什么一定要学上位机?

上位机是一个广泛用于自动化控制系统的术语&#xff0c;它通常指的是在自动化控制系统中&#xff0c;用于监控和控制下位机&#xff08;通常是嵌入式系统或者是PLC等&#xff09;的计算机系统。上位机可以通过各种通信协议&#xff08;如RS232、RS485、以太网等&#xff09;与下…

GitLab教程(四):分支(branch)和合并(merge)

文章目录 1.分支&#xff08;branch&#xff09;&#xff08;1&#xff09;分支的概念&#xff08;2&#xff09;branch命令 2.合并&#xff08;merge&#xff09;&#xff08;1&#xff09;三个命令pullfetchmergegit fetchgit mergegit pull &#xff08;2&#xff09;合并冲…

SVN 报错Error: Unable to connect to a repository at URL解决方法

1. 报错背景&#xff1a; 使用ssh 用svn拉取仓库代码时&#xff0c;出现如下报错&#xff1a; Can’t create session: Unable to connect to a repository at URL svn://127.0.0.1 …. Can’t connect to host ‘127.0.0.1’: Connection refused at C:/Program Files/Git/mi…

南师大GIS专业2024排名NO.1!!!

南师大GIS 666 学科专业实力666&#xff0c;研究方向多多多&#xff01; 有学术方向有开发应用方向&#xff0c; 有GIS&#xff08;建模、数字地形、基础理论和三维GIS等&#xff09;、 有Cartography &#xff08;叙事地图、动态地图、地图风格迁移等&#…

自养号测评全揭秘:沃尔玛卖家如何实现销量稳步增长

在沃尔玛这片激烈的商业战场上&#xff0c;我作为一位销售者&#xff0c;深知在这个竞争激烈的市场中&#xff0c;测评对于提升产品排名、权重以及销量的关键作用。随着测评需求的不断增长&#xff0c;我们意识到&#xff0c;寻找可靠的测评服务不再是简单的选择&#xff0c;而…

【刷力扣】23. 合并 K 个升序链表(dummy节点技巧 + 分治思维 + 优先队列)

目录 一、合并升序链表问题二、题目&#xff1a;[21. 合并两个有序链表](https://leetcode.cn/problems/merge-two-sorted-lists/description/)1、掌握dummy节点的技巧 三、题目&#xff1a;[23. 合并 K 个升序链表](https://leetcode.cn/problems/merge-k-sorted-lists/descri…

Linux DMA-Buf驱动框架

一、DMABUF 框架 dmabuf 是一个驱动间共享buf 的机制&#xff0c;他的简单使用场景如下&#xff1a; 用户从DRM&#xff08;显示驱动&#xff09;申请一个dmabuf&#xff0c;把dmabuf 设置给GPU驱动&#xff0c;并启动GPU将数据输出到dmabuf&#xff0c;GPU输出完成后&#xf…

Vscode flake8插件 python代码语法格式检测/代码过长等误报设置

在vscode中python格式检测使用flake8插件很方便&#xff0c;但是经常会报出一些不必要错误&#xff0c;影响开发效率&#xff0c;忽略这些错误可以帮助减少对于特定项目可能不太关键的PEP 8警告或代码风格问题的干扰&#xff0c;特别是在项目有自己的格式化和编码标准时。使用f…

一款经典BUCK DCDC降压芯片TPS5430适合24V转5V转12V及其电路图

前言&#xff1a; TPS5430封装和丝印 经典老款DCDC&#xff0c;适合24V转5V、24V转12V及其它24V转其它电压降压使用&#xff0c;对于输入电压较低&#xff0c;如输入12V电压的&#xff0c;不推荐使用该芯片&#xff0c;该芯片出现时间较长&#xff0c;且非同步整流芯片&#xf…

React@16.x(29)useRef

目录 1&#xff0c;介绍2&#xff0c;和 React.createRef() 的区别3&#xff0c;计时器的问题 目前来说&#xff0c;因为函数组件每次触发更新时&#xff0c;都会重新运行。无法像类组件一样让一些内容保持不变。 所以才出现了各种 HOOK 函数&#xff1a;useState&#xff0c;u…

北方工业大学24计算机考研情况,学硕专硕都是国家线复试!

北方工业大学&#xff08;North China University of Technology&#xff0c;NCUT&#xff09;&#xff0c;简称“北方工大”&#xff0c;位于北京市&#xff0c;为一所以工为主、文理兼融&#xff0c;具有学士、硕士、博士培养层次的多科性高等学府&#xff0c;是中华人民共和…

Python读取wps中的DISPIMG图片格式

需求&#xff1a; 读出excel的图片内容&#xff0c;这放在微软三件套是很容易的&#xff0c;但是由于wps的固有格式&#xff0c;会出现奇怪的问题&#xff0c;只能读出&#xff1a;类似于 DISPIMG(“ID_2B83F9717AE1XXXX920xxxx644C80DB1”,1) 【该DISPIMG函数只有wps才拥有】 …
最新文章