wxWidgets-ImageView
wxWidgets实现图片浏览、放大缩小、另存为新的图片格式等

#include "wx/wxprec.h"#ifndef WX_PRECOMP#include "wx/wx.h"
#endif#include "wx/filename.h"
#include "wx/zstream.h"#include "imageviewctrl.h"class MyFrame : public wxFrame
{
public:MyFrame(wxWindow* parent,wxWindowID id,const wxString& title,const wxPoint& pos = wxDefaultPosition,const wxSize& size = wxDefaultSize,long style = wxDEFAULT_FRAME_STYLE | wxSUNKEN_BORDER,ImageViewCtrl* imageview = NULL);
private:wxString LoadUserImage(wxImage& image){wxString filename;#if wxUSE_FILEDLGfilename = wxLoadFileSelector("image", wxEmptyString);if (!filename.empty()){if (!image.LoadFile(filename)){wxLogError("Couldn't load image from '%s'.", filename);return wxEmptyString;}}
#endif // wxUSE_FILEDLGreturn filename;}void OnOpen(wxCommandEvent& WXUNUSED(event)){wxImage image;wxString filename = LoadUserImage(image);if (!filename.empty()){this->image_view_ctrl_->SetBitmap(wxBitmap(image));}this->Refresh();}void OnQuit(wxCommandEvent& WXUNUSED(event)){Close(true);}void OnAbout(wxCommandEvent& WXUNUSED(event)){wxArrayString array;array.Add("ImageView demo");array.Add(wxT("交流QQ群:747166657"));array.Add(wxT("QQ:1083969551"));array.Add(wxT("Email:nonday@foxmail.com"));array.Add(wxEmptyString);array.Add("Version of the libraries used:");#if wxUSE_LIBPNGarray.Add(wxPNGHandler::GetLibraryVersionInfo().ToString());
#endif
#if wxUSE_LIBJPEGarray.Add(wxJPEGHandler::GetLibraryVersionInfo().ToString());
#endif
#if wxUSE_LIBTIFFarray.Add(wxTIFFHandler::GetLibraryVersionInfo().ToString());
#endif
#if wxUSE_ZLIB && wxUSE_STREAMS// zlib is used by libpngarray.Add(wxGetZlibVersionInfo().ToString());
#endif(void)wxMessageBox(wxJoin(array, '\n'),"About ImageView Demo",wxICON_INFORMATION | wxOK);}void OnSave(wxCommandEvent& WXUNUSED(event)){
#if wxUSE_FILEDLGconst wxBitmap& bitmap = this->image_view_ctrl_->GetBitmap();wxImage image = bitmap.ConvertToImage();wxString savefilename = wxFileSelector( "Save Image",wxEmptyString,wxEmptyString,wxEmptyString,"BMP files (*.bmp)|*.bmp|"
#if wxUSE_LIBPNG"PNG files (*.png)|*.png|"
#endif
#if wxUSE_LIBJPEG"JPEG files (*.jpg)|*.jpg|"
#endif
#if wxUSE_GIF"GIF files (*.gif)|*.gif|"
#endif
#if wxUSE_LIBTIFF"TIFF files (*.tif)|*.tif|"
#endif
#if wxUSE_PCX"PCX files (*.pcx)|*.pcx|"
#endif
#if wxUSE_XPM"X PixMap files (*.xpm)|*.xpm|"
#endif"ICO files (*.ico)|*.ico|""CUR files (*.cur)|*.cur",wxFD_SAVE | wxFD_OVERWRITE_PROMPT,this);if ( savefilename.empty() )return;wxString extension;wxFileName::SplitPath(savefilename, NULL, NULL, &extension);bool saved = false;if ( extension == "bmp" ){static const int bppvalues[] ={wxBMP_1BPP,wxBMP_1BPP_BW,wxBMP_4BPP,wxBMP_8BPP,wxBMP_8BPP_GREY,wxBMP_8BPP_RED,
#if wxUSE_PALETTEwxBMP_8BPP_PALETTE,
#endif // wxUSE_PALETTEwxBMP_24BPP};const wxString bppchoices[] ={"1 bpp color","1 bpp B&W","4 bpp color","8 bpp color","8 bpp greyscale","8 bpp red",
#if wxUSE_PALETTE"8 bpp own palette",
#endif // wxUSE_PALETTE"24 bpp"};int bppselection = wxGetSingleChoiceIndex("Set BMP BPP","Image sample: save file",WXSIZEOF(bppchoices),bppchoices,this);if ( bppselection != -1 ){int format = bppvalues[bppselection];image.SetOption(wxIMAGE_OPTION_BMP_FORMAT, format);
#if wxUSE_PALETTEif ( format == wxBMP_8BPP_PALETTE ){unsigned char *cmap = new unsigned char [256];for ( int i = 0; i < 256; i++ )cmap[i] = (unsigned char)i;image.SetPalette(wxPalette(256, cmap, cmap, cmap));delete[] cmap;}
#endif // wxUSE_PALETTE}}
#if wxUSE_LIBPNGelse if ( extension == "png" ){static const int pngvalues[] ={wxPNG_TYPE_COLOUR,wxPNG_TYPE_COLOUR,wxPNG_TYPE_GREY,wxPNG_TYPE_GREY,wxPNG_TYPE_GREY_RED,wxPNG_TYPE_GREY_RED,};const wxString pngchoices[] ={"Colour 8bpp","Colour 16bpp","Grey 8bpp","Grey 16bpp","Grey red 8bpp","Grey red 16bpp",};int sel = wxGetSingleChoiceIndex("Set PNG format","Image sample: save file",WXSIZEOF(pngchoices),pngchoices,this);if ( sel != -1 ){image.SetOption(wxIMAGE_OPTION_PNG_FORMAT, pngvalues[sel]);image.SetOption(wxIMAGE_OPTION_PNG_BITDEPTH, sel % 2 ? 16 : 8);// these values are taken from OptiPNG with -o3 switchconst wxString compressionChoices[] ={"compression = 9, memory = 8, strategy = 0, filter = 0","compression = 9, memory = 9, strategy = 0, filter = 0","compression = 9, memory = 8, strategy = 1, filter = 0","compression = 9, memory = 9, strategy = 1, filter = 0","compression = 1, memory = 8, strategy = 2, filter = 0","compression = 1, memory = 9, strategy = 2, filter = 0","compression = 9, memory = 8, strategy = 0, filter = 5","compression = 9, memory = 9, strategy = 0, filter = 5","compression = 9, memory = 8, strategy = 1, filter = 5","compression = 9, memory = 9, strategy = 1, filter = 5","compression = 1, memory = 8, strategy = 2, filter = 5","compression = 1, memory = 9, strategy = 2, filter = 5",};sel = wxGetSingleChoiceIndex("Select compression option (Cancel to use default)\n","PNG Compression Options",WXSIZEOF(compressionChoices),compressionChoices,this);if ( sel != -1 ){const int zc[] = {9, 9, 9, 9, 1, 1, 9, 9, 9, 9, 1, 1};const int zm[] = {8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9};const int zs[] = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2};const int f[] = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08,0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8};image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_LEVEL , zc[sel]);image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_MEM_LEVEL , zm[sel]);image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_STRATEGY , zs[sel]);image.SetOption(wxIMAGE_OPTION_PNG_FILTER , f[sel]);image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_BUFFER_SIZE, 1048576); // 1 MB}}}
#endif // wxUSE_LIBPNGelse if ( extension == "cur" ){image.Rescale(32,32);image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X, 0);image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, 0);// This shows how you can save an image with explicitly// specified image format:saved = image.SaveFile(savefilename, wxBITMAP_TYPE_CUR);}if ( !saved ){// This one guesses image format from filename extension// (it may fail if the extension is not recognized):image.SaveFile(savefilename);}
#endif // wxUSE_FILEDLG}void OnSize(wxSizeEvent& event){//event.GetSize();wxLogDebug("MyFrame OnSize");wxSize size = this->GetClientSize();wxLogDebug("MyFrame.w=%d, MyFrame.h=%d", size.x, size.y);wxLogStatus(this, "Size size: (%d, %d), ClientSize size: (%d, %d)",GetSize().x,GetSize().y,size.x,size.y);if (image_view_ctrl_){image_view_ctrl_->SetSize(10, 10, size.x-20, size.y-20);}event.Skip();}ImageViewCtrl* image_view_ctrl_;// = NULL;wxDECLARE_EVENT_TABLE();
};// ============================================================================
// implementations
// ============================================================================//-----------------------------------------------------------------------------
// MyFrame
//-----------------------------------------------------------------------------wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
EVT_MENU(wxID_SAVEAS, MyFrame::OnSave)
EVT_SIZE(MyFrame::OnSize)
wxEND_EVENT_TABLE()MyFrame::MyFrame(wxWindow* parent,wxWindowID id,const wxString& title,const wxPoint& pos,const wxSize& size,long style,ImageViewCtrl* imageview): wxFrame(parent, id, title, pos, size, style | wxFULL_REPAINT_ON_RESIZE), image_view_ctrl_(imageview)
{wxMenu* fileMenu = new wxMenu;fileMenu->Append(wxID_OPEN);fileMenu->Append(wxID_EXIT);fileMenu->Append(wxID_SAVEAS);wxMenu* helpMenu = new wxMenu;helpMenu->Append(wxID_ABOUT, "&About\tCtrl-O");wxMenuBar* menuBar = new wxMenuBar;menuBar->Append(fileMenu, "&File");menuBar->Append(helpMenu, "&Help");SetMenuBar(menuBar);CreateStatusBar(1);SetMinSize(wxSize(640, 480));this->SetBackgroundColour(*wxRED);wxPanel * panel = new wxPanel(this, wxID_ANY, wxPoint(0,0), GetClientSize());image_view_ctrl_ = new ImageViewCtrl(panel, wxID_ANY, wxDefaultPosition, GetClientSize());}//-----------------------------------------------------------------------------
// MyApp
//-----------------------------------------------------------------------------
// declare
class MyApp: public wxApp
{
public:virtual bool OnInit() wxOVERRIDE;
};// implement
wxIMPLEMENT_APP(MyApp);bool MyApp::OnInit()
{if ( !wxApp::OnInit() )return false;wxInitAllImageHandlers();wxFrame *frame = new MyFrame(NULL, wxID_ANY, "ImageView Demo", wxDefaultPosition, wxWindow::FromDIP(wxSize(900, 600), NULL), wxDEFAULT_FRAME_STYLE | wxSIMPLE_BORDER);frame->Show();return true;
}
相关文章:
wxWidgets-ImageView
wxWidgets实现图片浏览、放大缩小、另存为新的图片格式等 #include "wx/wxprec.h"#ifndef WX_PRECOMP#include "wx/wx.h" #endif#include "wx/filename.h" #include "wx/zstream.h"#include "imageviewctrl.h"class MyFrame…...
第1章-JVM和Java体系架构
虚拟机 虚拟机概念 所谓虚拟机(Virtual Machine),就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。 大名鼎鼎的Virtual Box,VMware就属…...
windows 服务器角色
windows 服务器角色 Active Directory Rights Management Services Active Directory RightsManagement Services (AD RS)帮助保护信息,防止未授权使用。AD RMS 将建立用户标识,并为授权用户提供受保护信息的许可证。 ServicesActive Directory 联合身…...
[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式
T. 已测试目录 主机类型主机版本Docker镜像版本结果WSL2Ubuntu22.04Ubuntu20.04PASSWSL2Ubuntu22.04Ubuntu18.04PASS R. 软硬件要求: 编译硬件需求:做多系统测试,磁盘500GB起步(固态)(机械会卡死),内存3…...
C#中判断两个 List<T> 的内容是否相等
ET实现游戏中邮件系统逻辑思路(服务端)_游戏邮件系统设计-CSDN博客 场景:今天遇到一个BUG,在服务器重启的时候(体验服),玩家之前接收的邮件又重新接收了一次,但是两封邮件的ID是不同…...
Linux环境下配置neo4j图数据库
1.下载安装包 openjdk-11.0.1_linux-x64_bin.tar.gz neo4j-community-4.2.19-unix.tar.gz 2.之前配置好的配置文件 neo4j.conf 3.安装 3.1-jdk11的安装(jdk1.8不够用) 解压缩 tar -zxvf openjdk-11.0.1_linux-x64_bin.tar.gz修改系统环境变量 打开pro…...
Windows 11 搭建 Docker 桌面版详细教程
在当今的软件开发与部署领域,Docker 已成为一项极为重要的容器化技术。它能够让开发者轻松地打包应用及其依赖项,实现跨环境的一致性运行,大大提高了开发效率与部署的便捷性。本教程将详细介绍在 Windows 11 操作系统上搭建 Docker 桌面版的具…...
Pytest-Bdd-Playwright 系列教程(13):钩子(hooks)
Pytest-Bdd-Playwright 系列教程(13):钩子(hooks) 前言一、什么是钩子?二、Pytest-Bdd 提供的钩子一览三、钩子用法详解1. pytest_bdd_before_scenario2. pytest_bdd_after_scenario3. pytest_bdd_before_s…...
dns 服务器简单介绍
dns 服务器分类: 根域名服务器顶级域名服务器权威域名服务器本地域名服务器 dns 的查询过程 国内优秀公共域名 腾讯:DNSPod-免费智能DNS解析服务商-电信_网通_教育网,智能DNS-烟台帝思普网络科技有限公司 119.29.29.29 和 182.254.118.118 阿里…...
Neo4j图形数据库-Cypher中常用指令
一、创建与修改 1.1 create 创建图数据库中的节点、关系等元素: CREATE (:Person {name: "Alice", age: 30}) CREATE (p1:Person {name: "Bob"})-[r:KNOWS]->(p2:Person {name: "Charlie"})批量创建元素 CREATE (n1:Node),(n2…...
linux安全管理-防火墙配置
1. 开启系统防火墙 1、检查内容 检查操作系统是否开启防火墙; 2、配置要求 操作系统开启防火墙; 3、配置方法 systemctl status firewalld ##查看系统防火墙运行状态 systemctl start firewalld ##启动防火墙 systemctl restart firewalld ##重启防火墙…...
什么是BIOS
BIOS(Basic Input/Output System,基本输入输出系统)是计算机启动过程中的一个关键组件,主要负责硬件的初始化和系统的引导。以下是关于 BIOS 的一些详细信息: 1. 基本功能 硬件初始化:当计算机启动时&…...
c++视频图像处理
打开视频或摄像头 打开指定视频 /*VideoCapture(const String &filename, apiPreference);filename:读取的视频或者图像序列的名称apiPreference:读取数据时设置的属性*/ VideoCapture video; //定义一个空的视频对象 video.open("H:/BaiduNetdiskDownlo…...
音视频入门基础:MPEG2-TS专题(8)——TS Header中的适配域
注:本文有部分内容引用了维基百科:https://zh.wikipedia.org/wiki/MPEG2-TS 一、引言 当TS Header中的adaptation_field_control属性的值为10或11 时,TS Header包含adaptation field(适配域): 根据《T-RE…...
基于stm32单片机的教室节能系统设计
功能描述 0. STM32F103C8T6单片机为控制核心 1. OLED液晶显示当前年 月 日 时 分 秒 星期 2. 按键可以设置定时时间 3. 按键可以设置用电开关的开启和关闭时间,实现设备的节能 4. 通过红外遥控可以打开关闭空调设备(通过继电器开关闭合模拟&#x…...
mini主机通过内网穿透做成服务器
文章目录 简介1.ubuntu 的ssh server 安装2.ubuntu 的docker 安装3.ubuntu的curl的安装4.ubuntu的frp客户端安装5.ubuntu的docker compose安装6.声明 简介 主要目的 本地设备做成服务器,实现ssh远程登录以及内网穿透设备总成本1千多元(其实部分设备可以…...
智能桥梁安全运行监测系统守护桥梁安全卫士
一、方案背景 桥梁作为交通基础设施中不可或缺的重要组成部分,其安全稳定的运行直接关联到广大人民群众的生命财产安全以及整个社会的稳定与和谐。桥梁不仅是连接两地的通道,更是经济发展和社会进步的重要纽带。为了确保桥梁的安全运行,桥梁安…...
Selenium和Pyppeteer有什么区别?
Selenium和Pyppeteer都是自动化测试工具,它们可以模拟用户在浏览器中的操作,但它们之间存在一些关键的区别: Selenium 跨浏览器支持:Selenium支持多种浏览器,包括Chrome、Firefox、Internet Explorer等,而…...
82从零开始学Java之异常处理机制简介
作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 大家可以想一个问题,有没有谁能够做到开发项目时一个错误都不发生?如果谁能够做到这一点,那他可能真的是“天才”!但实际上,任何人都不可能在项目开发…...
Git上传本地项目到远程仓库(gitee/github)
目录 序言一、创建git本地版本库二、连接远程仓库(以gitee为例)三、将项目提交到git(本地)版本库1.由工作区添加到暂存区2.由暂存区添加到版本库 四、将代码由本地仓库上传到 gitee远程仓库1.获取远程库与本地同步2.把当前分支 ma…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
