我的Qt作品(9)Qt使用Cairo绘图引擎提升抗锯齿效果【开源】

之前写了一篇文章《Qt使用GDI绘图(仅Windows平台)》

Qt使用GDI绘图(仅Windows平台)_libaineu2004的博客-CSDN博客

本篇重点介绍Cairo绘图引擎,Qt自带的QPainter的绘图效率和抗锯齿效果都没有cairo的好。cairo 的目标是以跨平台的方式在打印机和屏幕上产生相同的输出,它正在成为 Linux® 图形领域的重要软件。GNOME、GTK+、Pango 等许多软件已经使用了它提供的 2D 功能。另外,cairo 还支持生成 PostScript 或 PDF 输出,从而产生高质量的打印结果。在理想情况下,cairo 的用户可以在打印机和屏幕上获得非常接近的输出效果。

一、Cairo简介

Cairo:C编写的开源绘图引擎(基于LGPL协议),大名鼎鼎的FireFox就是用这个绘图引擎的。Cairo是非常流行的开源2D图形渲染引擎库,它支持包括X-Windos,Win32,图像,pdf在内的各种输出设备。目前,Cairo已被广泛的使用在多个平台上来渲染图形界面,包括Firefox/Webkit-EFL/GTK+/Poppler/Qt等等。Qt的QPainter提供的抗锯齿效果没有cairo的好。cairo是用C编写的,但是为大多数常用的语言提供了绑定。选用 C 语言有助于创建新的绑定,同时在进行C语言调用时可以提供高性能。应该特别注意Python绑定,它支持快速原型开发,而且降低了学习cairo绘图API的门槛。Cairo的绘图效率是接近GDI/GDIPlus的。经过优化算法,可以做到完全忽略绘图效率上的差别。此外,gtk不如qt流行,Qt支持cairo。

cairo 是一个矢量绘图(vector drawing)库,因此绘图需要对图形进行几何描述,而不是描述位图中填充的像素。在采用位图绘图(bitmap drawing)时,按照预先决定的布局用预先决定的颜色填充一系列像素,而且图形的质量与位图的大小成正比。 在放大或修改位图图像时,位图绘图方法的效果就会变差。图像常常会变得模糊,就像是近距离观看背投电视或其他大屏幕电视时的效果。在某一距离上,图像可能看起来很清楚,但是靠近之后就会看到许多离散的点。因为数据无法定义预先定义的像素之间应该是什么,所以放大时会很明显地损失清晰度。计算机绘图系统和体系结构很早就出现了,cairo 的设计借鉴了 PostScript 和 PDF 模型的许多经验。cairo 之所以借鉴 PostScript 和 Portable Document Format(PDF)方法是因为,它们都使用数学语句定义图像。由于用几何方法表示图像,所以可以在任何时候在一定范围内计算几何描述,从而重新创建整个图像(或一部分图像)。图形的几何性质被表示为点、曲线和直线(这些元素构成了矢量)。

cairographics.org

Cairo samples 官方样例

Examples 官方案例

Download

Index of /snapshots 抢鲜版源码

Index of /releases 稳定版源码,提供了C/C++,Python,R语言的支持。pixman是它的依赖库。

https://github.com/freedesktop/cairo C语言源码

https://github.com/pygobject/pycairo Python bindings for cairo

cairo / cairo-demos · GitLab

二、Cairo使用示例

例1、和Qt结合的原理是:Cairo画图到QImage的缓存(image.bits),再用QPainter把QImae贴图出来。

