前言

本文是关于iced库的部件介绍,iced库是基于rust的GUI库,作者自述是受Elm启发。

iced目前的版本是0.13.1,相较于此前的0.12版本,有较大改动。

本合集是基于新版本的关于分部件(widget)的使用介绍,包括源代码介绍、实例使用等。

环境配置

系统:window10

平台:visual studio code

语言:rust

库:iced 0.13

图像导入及显示

iced中显示图像,可以使用image部件,但image部件不是默认启用的,需要启用feature。在toml文件添加:

iced={version="0.13.1", features=["image"]}

然后在代码中导入:

use iced::widget::{button,column,text,row,container,slider,image};

之前我们在介绍为iced窗口设置图标时还提到过一个外部图像库image:

image="0.25.5"

导入image,为了不与iced的image部件名称冲突,需要为image改个名称:

extern crate image as eximg;

1、图像导入

图像导入,通常需要使用文件对话框来导入文件,在iced中并没有提供对应的部件,因此,我们需要使用一个外部库,RFD,首先在toml中添加:

rfd="0.15.2"

下面是rfd库支持的功能:



包括了文件导入、保存、文件夹选择等,当然rfd也可以支持消息对话框。

use rfd::{FileDialog,MessageDialog};

本文的目的是实现图像文件的导入与显示,并可以调整一些图像属性,如大小、透明度等,因此,我们将添加一个按钮用于触发文件选中对话框,获取图像文件的路径并显示。

我们为结构体添加一个变量用于记录图像路径:

#[derive(Clone)]
struct Counter {
slidervalue:f32,
slidervalue2:f32,
imgpath:String,
}

上述imgpath即图像路径变量,另外两个变量用于接受slider部件的实时值,因为我们需要调整图像的大小和透明度,正好可以适应slider,而关于slider的使用介绍,我们在上一篇博文里有单独介绍:

[rustGUI][iced]基于rust的GUI库iced(0.13)的部件学习(02):滑动条部件实现部件(文本或其他)缩放(slider)

然后我们添加按钮触发消息:

#[derive(Debug,Clone, Copy)]
enum Message {
SliderChange(f32),
SliderChange2(f32),
BtnLoad,
}

上述的BtnLoad是按钮触发消息,另外两个是slider的滑动时触发,就不多说了。

我们希望的是,点击按钮时弹出文件对话框,因此需要在view函数里添加:

let btn_load=button(text("加载图片").size(15)).width(80).height(40)
.on_press(Message::BtnLoad);

然后在update函数里更新状态:

Message::BtnLoad =>{
if let Some(file)=FileDialog::new()
.set_title("选择图片")
.add_filter("Image",&["png","jpg","jpeg","bmp"])
.add_filter("png",&["png"])
.set_directory("C://")
.pick_file(){ println!("当前选择的文件:{:?}",file);
self.imgpath=file.display().to_string(); }; }

上述代码中,FileDialog::new()是rfd库中文件夹选择的用法,看rfd的官方示例:



我们在实例中,将获取的图像路径传递给我们设置的变量imgpath。

2、图像显示

当我们获取到了图像的本地路径之后,就可以使用iced的image部件来显示图像,我们首先来看下iced中image的定义:

官方源码
#[derive(Debug)]
pub struct Image<Handle = image::Handle> {
handle: Handle,
width: Length,
height: Length,
content_fit: ContentFit,
filter_method: FilterMethod,
rotation: Rotation,
opacity: f32,
}

我们主要关注的就是handle这个参数,它的类型是Handle,可以理解为图像的原始数据来源,Handle在iced中的定义:

官方源码
pub enum Handle {
/// A file handle. The image data will be read
/// from the file path.
///
/// Use [`from_path`] to create this variant.
///
/// [`from_path`]: Self::from_path
Path(Id, PathBuf), /// A handle pointing to some encoded image bytes in-memory.
///
/// Use [`from_bytes`] to create this variant.
///
/// [`from_bytes`]: Self::from_bytes
Bytes(Id, Bytes), /// A handle pointing to decoded image pixels in RGBA format.
///
/// Use [`from_rgba`] to create this variant.
///
/// [`from_rgba`]: Self::from_rgba
Rgba {
/// The id of this handle.
id: Id,
/// The width of the image.
width: u32,
/// The height of the image.
height: u32,
/// The pixels.
pixels: Bytes,
},
}

可以看到,Handle定义了三种获取图像原始数据的方式,一种是直接从图像路径获取,一种是图像的字节数组获取,一种是从rgba数据获取。

我们在本文显然是使用第一种方式,即图像路径来获取handle,用于显示。iced官方给了典型的image使用代码:

image("ferris.png")

