QT- QT-lximagerEidtor图片编辑器
QT- QT-lximagerEidtor图片编辑器
- 一、演示效果
- 二、关键程序
- 三、下载链接
功能如下:
1、缩放、旋转、翻转和调整图像大小
2、幻灯片
3、缩略图栏(左、上或下);不同的缩略图大小
4、Exif数据栏
5、内联图像重命名
6、自定义快捷方式
7、图像注释(箭头、矩形、圆形、数字)
8、最近的文件
9、上传图片(Imgur)
10、截屏
一、演示效果
二、关键程序
using namespace LxImage;static bool hasXFixes() {int event_base, error_base;return XFixesQueryExtension(QX11Info::display(), &event_base, &error_base);
}ScreenshotDialog::ScreenshotDialog(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f), hasXfixes_(hasXFixes()) {ui.setupUi(this);Application* app = static_cast<Application*>(qApp);app->addWindow();if(!hasXfixes_) {ui.includeCursor->hide();}
}ScreenshotDialog::~ScreenshotDialog() {Application* app = static_cast<Application*>(qApp);app->removeWindow();
}void ScreenshotDialog::done(int r) {if(r == QDialog::Accepted) {hide();QDialog::done(r);XSync(QX11Info::display(), 0); // is this useful?int delay = ui.delay->value();if(delay == 0) {// NOTE:// Well, we need to give X and the window manager some time to// really hide our own dialog from the screen.// Nobody knows how long it will take, and there is no reliable// way to ensure that. Let's wait for 400 ms here for it.delay = 400;}else {delay *= 1000;}// the dialog object will be deleted in doScreenshot().QTimer::singleShot(delay, this, SLOT(doScreenshot()));}else {deleteLater();}
}QRect ScreenshotDialog::windowFrame(WId wid) {QRect result;XWindowAttributes wa;if(XGetWindowAttributes(QX11Info::display(), wid, &wa)) {Window child;int x, y;// translate to root coordinateXTranslateCoordinates(QX11Info::display(), wid, wa.root, 0, 0, &x, &y, &child);//qDebug("%d, %d, %d, %d", x, y, wa.width, wa.height);result.setRect(x, y, wa.width, wa.height);// get the frame widths added by the window managerAtom atom = XInternAtom(QX11Info::display(), "_NET_FRAME_EXTENTS", false);unsigned long type, resultLen, rest;int format;unsigned char* data = nullptr;if(XGetWindowProperty(QX11Info::display(), wid, atom, 0, G_MAXLONG, false,XA_CARDINAL, &type, &format, &resultLen, &rest, &data) == Success) {}if(data) { // left, right, top, bottomlong* offsets = reinterpret_cast<long*>(data);result.setLeft(result.left() - offsets[0]);result.setRight(result.right() + offsets[1]);result.setTop(result.top() - offsets[2]);result.setBottom(result.bottom() + offsets[3]);XFree(data);}}return result;
}WId ScreenshotDialog::activeWindowId() {WId root = WId(QX11Info::appRootWindow());Atom atom = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", false);unsigned long type, resultLen, rest;int format;WId result = 0;unsigned char* data = nullptr;if(XGetWindowProperty(QX11Info::display(), root, atom, 0, 1, false,XA_WINDOW, &type, &format, &resultLen, &rest, &data) == Success) {result = *reinterpret_cast<long*>(data);XFree(data);}return result;
}QImage ScreenshotDialog::takeScreenshot(const WId& wid, const QRect& rect, bool takeCursor) {QImage image;QScreen *screen = QGuiApplication::primaryScreen();if(screen) {QPixmap pixmap = screen->grabWindow(wid, rect.x(), rect.y(), rect.width(), rect.height());image = pixmap.toImage();//call to hasXFixes() maybe executed here from cmd line with no gui mode (some day though, currently ignore cursor)if(takeCursor && hasXFixes()) {// capture the cursor if neededXFixesCursorImage* cursor = XFixesGetCursorImage(QX11Info::display());if(cursor) {if(cursor->pixels) { // pixles should be an ARGB arrayQImage cursorImage;if(sizeof(long) == 4) {// FIXME: will we encounter byte-order problems here?cursorImage = QImage((uchar*)cursor->pixels, cursor->width, cursor->height, QImage::Format_ARGB32);}else { // XFixes returns long integers which is not 32 bit on 64 bit systems.long len = cursor->width * cursor->height;quint32* buf = new quint32[len];for(long i = 0; i < len; ++i) {buf[i] = (quint32)cursor->pixels[i];}cursorImage = QImage((uchar*)buf, cursor->width, cursor->height, QImage::Format_ARGB32, [](void* b) {delete[](quint32*)b;}, buf);}// paint the cursor on the current imageQPainter painter(&image);painter.drawImage(cursor->x - cursor->xhot, cursor->y - cursor->yhot, cursorImage);}XFree(cursor);}}}return image;
}void ScreenshotDialog::doScreenshot() {WId wid = 0;QRect rect{0, 0, -1, -1};wid = QApplication::desktop()->winId(); // get desktop windowif(ui.currentWindow->isChecked()) {WId activeWid = activeWindowId();if(activeWid) {if(ui.includeFrame->isChecked()) {rect = windowFrame(activeWid);}else {wid = activeWid;}}}//using stored hasXfixes_ so avoid extra call to function laterQImage image{takeScreenshot(wid, rect, hasXfixes_ && ui.includeCursor->isChecked())};if(ui.screenArea->isChecked() && !image.isNull()) {ScreenshotSelectArea selectArea(image);if(QDialog::Accepted == selectArea.exec()) {image = image.copy(selectArea.selectedArea());}}Application* app = static_cast<Application*>(qApp);MainWindow* window = app->createWindow();window->resize(app->settings().windowWidth(), app->settings().windowHeight());if(!image.isNull()) {window->pasteImage(image);}window->show();deleteLater(); // destroy ourself
}static QString buildNumericFnPart() {//we may have many copies running with no gui, for example user presses hot keys fast//so they must have different file names to save, lets do it time + pidconst auto now = QDateTime::currentDateTime().toMSecsSinceEpoch();const auto pid = getpid();return QStringLiteral("%1_%2").arg(now).arg(pid);
}static QString getWindowName(WId wid) {QString result;if(wid) {static const char* atoms[] = {"WM_NAME","_NET_WM_NAME","STRING","UTF8_STRING",};const auto display = QX11Info::display();Atom a = None, type;for(const auto& c : atoms) {if(None != (a = XInternAtom(display, c, true))) {int form;unsigned long remain, len;unsigned char *list;errno = 0;if(XGetWindowProperty(display, wid, a, 0, 1024, False, XA_STRING,&type, &form, &len, &remain, &list) == Success) {if(list && *list) {std::string dump((const char*)list);std::stringstream ss;for(const auto& sym : dump) {if(std::isalnum(sym)) {ss.put(sym);}}result = QString::fromStdString(ss.str());break;}}}}}return (result.isEmpty()) ? QStringLiteral("UNKNOWN") : result;
}void ScreenshotDialog::cmdTopShotToDir(QString path) {WId activeWid = activeWindowId();const QRect rect = (activeWid) ? windowFrame(activeWid) : QRect{0, 0, -1, -1};QImage img{takeScreenshot(QApplication::desktop()->winId(), rect, false)};QDir d;d.mkpath(path);QFileInfo fi(path);if(!fi.exists() || !fi.isDir() || !fi.isWritable()) {path = QDir::homePath();}const QString filename = QStringLiteral("%1/%2_%3").arg(path).arg(getWindowName(activeWid)).arg(buildNumericFnPart());const auto static png = QStringLiteral(".png");QString finalName = filename % png;//most unlikelly this will happen ... but user might change system clock or so and we dont want to overwrite filefor(int counter = 0; QFile::exists(finalName) && counter < 5000; ++counter) {finalName = QStringLiteral("%1_%2%3").arg(filename).arg(counter).arg(png);}//std::cout << finalName.toStdString() << std::endl;img.save(finalName);
}
三、下载链接
https://download.csdn.net/download/u013083044/88628914
相关文章:

QT- QT-lximagerEidtor图片编辑器
QT- QT-lximagerEidtor图片编辑器 一、演示效果二、关键程序三、下载链接 功能如下: 1、缩放、旋转、翻转和调整图像大小 2、幻灯片 3、缩略图栏(左、上或下);不同的缩略图大小 4、Exif数据栏 5、内联图像重命名 6、自定义快捷方式…...
PyQt 如何通过连续点击托盘图标显示隐藏主窗口并且在主窗口隐藏时调整界面到托盘图标附近
不废话直接看代码 # -*- codingutf-8 -*- # # author: Ruben # mail: 773849069qq.com # time: 2023/12/8 # u""" 一个托盘图标的小部件 """ from Qt import QtWidgets, QtGui, QtCore# --*--*--*--*--*--*--*--*--*--…...

什么是纯净IP?如何判断IP地址的纯净度?有哪些干净IP推荐?
您是否想知道什么使代理“干净”或如何确保您的代理不会将您列入网站的黑名单?对于通过代理访问网络的人来说,干净的代理是无缝在线体验的重要组成部分。在这篇文章中,我们将深入研究干净代理的世界,并探讨决定其质量的因素。 一、…...
MySQL和Minio数据备份
文章目录 一、MySQL数据备份1. MySQL客户端2. 数据增量备份3. 数据增量还原4. 数据全量备份5. 数据全量还原 二、Minio数据备份1. Minio客户端2. 数据备份3. 数据还原 三、其他参考1. 设置定时备份2. 数据拷贝到其他服务器3. MySQL其他语句 一、MySQL数据备份 Linux环境&#…...
在Go中过滤范型集合:性能回顾
在一个真实的 Golang 场景中使用泛型,同时寻找与 Stream filter(Predicate<? super T> predicate)和 Python list comprehension 等同的函数。我没有依赖现有的包,而是选择自己写一个过滤函数,以达到学习的目的 func filterStrings(c…...

MATLAB 最小二乘直线拟合方法二 (36)
MATLAB 最小二乘直线拟合方法二 (36) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 这里介绍另一种拟合直线点云的方法,更为简单方便,结果与前者一致,主要内容直接复制代码使用即可,原理简单看代码即可,下面是具体的实现和拟合结果展示 二、算法实现 1.代码 代…...

Python 实现:OCR在图片中提取文字(基于Gradio实现)
Paddle OCR PaddleOCR 基于深度学习技术实现的,使用十分简单。 先看效果 可以看出来识别效果还是不错的,里面的“湿”字识别成了繁体字。如果不是连体字,就不会出现这个问题。 1.测试环境 操作系统:Win10 Python:3…...
idea插件开发报错: ZipException opening “slf4j.jar“: zip END header not found
错误信息 E:\idea-workspace\#idea-plugin\JSON2Object\src\main\java\com\hgy\plugin\json2object\GenerateAction.java:1: 错误: 无法访问com.hgy.plugin.json2object package com.hgy.plugin.json2object; ^ZipException opening "slf4j.jar": zip END header no…...

【Linux】多线程编程
目录 1. 线程基础知识 2. 线程创建 3. 线程ID(TID) 4. 线程终止 5. 线程取消 6. 线程等待 7. 线程分离 8. 线程互斥 8.1 初始化互斥量 8.2 销毁互斥量 8.3 互斥量加锁和解锁 9. 可重入和线程安全 10. 线程同步之条件变量 10.1 初始化条件变…...

【Mysql】InnoDB的表空间(九)
概述 表空间是一个在 InnoDB 中比较抽象的概念,对于系统表空间来说,对应着文件系统中一个或多个实际文件;而对于每个独立表空间来说,对应着文件系统中一个名为表名.ibd 的实际文件。可以把表空间想象成由很多个页组成的池子&…...
【09】ES6:Set 和 Map 数据结构
一、Set 1、基本语法 定义 Set 是一系列无序、没有重复值的数据集合。数组是一系列有序(下标索引)的数据集合。 Set 本身是一个构造函数,用来生成 Set 数据结构。 const s new Set() [2, 3, 5, 4, 5, 2, 2].forEach(x > s.add(x))fo…...
Java通过documents4j和libreoffice把word转为pdf
文章目录 word转pdf的相关第三方jar说明Linux系统安装LibreOffice在线安装离线安装word转pdf验证 Java工具类代码 word转pdf的相关第三方jar说明 docx4j 免费开源、稍微复杂点的word,样式完全乱了,且xalan升级为2.7.3后会报错。poi 免费开源、官方文档少…...

物联网时代的访问控制研究综述
A survey on Access Control in the Age of Internet of Things 文章目录 A B S T R A C T引言A. Comparison Between This Paper and Existing SurveysB. Contributions II.ACCESS CONTROL BACKGROUNDIII. ACCESS CONTROL CHALLENGES IN IOT SEARCHA. Characteristics of IoT …...

【产品经理】需求池和版本树
在这个人人都是产品经理的时代,每位入行的产品人进阶速度与到达高度各有不同。本文作者结合自身三年产品行业的经历,根据案例拆解产品行业的极简研发过程、需求池、版本树、产品自我优化等相关具体方法论。 一、产品研发的极简过程 1. 产品概述 产品就…...
Qt图像处理-OpenCv中Mat与QImage互转
Qt图像处理时需要OpenCv中Mat与QImage互转,具体代码如下 创建EditPhoto,头文件,使用前需要配置好opencv #include <QObject> #include <QImage> #include <QDebug>#include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> …...

构建外卖小程序:技术代码实践
在这个数字化的时代,外卖小程序已经成为餐饮业的一项重要工具。在本文中,我们将通过一些简单而实用的技术代码,向您展示如何构建一个基本的外卖小程序。我们将使用微信小程序平台作为例子,但这些原理同样适用于其他小程序平台。 …...

IDEA中显示方法、类注释信息
目录 一、IDEA测试版本及环境二、操作步骤2.1 鼠标悬停在某一个方法上,从而显示方法的注释信息2.2 调用方法时同步显示方法注释信息2.3 在new一个对象时,这个对象有很多重载的构造方法,想要重载的构造函数都显示出来 一、IDEA测试版本及环境 …...
《数据结构、算法与应用C++语言描述》- 堆排序 - 借助priority_queue的C++实现
堆排序 完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_27HeapSort 定义 借助堆进行排序。先用n个待排序的元素初始化一个小根堆,然后从堆中逐个提取(即删除元素)元素。初始化的时间复杂度为O(n),大根堆中每…...

10.CSS浮动
CSS浮动 1.介绍 在最初,浮动是用来实现文字环绕图片效果的,现在浮动是主流的页面布局方式之一 2.作用 让元素脱离标准流,同一级的浮动的元素可以并排在一排显示 3.元素浮动后的特点 脱离文档流不管浮动前是什么元素,浮动后&…...
Angular 2 学习笔记
Angular 2 应用主要由以下 几个部分组成: 1、模块 (Modules): 2、组件 (Components): 3、模板 (Templates): 4、元数据 (Metadata): 5、数据绑定 (Data Binding) 6、指令 (Directives) 7、服务 (Servic…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...