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…...
高级渗透测试:KitHack多平台后门生成与持久化技术
高级渗透测试:KitHack多平台后门生成与持久化技术 【免费下载链接】KitHack Hacking tools pack & backdoors generator. 项目地址: https://gitcode.com/gh_mirrors/ki/KitHack KitHack是一款功能强大的渗透测试工具包,专为安全研究人员和渗…...
PX4 Firmware V1.14.4 开源支持
PX4 官方固件版本迭代迅猛,这往往导致开发者在硬件兼容性、环境搭建及软件依赖性上遭遇重重挑战。为彻底解决这一问题,Kerloud 推出固件与文档长期支持(LTS)计划。我们将对飞控固件代码、技术文档及参数调优指南实施持续性维护&am…...
精读双模态检测论文二十六|DefDeN(兰州大学)创新点拉满!门控融合+可变形去噪+对比学习,LiDAR-Camera 3D检测暴力涨点!!!
🔥 本文定位:CSDN 原创干货 | 兰州大学/卧龙岗大学 LiDAR-Camera 3D目标检测 SOTA 方案 🎯 核心收益:一次性解决注意力融合三大痛点——收敛慢、计算量大、误检率高!基于门控多模态融合单元(GMFU࿰…...
国内主流AI开发框架横向性能评测
一、引言:从“能用”到“好用”的框架选型挑战随着大模型与生成式AI从实验室走向产业落地,AI开发框架的选择已从单纯的“能否跑通模型”演变为一套复杂的多维度权衡。开发者普遍面临以下痛点:框架与模型的兼容性、训练与推理的端到端效率、…...
Letta框架:全栈AI应用开发,从模型集成到部署上线的完整解决方案
1. 项目概述:一个开箱即用的AI应用开发框架最近在折腾AI应用开发的朋友,估计都绕不开一个核心痛点:想法很美好,落地很骨感。从模型调用、提示词工程,到前后端集成、状态管理,再到部署上线,每个环…...
示波器有效位数(ENOB)实战指南:从原理到选型与应用
1. 从“看见”到“看清”:示波器有效位数(ENOB)的实战解读在电子工程师的日常里,示波器就是我们观察电路世界的“眼睛”。它能让我们直观地看到信号在连接器、线缆、PCB走线和元器件之间穿梭的模样。但就像视力有1.0和1.5的区别一…...
白炽灯非线性电阻特性在电路保护与调试中的经典应用
1. 项目概述:当白炽灯不再照明作为一名在电子工程领域摸爬滚打了十几年的老工程师,我手边的“破烂”工具箱里,除了常规的电阻、电容、芯片,还常年备着几样“非主流”玩意儿:几个不同瓦数的白炽灯泡。在很多人看来&…...
GitHub Actions 工作流中的输出处理
在现代软件开发中,CI/CD(持续集成和持续交付)是确保代码质量和自动化部署的关键环节。GitHub Actions 作为 GitHub 提供的 CI/CD 工具,支持通过工作流文件定义自动化任务。本文将结合一个实际的 GitHub Actions 工作流实例,探讨如何处理 Python 脚本的输出,并根据该输出决…...
ARM CP15寄存器详解与底层开发实践
1. ARM CP15寄存器概述CP15是ARM架构中的系统控制协处理器,负责管理处理器核心的关键功能模块。作为嵌入式系统开发人员,理解CP15寄存器的工作原理和操作方法,是进行底层系统软件开发的基础。CP15寄存器通过协处理器指令MRC(读)和MCR(写)进行…...
【C++ -Day7】封装实战 | 用类封装日志、配置和文件操作模块
引言 封装是面向对象三大特性(封装、继承、多态)中最基础也最重要的一环。在嵌入式开发中,代码的安全性、可维护性和可复用性直接决定了项目的成败。通过封装,我们可以将数据和操作隐藏在类内部,只暴露简洁的接口&…...