这是最简单的应用,不过我们在实例使用时,因为希望能调整图像的大小与透明度,所以可以这样写:

let img_handle=image::Handle::from_path(self.imgpath.clone());
let img1=image(img_handle).opacity(opacity).width(img_w).height(img_h);

其中,opacity用于调整透明度,width和height用于调整图像尺寸。

我们来看下实际显示效果:

3、图像调整

有了之前slider调整text文字大小的经验,此处就比较简单了,因为我们已经获取了图像路径,显然也就能获取图像尺寸了,这里,我们使用外部的image库来处理。image库的功能还是很强大的,看下它支持的图像处理格式:



为了方便管理,我们将获取图像尺寸封装为一个函数,与此前的img_to_icon函数放到一起,使用时直接调用即可:

///
/// 获取图片大小
///
/// 例:jpg or png -> (w,h)
pub fn get_img_size(path:&str) ->(f32,f32){ if path != "" {
let img_re=eximg::open(path);
match img_re{
Ok(img)=>{
return (img.width() as f32,img.height() as f32)
},
Err(e)=>{
let res=MessageDialog::new()
.set_title("错误")
.set_level(rfd::MessageLevel::Error)
.set_buttons(rfd::MessageButtons::Ok)
.set_description(&e.to_string())
.show();
if res == rfd::MessageDialogResult::Yes{
return (0.0,0.0)
}
return (0.0,0.0)
}
}
//return (img.width() as f32,img.height() as f32)
}
return (0.0,0.0) }
 let img_size=imgprocess::get_img_size(&self.imgpath);

看下完整的view函数:

let btn_load=button(text("加载图片").size(15)).width(80).height(40)
.on_press(Message::BtnLoad);
let sl1=slider(
0.0..=1.0,
self.slidervalue,
Message::SliderChange)
.height(40).width(200)
.step(0.01); let opacity= self.slidervalue;
let tt1=text("透明度:").size(15);
let tt2=text(format!("{:.2}",opacity)).size(15);
let row1=row![tt1,sl1,tt2,].spacing(10)
.align_y(iced::Center); let slider_scale=slider(0.1..=2.0,self.slidervalue2,Message::SliderChange2)
.height(40).width(200)
.step(0.01);
let tt3=text("缩放:").size(15);
let tt4=text(format!("{:.2}",self.slidervalue2)).size(15);
let row2=row![tt3,slider_scale,tt4,].spacing(10); let tt_imgpath=text("当前图片路径:").size(15);
let tt_imgpath2=text(format!("{}",self.imgpath)).size(15);
let row3=row![tt_imgpath,tt_imgpath2,].spacing(10); let img_handle=image::Handle::from_path(self.imgpath.clone());
let img_size=imgprocess::get_img_size(&self.imgpath);
let img_w=img_size.0 * self.slidervalue2;
let img_h=img_size.1 * self.slidervalue2;
let tt_imgsize=text(format!("图片大小:{:?}",img_size)).size(15);
//let row4=row![].spacing(10); let img1=image(img_handle).opacity(opacity).width(img_w).height(img_h);
//let cont_color=Color::from_rgb(120.0, 120.0, 0.0);
let cont_color2=iced::color!(0xE9E7E7,0.5);//#E9E7E7FF
let cont_img=container(img1)
.width(1000).height(1000)
.align_x(iced::Center).align_y(iced::Center)
.style(move |t|styles::mycontainerstyle(t, cont_color2)); column![
btn_load,
row1,
row2,
row3,
tt_imgsize,
cont_img,
].align_x(iced::Center)
.padding(20)
.into()

它整体显示效果如下:

4、综述

先来看看动态演示:



结合前文slider的使用,本文介绍了如何在iced中导入图像、显示图像以及调整图像,当然也是很简单的示例。比如导入按钮,后续将会使用菜单替代。

