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

news/2025/1/9 10:17:05/文章来源:https://www.cnblogs.com/rongjv/p/18659695

前言
本文是关于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、图像导入

image

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

rfd="0.15.2"

下面是rfd库支持的功能:
image
包括了文件导入、保存、文件夹选择等,当然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的官方示例:
image
我们在实例中,将获取的图像路径传递给我们设置的变量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_pathPath(Id, PathBuf),/// A handle pointing to some encoded image bytes in-memory.////// Use [`from_bytes`] to create this variant.////// [`from_bytes`]: Self::from_bytesBytes(Id, Bytes),/// A handle pointing to decoded image pixels in RGBA format.////// Use [`from_rgba`] to create this variant.////// [`from_rgba`]: Self::from_rgbaRgba {/// 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用于调整图像尺寸。
我们来看下实际显示效果:
image

3、图像调整

有了之前slider调整text文字大小的经验,此处就比较简单了,因为我们已经获取了图像路径,显然也就能获取图像尺寸了,这里,我们使用外部的image库来处理。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);//#E9E7E7FFlet 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()

它整体显示效果如下:
image

4、综述

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

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

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

相关文章

PyTorch团队为TorchAO引入1-8比特量化,提升ARM平台性能

在深度学习模型部署和优化领域,计算效率与资源消耗的平衡一直是一个核心挑战。PyTorch团队针对这一问题推出了创新性的技术方案——在其原生低精度计算库TorchAO中引入低位运算符支持。这一技术突破不仅实现了1至8位精度的嵌入层权重量化,还支持了具有8位动态量化激活的线性运…

设计团队管理的关键因素:如何确保成员高效协作

一、设计团队的组织架构 一个高效的设计团队通常有一个明确的组织架构,合理的分工与协作关系能够最大程度地提高团队的工作效率。在设计团队的组织架构中,一般包括项目经理、设计师、协调员以及可能的开发人员和客户代表。 1.1 项目经理(PM) 项目经理是设计团队的核心角色之…

欧阳的2024年终总结,迷茫,重生与失业

前言 这是欧阳第一次写年终总结,今年发生的事情还挺多的值得写篇文章记录一下。立个flag,以后每年都写一篇年终总结文章,5年后35岁再来看这些文章不知道是什么感觉。今年发生的事情可以总结为三个词语:迷茫、重生、失业。 欧阳也在找工作,坐标成都求内推! 事件 今年发生的…

JS将docx转为html代码--Vue3(简易版)

这两天突然接了一个把节气文章转成html页面的需求,本来只是需要多按几下ctrl+c,ctrl+v能解决的事,但是想想后续一年24个节气,就做个自动转换的工具吧。由于做软件还涉及到其他语言和配置环境,所以还是选择了web。 首先创建一个vue3项目,我用的vite搭建的,不会的请自行移步…

大语言模型提示技巧(八)-防止胡说八道

自然语言往往充满歧义和模糊性,模型在学习时可能会产生误解或错误理解一些概念,导致生成不准确的信息。为了尽量减少这些问题,研究人员和工程师会使用更大规模、更多样化和更准确的训练数据,调整模型架构,以及使用更先进的训练技术。但是自然语言本身就是复杂且充满挑战的…

使用API方式远程调用ollama模型

在有GPU的环境启动一个ollama大模型,非常简单:注意,ollama启动时默认监听在127.0.0.1:11434上,可以通过配置OLLAMA_HOST环境变量修改 `export OLLAMA_HOST="0.0.0.0:11434" ollama serve& ollama run qwen2.5:7b-instruct`然后就可以在远端访问: `curl http…

JMeter——压力测试工具的安装

JMetere 简介 jmeter 是 apache 公司基于 java 开发的一款开源压力测试工具,体积小,功能全,使用方便,是一个比较轻量级的测试工具,使用起来非常简 单。 jmeter 是免安装的,拿到安装包之后直接解压就可以使用,同时它在 linux/windows/macos 上都可以使用。 前提 已安装和…

微软开源!Office 文档轻松转 Markdown!

MarkItDown —— 微软开源的 Python 工具,能够将多种常见的文件格式(如 PDF、PowerPoint、Word、Excel、图像、音频和 HTML 等)转换为 Markdown 格式。大家好,我是 Java陈序员。 今天,给大家介绍一款微软开源的文档转 Markdown 工具。关注微信公众号:【Java陈序员】,获取…

人工智能(AI)在医学领域的应用 -九五小庞

人工智能(AI)在医学领域的应用是当前科技发展的重要方向之一,它通过提高医疗效率、准确性和个性化治疗水平,极大地改善了医疗服务的质量和患者的体验。以下是一些AI在医学领域的主要应用:辅助诊断医学影像分析:AI可以通过深度学习算法快速准确地分析CT、MRI、X光等医学影…

Ftrans汽车制造供应链管理方案,如何实现协同共赢?

汽车制造供应链管理是指对从供应商到客户的汽车产品、信息及资金流动进行集成管理的过程,旨在最大化供应链价值。在汽车制造供应链管理中,信息流扮演着至关重要的角色。它不仅是供应链各环节之间沟通协作的桥梁,也是确保供应链高效运作、降低库存成本、提升客户满意度的重要…

升级后手机版网站无法访问,可能的原因及解决方案

!在进行服务器或应用程序升级后,如果发现手机版网站无法访问,这通常是由于升级过程中某些配置发生了变化,导致移动端设备无法正确解析或加载网页内容。为了帮助您更好地理解和解决这个问题,以下是几个可能的原因及相应的解决方案:检查域名解析设置升级后,域名解析设置可…

如何解决批量主机升级未成功的问题?

如果您尝试对多个主机进行批量升级,但部分主机未能成功升级,可能是由多种原因引起的。以下是详细的排查步骤和解决方案:检查财务记录:首先,确保所有主机的升级订单已经成功支付。您可以登录到云服务提供商的控制面板,查看财务记录,确认每个主机的升级订单状态。如果存在…