void MainWindow::paintEvent(QPaintEvent *pEvent)
{Q_UNUSED(pEvent);//原生的绘图QPainter p(this);p.drawLine(QPoint(0, 0), QPoint(150, 220));//使用cairo绘图引擎const char *pVersion = cairo_version_string();qDebug() << pVersion;//创建一张图QImageint iW = this->width();int iH = this->height();QImage image(iW, iH, QImage::Format_ARGB32);unsigned char *pData = image.bits();int iLineStride = image.bytesPerLine();//将此图转换为cairo图cairo_surface_t *pCairoSurface = cairo_image_surface_create_for_data(pData, CAIRO_FORMAT_ARGB32, iW, iH, iLineStride);cairo_surface_set_device_scale(pCairoSurface, 1, 1);cairo_t *pCairoContext = cairo_create(pCairoSurface);cairo_surface_destroy(pCairoSurface);if (pCairoContext){double x = 100.6, y = 328.0;double x1 = 102.4 + 100, y1 = 130.4,x2 = 153.6 + 240, y2 = 405.6,x3 = 230.4 + 400, y3 = 200;cairo_move_to(pCairoContext, x, y);cairo_curve_to(pCairoContext, x1, y1, x2, y2, x3, y3);cairo_set_line_width(pCairoContext, 1.0);           //设置线宽cairo_set_source_rgb(pCairoContext, 1.0, 0.0, 0.0); //设置线颜色cairo_stroke(pCairoContext);cairo_destroy(pCairoContext);}//贴图p.drawImage(this->rect(), image);
}

例2、读图片文件,并显示

//define params
int width, height, channels;
//read image data from file using stb_image.h
unsigned char* data = stbi_load(imagePath.c_str(), &width, &height, &channels, STBI_rgb_alpha);
//create surface with image size and format is ARGB32
this->imageSource = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
//get pointer of cairo data
unsigned char * surface_data = cairo_image_surface_get_data(this->imageSource);
//copy current data to surface pointer
memcpy(surface_data, data, width * height * 4 * sizeof(unsigned char));
//mark as dirty to refresh surface
cairo_surface_mark_dirty(this->imageSource);
//free image data
free(data);

或者

int              w, h;
cairo_surface_t *image;image = cairo_image_surface_create_from_png ("data/romedalen.png");
w = cairo_image_surface_get_width (image);
h = cairo_image_surface_get_height (image);cairo_translate (cr, 128.0, 128.0);
cairo_rotate (cr, 45* M_PI/180);
cairo_scale  (cr, 256.0/w, 256.0/h);
cairo_translate (cr, -0.5*w, -0.5*h);cairo_set_source_surface (cr, image, 0, 0);
cairo_paint (cr);
cairo_surface_destroy (image);

三、完整的工程源码及库文件

本人使用的编程环境是QtCreator + MSVC2019 32/64位

https://gitee.com/libaineu2004/cairo_demo

四、cairo的开源应用案例是scribus软件

scribus是开源项目,使用C++/Qt GUI

源码检索关键词【cairo_image_surface_create_for_data】 

 Cairo画图到QImage的缓存(image.bits),再用QPainter把QImae贴图出来。

canvas.cpp
void Canvas::drawContents(QPainter *psx, int clipx, int clipy, int clipw, int cliph)
{ScPainter *painter=nullptr;QImage img = QImage(clipw * devicePixelRatio(), cliph * devicePixelRatio(), QImage::Format_ARGB32_Premultiplied);img.setDevicePixelRatio(devicePixelRatio());painter = new ScPainter(&img, img.width(), img.height(), 1.0, 0);painter->clear(palette().color(QPalette::Window));
painter->newPath();painter->moveTo(0, 0);painter->lineTo(clipw, 0);painter->lineTo(clipw, cliph);painter->lineTo(0, cliph);painter->closePath();painter->setClipPath();painter->translate(-clipx, -clipy);painter->setZoomFactor(m_viewMode.scale);painter->translate(-m_doc->minCanvasCoordinate.x(), -m_doc->minCanvasCoordinate.y());painter->setLineWidth(1);painter->setFillMode(ScPainter::Solid);painter->end();psx->drawImage(clipx, clipy, img);delete painter;painter=nullptr;
}

桌面排版软件Scribus v1.5.5源码编译,使用VS2017+Qt5.12.7环境_libaineu2004的博客-CSDN博客

x1.skia

Skia是一个开源的二维图形库,提供各种常用的API,并可在多种软硬件平台上运行。谷歌Chrome浏览器、Chrome OS、Fuchsia、安卓、Flutter、火狐浏览器、火狐操作系统以及其它许多产品都使用它作为图形引擎。Skia由谷歌出资管理,任何人都可基于BSD免费软件许可证使用Skia。Skia开发团队致力于开发其核心部分, 并广泛采纳各方对于Skia的开源贡献。
Qt+Skia组合也是绘图的好方案