[rustGUI][iced]基于rust的GUI库iced(0.13)的部件学习(03):图像的导入、显示、调整(暨image部件的使用介绍)的更多相关文章

  1. [OpenCV实战]28 基于OpenCV的GUI库cvui

    目录 1 cvui的使用 1.1 如何在您的应用程序中添加cvui 1.2 基本的"hello world"应用程序 2 更高级的应用 3 代码 4 参考 有很多很棒的GUI库,例 ...

  2. 新做的一个基于OPENGL的gui库

    #include <BGE/All> ,text);     button->setName(name);     button->setSize(Vector2f(,)); ...

  3. Python GUI库

    PyQT不错的,只是要小心,这个东西是GPL的,如果你要写商业程序需要购买商业版授权.另外PyGTK.wxPython都是不错的GUI库.Python自带了一个基于TkInter的GUI库,如果你不想 ...

  4. C# 基于Directshow.Net lib库 USB摄像头使用DirectShow.NET获取摄像头视频流

    https://blog.csdn.net/u010118312/article/details/91766787 https://download.csdn.net/download/u010118 ...

  5. 8个免费实用的C++GUI库(转载)

      C++标准中并没有包含GUI,这也使得C++开发图形化界面需要依赖于第三方的库.实际上,图形界面恰恰是C++的强项,小到平常使用的各类桌面软件,大到魔兽世界这样的游戏,都是C++擅长的地方.C++ ...

  6. Python 图形 GUI 库 pyqtgraph

    原文  Python 图形 GUI 库 pyqtgraph pyqtgraph 是纯 Python 图形 GUI 库,基于PyQT4 /pyside和NumPy.它主要目的用于在数学/科学/工程中.M ...

  7. 8个免费实用的C++GUI库

    8个免费实用的C++GUI库 C++标准中并没有包含GUI,这也使得C++开发图形化界面需要依赖于第三方的库.实际上,图形界面恰恰是C++的强项,小到平常使用的各类桌面软件,大到魔兽世界这样的游戏,都 ...

  8. C/C++编程GUI库比较

    转自:http://blog.csdn.net/lostown/article/details/658654 最强的GUI库当属Qt,毕竟是商业化的东西,功能最完整,什么都好,包括类似java代码风格 ...

  9. 用PYTHON首选的GUI库WXPYTHON做程序界面

    大家好,我是A8U神经网络,今天又要跟大家分享一下wxWidgets开发神经网络程序界面的一些经验,希望对开发有兴趣的朋友有所帮助.跨平台的GUI工具库以GTK +,Qt和wxWidgets闻名. G ...

  10. Qt和其它GUI库的对比

    http://c.biancheng.net/view/3876.html 世界上的 GUI 库多如牛毛,有的跨平台,有的专属于某个操作系统:有的只有 UI 功能,有的还融合了网络通信.多媒体处理.数 ...

随机推荐

  1. 《HelloGitHub》第 103 期

    兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. github.com/521xueweihan/HelloG ...

  2. Docker Compose容器编排--项目五

    一.Docker Compose概念 Docker Compose (可简称Compose)是一个定义与运行复杂应用程序的 Docker 工具,是 Docker 官方 编排(Orchestration ...

  3. 共享存储ISCSI

    建立共享iscsi磁盘组 资源环境 服务端:192.168.2.131 客户端:192.168.2.[110,169] 服务端磁盘: [root@centos ~]# lsblk NAME MAJ:M ...

  4. CF2030E MEXimize the Score 题解

    题面 假设我们将数组 \(b\) 中的元素分割成任意多个 \(k\) 的非空多集 \(S_1, S_2, \ldots, S_k\) ,其中 \(k\) 是一个任意的正整数.定义 \(b\) 的分值为 ...

  5. 使用yt-dlp下载youtube高清2k 60fps视频

    只演示windows下的操作,linux和mac应该差不多的命令行. 首先放上github仓库地址:https://github.com/yt-dlp/yt-dlp 它的介绍: 厉害啊,支持数千个网站 ...

  6. 鸿蒙NEXT开发案例:亲戚关系计算器

    [引言] 在快节奏的现代生活中,人们往往因为忙碌而忽略了与亲戚间的互动,特别是在春节期间,面对众多的长辈和晚辈时,很多人会感到困惑,不知道该如何正确地称呼每一位亲戚.针对这一问题,我们开发了一款基于鸿 ...

  7. 读书笔记-C#8.0本质论-03

    15. 委托和lambda表达式 15.1 委托概述 namespace ConsoleApp1; internal static class Program { private enum SortT ...

  8. HarmonyOS Next 入门实战 - 创建项目、主题适配

    ​开发一个简单的demo,其中涉及一些鸿蒙应用开发的知识点,其中涉及导航框架,常用组件,列表懒加载,动画,深色模式适配,关系型数据库等内容,在实践中学习和熟悉鸿蒙应用开发. ​​ ​​ 首先下载并安装 ...

  9. LeetCode题集-5 - 最长回文子串之马拉车(二)

    书接上回,我们今天继续来聊聊最长回文子串的马拉车解法. 题目:给你一个字符串 s,找到 s 中最长的回文子串. 01.中心扩展法优化-合并奇偶处理 俗话说没有最好只有更好,看着O(n^2)的时间复杂度 ...

  10. openEuler欧拉安装Docker

    ​1. dnf配置 # 更新镜像源缓存 dnf makecache # 修改chrony时间同步配置 sed -i 's/pool pool.ntp.org iburst/pool ntp.aliyu ...