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 coordinate
    XTranslateCoordinates(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 manager
    Atom 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, bottom
      long* 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 needed
      XFixesCursorImage* cursor = XFixesGetCursorImage(QX11Info::display());
      if(cursor) {
        if(cursor->pixels) {  // pixles should be an ARGB array
          QImage 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 image
          QPainter 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 window
  if(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 later
  QImage 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 + pid
  const 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 file
  for(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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DC-3靶场

DC-3 DC-3靶场链接&#xff1a;https://download.vulnhub.com/dc/DC-3-2.zip 下载后解压会有一个DC-3.ova文件&#xff0c;直接在vm虚拟机点击左上角打开-->文件--.选中这个.ova文件就能创建靶场&#xff0c;kali和靶机都调整至NAT模式 首先进行主机发现&#xff1a; arp…

Appium自动化常用adb操作封装

一、前置说明 在Appium自动化中&#xff0c;经常需要使用adb命令与设备进行交互&#xff0c;所以有必要把常用的adb操作封装成一个类 二、代码实现 import os import platform import re import subprocessfrom common import path from common.exception import AndroidSDK…

sysdig源码分析

Falco 0.6.0 Released New Features | Sysdig 在0.6.0之前&#xff0c;falco使用来自sysdig的内核模块sysdig-probe。从0.6.0开始&#xff0c;falco使用自己的内核模块falco-probe。内核模块实际上是由相同的源代码构建的&#xff0c;但是拥有一个特定于falco的内核模块允许fa…

电子科大陈瑞杰:开源不是那么的遥不可及

个人介绍 大家好&#xff0c;我是来自西安电子科技大学计算机学院软件工程专业的陈瑞杰&#xff0c;本科就读中北大学&#xff0c;本科通过校赛加入ACM校队&#xff0c;参与ACM-ICPC、CCPC等算法比赛&#xff0c;获区域赛铜奖(CCPC铜首&#xff0c;差点银&#xff0c;比较可惜…

【论文阅读】LoRA: Low-Rank Adaptation of Large Language Models

code&#xff1a;GitHub - microsoft/LoRA: Code for loralib, an implementation of "LoRA: Low-Rank Adaptation of Large Language Models" 做法&#xff1a; 把预训练LLMs里面的参数权重给冻结&#xff1b;向transformer架构中的每一层&#xff0c;注入可训练的…

IDEA中显示方法、类注释信息

目录 一、IDEA测试版本及环境二、操作步骤2.1 鼠标悬停在某一个方法上&#xff0c;从而显示方法的注释信息2.2 调用方法时同步显示方法注释信息2.3 在new一个对象时&#xff0c;这个对象有很多重载的构造方法&#xff0c;想要重载的构造函数都显示出来 一、IDEA测试版本及环境 …

2019年第八届数学建模国际赛小美赛B题数据中心冷出风口的设计解题全过程文档及程序

2019年第八届数学建模国际赛小美赛 B题 数据中心冷出风口的设计 原题再现&#xff1a; 这是数据中心空调设计面临的一个问题。在一些数据中心&#xff0c;计算机机柜是开放的&#xff0c;在一个房间里排列成三到四排。冷却后的空气通过主管进入房间&#xff0c;并分为三到四个…

聚观早报 |iOS17.3引入设备被盗保护;iPhone16或调整设计

【聚观365】12月14日消息 iOS17.3引入设备被盗保护 iPhone16或调整设计 马斯克星链网络使用量飙升 华为鸿蒙智行App正式上线 特斯拉人形机器人Optimus二代上线 iOS17.3引入设备被盗保护 苹果向iPhone用户推送了iOS17.3开发者预览版Beta更新&#xff0c;本次更新距离上次发…

【贝叶斯分析】计算机科学专业博士作业二

1 第一题 1.1 题目 已知变量A和B的取值只能为0或1&#xff0c;A⫫&#x1d469;&#xff0c;且&#x1d45d;(&#x1d434;1)0.65&#xff0c;&#x1d45d;(&#x1d435;1)0.77。C的取值与A和B有关&#xff0c;具体关系如下图所表&#xff1a; ABP(C1|A,B)000.1010.99100…

Android其他组件(单选框)

一、单选框&#xff08;RadioGroup&#xff09; 单选框&#xff08;RadioGroup&#xff09;需要配合单选按钮&#xff08;RadioButton&#xff09;使用&#xff0c;同一个单选框中的单选按钮只能被选中一个&#xff0c;默认是一个都不选中。 RadioGroup的常见属性&#xff08…

[Linformer]论文实现:Linformer: Self-Attention with Linear Complexity

文章目录 一、完整代码二、论文解读2.1 介绍2.2 Self-Attention is Low Rank2.3 模型架构2.4 结果 三、整体总结 论文&#xff1a;Linformer: Self-Attention with Linear Complexity 作者&#xff1a;Sinong Wang, Belinda Z. Li, Madian Khabsa, Han Fang, Hao Ma 时间&#…

修复录制异常终止导致的 MP4 文件损坏(moov atom not found)

如果录制视频时异常退出&#xff08;蓝屏死机、程序崩溃等&#xff09;&#xff0c;会导致录制的 MP4 文件损坏无法打开。 在这里简单记录一下解决方法。 1 首先尝试用 ffmpeg。运行 ffmpeg -i <损坏文件> -c copy <输出路径>看看能不能正常运行。 如果不能&am…

【Linux】信号--信号初识/信号的产生方式/信号的保存

文章目录 一、信号初步理解1.生活角度的信号2.技术应用角度的信号 二、信号的产生方式1.通过终端按键产生信号2.调用系统函数向进程发信号3.硬件异常产生信号4.由软件条件产生信号5.进程退出时的核心转储问题 三、信号的保存1.信号其他相关常见概念2.信号在内核中的表示3.sigse…

vue实现滑动验证

效果图&#xff1a; 源码地址&#xff1a;github文档地址&#xff1a; https://github.com/monoplasty/vue-monoplasty-slide-verify 使用步骤&#xff1a;1&#xff0c;安装插件&#xff1a; npm install --save vue-monoplasty-slide-verify 在main.js中使用一下&#xff…

HTML---初识CSS

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.CSS概念 CSS是层叠样式表&#xff08;Cascading Style Sheets&#xff09;的缩写。它是一种用于描述HTML文档外观样式的标记语言。通过CSS&#xff0c;开发者可以在不改变HTML标记结构的情况…

尚硅谷Docker笔记-高级篇

1.Docker复杂安装 1.1安装mysql主从复制搭建步骤 1.新建主服务器容器实例3307 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql-master/log:/var/log/mysql \ -v /mydata/mysql-master/data:/var/lib/mysql \ -v /mydata/mysql-master/conf:/etc/mysql \ -…

运筹学经典问题(六):设施选址问题

问题描述 设施选址问题&#xff08;Facility Location Problem, FLP&#xff09;也成选址-分配问题&#xff0c;是企业面临的一类重要问题&#xff1a;在哪里建造设施&#xff1f;建造多少&#xff1f;以及将哪些客户分配给哪些设施去服务&#xff1f; 以物流业的航空站点选…

华为云sp2服务器系统根分区扩容后重启失败解决

lvm根分区扩容 概念&#xff1a; PV&#xff08;物理卷&#xff1a;Physical Volumes&#xff09; VG&#xff08;物理卷组&#xff1a;Volume Group&#xff09; LV&#xff08;逻辑卷&#xff1a;Logical Volumes&#xff09; R系 V10服务器&#xff1a; 显示当前Logic…

实验5:NAT配置

1.实验目的&#xff1a; 了解NAT的基本概念和功能 掌握NAT的配置方法和命令 观察和分析NAT的工作原理和流程 2.实验内容&#xff1a; 在路由器上配置静态NAT&#xff0c;实现内网主机通过公网IP地址访问外网服务器在路由器上配置动态NAT&#xff0c;实现内网主机通过公网I…

华为配置本地端口镜像示例(1:1)

图1 配置本地端口镜像组网图 组网需求 如图1所示&#xff0c;某公司行政部通过Switch与外部Internet通信&#xff0c;监控设备Server与Switch直连。 现在希望通过Server对行政部访问Internet的流量进行监控 配置思路 在Switch进行如下配置&#xff0c;实现Server对所有行政…