Windows环境VS2017编译skia库,亲测成功,借助skui的方法_libaineu2004的博客-CSDN博客

x2.geogebra

GeoGebra是自由且跨平台的动态数学软件,提供各级教育使用,包含了几何、代数、表格、图形、统计和微积分,集中在一个容易使用的软件。

www.geogebra.org/classic

www.geogebra.org/calculator

GeoGebra Classic - GeoGebra

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

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

相关文章

基于Qt的多媒体综合应用程序设计(2)

框架结构图等 1.多媒体综合应用程序设计思路 首先创建一个Qt Widgets Application程序,在头文件中完成类、函数及变量的设置,在程序窗口中添加相应的控件,利用控件的属性和方法分别实现文字处理程序跳转、绘图程序跳转、图像处理程序跳转、音频播放器跳转、视频播放器跳转和…

VS+Qt+鼠标框选后掩膜去除背景

前言&#xff1a; 实际采集的图片背景比较复杂&#xff0c;所以我想着采用框选矩形框掩膜的方式简单粗暴的消除背景对图片有用区域的干扰。网上搜索了一圈尝试了几种不同的方式去框选&#xff0c;最后发现还是Qt的鼠标事件比较容易上手。 效果图&#xff1a; 主要思路&#x…

QT—3D绘图

OpenGL是一个跨平台的、用来渲染3D图形的标准API,Qt对OpenGL提供了强大的支持。Qt4时代的QtOpenGL模块在Qt5中已经不再建议使用,OpenGL相关的类被移到了Qt GUI模块。Qt Widgets模块中的QOpenGLWidget类提供了一个可以渲染OpenGL图形的部件&#xff0c;通过该部件可以轻松地将Op…

【Qt】Qt环境配置与入门案例

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Qt环境配置与入门。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&…

(三)NI采集卡应用学习:在Qt中实现多路数据的同时采集、显示、绘图及存储

1、使用NI MAX创建多路输入的测量任务 本处设置Dev1/ai0:3四路电压输入&#xff0c;采样率均为100&#xff0c;差分连接。 2、代码 // 设置地址 void Widget::on_add_pushButton_clicked() {address_txt QFileDialog::getExistingDirectory(this, tr("Open Directory&q…

linux程序框架设计,《Linux与Qt程序设计》知识框架

本文主要是通过一本书来大致了解Qt开发的框架,不对具体内容做详细分析。 1.首先弄清楚概念:定义->以自己的话理解是什么-> 实现的是什么功能->用在哪些地方 2.前面认识到的知识点的特点-> 代码实现-> 工程代码分析 第一部分 Linux基础知识 第二部分 Qt程序基础…

QT开发应用程序(11)--图形绘制和文本输出

代码演示&#xff1a; #include <QPainter> MyDraw::MyDraw(QWidget *parent) :QWidget(parent) {QLinearGradient linearGradient(0,0,400,400);linearGradient.setColorAt(0.0,Qt::white);linearGradient.setColorAt(0.2,QColor(0,0,0));linearGradient.setColorAt(1.…

chatgpt赋能python:使用Python捕获错误:为您的代码添加可靠性

使用Python捕获错误&#xff1a;为您的代码添加可靠性 在编写Python代码时&#xff0c;错误很常见。您可能会因输入无效参数而收到TypeError&#xff0c;或者因无法连接到数据库而收到ConnectionError。当这些错误发生时&#xff0c;您的代码可能会崩溃或产生不正确的结果。尽…

chatgpt赋能python:关闭Python:如何优雅地退出一个Python程序

关闭Python&#xff1a;如何优雅地退出一个Python程序 Python作为一门开发语言&#xff0c;可以广泛应用于众多领域&#xff0c;如数据科学、人工智能、Web应用开发等等。但有时候&#xff0c;我们需要关闭一个正在运行的Python程序。本文将介绍如何优雅地退出一个Python程序&…

chatgpt赋能python:Python异常捕获存在的问题

Python 异常捕获存在的问题 作为一门广受欢迎、应用广泛的编程语言&#xff0c;Python 在处理异常方面有着比较完善的设计。Python 提供了 try…except…finally 这样的异常处理机制&#xff0c;通过这些机制&#xff0c;开发者可以捕获、处理程序中产生的异常&#xff0c;从而…

yagmail——快速发送邮件

yagmail——快速发送邮件 目标&#xff1a;如何利用python中的yagmail包&#xff0c;快速发送邮件。 python写的一个简单demo脚本代码如下&#xff1a; import yagmail import pandas as pd from loguru import logger# 保存excel文件 contents pd.DataFrame() contents[&quo…

电脑和微信怎么发邮件到别人邮箱,企业邮箱如何发email给别人

邮箱已成为主流的办公软件&#xff0c;除了日常的电脑办公使用以外&#xff0c;你知道还有哪些便捷的方式使用邮箱吗&#xff1f;现在是互联网时代&#xff0c;许多邮箱都研发了手机邮箱配合使用&#xff0c;那TOM企业邮箱有哪些便捷的服务呢&#xff1f;一起看看吧&#xff01…

怎么发送电子邮件到别人邮箱?手把手教你!

在日常生活中&#xff0c;我们在工作学习的时候都离不开电子邮件&#xff0c;无论两人的距离有多远&#xff0c;都是可以通过电子邮件的方式完成信息的即时传递。这样不仅可以传输文字信息&#xff0c;还能传输图片、视频等多种格式的信息。那么&#xff0c;怎么发送电子邮件到…

chatgpt赋能Python-pythonapp自动化

Python App自动化&#xff1a;优化SEO的终极解决方案 随着互联网的发展&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;变得日益重要。对于任何网站或应用程序开发人员来说&#xff0c;SEO应该是一个非常重要的考虑因素。为了帮助开发人员和企业提高其在线可见性&#x…

chatgpt赋能python:Python自动化断言介绍

Python 自动化断言介绍 软件业的各种应用程序不可避免地需要与用户进行交互。测试团队应该确保这些应用程序快速&#xff0c;可靠地响应用户交互&#xff0c;并注重高质量测试的策略和工具。Python自动化断言是一种测试策略&#xff0c;可帮助团队实现高品质和高效率的测试。P…

chatgpt赋能python:Python自动化操作桌面的方法和应用

Python自动化操作桌面的方法和应用 Python是一种高级编程语言&#xff0c;越来越多的研究人员和程序员将其应用在自动化操作任务上。本文将向您介绍如何利用Python自动化操作桌面并且展示一些实际应用。 桌面自动化操作是什么&#xff1f; 桌面自动化操作是使用编程语言编写…

chatgpt赋能python:Python表格自动化:优化你的数据处理工作效率

Python表格自动化&#xff1a;优化你的数据处理工作效率 作为一名有10年Python编程经验的工程师&#xff0c;我深切体会到编程能够为我们带来的高效和便利。其中&#xff0c;Python在数据分析和处理方面的优势尤为突出。本文将从Python表格自动化的角度&#xff0c;为大家介绍…

chatgpt赋能python:Python如何自动化办公

Python如何自动化办公 随着信息技术的不断发展和进步&#xff0c;自动化技术已经在各行各业得到了广泛的应用。作为一种高级编程语言&#xff0c;Python在自动化办公领域发挥了重要的作用。下面&#xff0c;我们来详细了解一下Python如何自动化办公。 什么是Python自动化办公…

chatgpt赋能Python-python_gui自动化点击

简介 Python是一种功能强大的编程语言&#xff0c;它的广泛应用让许多企业都使用了这种语言来编写脚本&#xff0c;编写小型应用程序和构建自动化工作流程。其中&#xff0c;Python GUI自动化成为了越来越普遍的需求。Python可以使用多种GUI库&#xff0c;例如PyQt、Tkinter和…

chatgpt赋能python:如何用Python自动化办公提升工作效率

如何用Python自动化办公提升工作效率 随着科技的不断发展和普及&#xff0c;人们越来越重视如何利用技术手段提高生产效率。对于很多办公人员来说&#xff0c;每天大量的重复性工作可能会让人感到枯燥乏味。而Python作为一种易学易用的编程语言&#xff0c;可以帮助办公人员自…