cario库——C++画图

news2024/12/28 22:22:58

文章目录

  • RGBA
  • 1. 多个(x,y)坐标点,连成线
  • 2. 画圆
  • 3. 填充颜色
  • 4. 曲线图

RGBA

  • rgb:红绿蓝

    • rgb(0,0,0):黑色
    • rgb(255,255,255):白色
  • rgba:红绿蓝+透明度(0:完全透明,1:完全不透明)

    • rgba(255,255,255,0)则表示完全透明的白色;
    • rgba(0,0,0,1)则表示完全不透明的黑色;
    • rgba(0,0,0,0)则表示完全不透明的白色,也即是无色

Cario库是一个用于图形绘制的开源C++库,主要用于处理2D图形的渲染和绘制。Cario库通过使用矢量图形来实现高质量的渲染,这意味着图形可以按照任意缩放级别进行绘制而不会产生锯齿或像素化。

头文件:#include <cairo/cairo.h>

1. 多个(x,y)坐标点,连成线

示例:
	#include <cairo/cairo.h>
	// 创建一个画布
	cairo_surface_t* surface;
	// 创建画布之后,需要一个管理员,即上下文
	cairo_t* cr;
	
	// 创建基于PNG图像文件
	surface = cairo_image_surface_create_from_png("./one.png"); // (CAIRO_FORMAT_A8, _param_width, _param_height);
	// _get_width()和_get_height()是用于获取图像表面宽度和高度的函数
	int w = cairo_image_surface_get_width(surface);
	int h = cairo_image_surface_get_height(surface);

	//
	cr = cairo_create(surface);
	cairo_set_source_rgb(cr, 1, 1, 0);  //1,1,0表示黄色(1,0,0 表示红色)
	cairo_set_line_width(cr, 3);  // 设置前线条宽度设置为指定的值。它接受2个参数,第一个参数是 Cairo 上下文对象,第二个参数是线条宽度
	
	// 定义一个面,一个面包含N个点
	vector<point_int> all_point ;
	// 每个点的结构体,
	sturct point_int
	{
		int x;
		int y;
	};
	// 绘制原始边界
	if (all_point.size() > 0)
	{
			// 绘制原始边界
			// cairo_move_to(cr, x, y) 函数将当前绘图点移动到坐标为(x, y) 的位置
			cairo_move_to(cr, all_point[m].x, all_point[m].y);
			for (int i = 1; i < all_point.size(); i++)
			{
				//cairo_line_to(cr, x, y) 函数会从当前绘图点绘制一条到(x, y) 坐标点的直线。
				if (all_point[i].x > w)
				{
					all_point[i].x = w;
				}
				if (all_point[i].y > h)
				{
					all_point[i].y = h;
				}
				cairo_line_to(cr, all_point[i].x, all_point[i].y);
			}
			// 再次连线到起始点,使其闭合起来,也可以使用 cairo_close_path() 函数
			cairo_line_to(cr, all_point.at(0).x, all_point.at(0).y);
			//cairo_close_path() 函数用于将当前路径的最后一个点连接到路径起点,从而封闭路径。
			cairo_close_path(cr);
			//cairo_stroke() 函数则是用于描边并显示出路径的函数。
			cairo_stroke(cr);
		}

		// _write_to_png() 函数用于将 Cairo 库中的 cairo_surface_t 对象保存为 PNG 文件,需要指定 PNG 文件的路径。
		cairo_surface_write_to_png(surface, "./result.png");

		// cairo_destroy() 和 cairo_surface_destroy() 函数则分别用于释放绘图环境和绘图表面的内存资源。
		cairo_destroy(cr);
		cairo_surface_destroy(surface);
  • cairo_image_surface_create_from_png()是用于创建基于PNG图像文件创建表面的函数之一
    该函数将指定路径上的 PNG 文件读入一个新表面中,返回的指针就是新创建的cairo_surface_t类型的表面。如果读取 PNG 文件失败或文件格式不正确,则函数返回一个 NULL 指针。

  • cairo_create()是用于创建新上下文对象的函数,该函数创建和返回一个新的 Cairo 上下文对象,该对象链接到指定的表面(cairo_surface_t类型)。使用该对象,您可以执行各种绘图操作,包括绘制线条、矩形、文本、图像等。

2. 画圆

  1. cairo_arc(cr, centerX, centerY, radius, 0, 2 * M_PI);
  2. cairo_arc 是Cairo库提供的函数,用于绘制一段圆弧。在这里,它被用来绘制一个完整的圆。
  3. cr 是Cairo渲染上下文,这是你之前创建并初始化的渲染上下文。
  4. centerX和 centerY是圆的中心坐标,表示在渲染上下文中绘制圆的位置。
  5. radius 是圆的半径,表示圆的大小。
  6. 0 是起始角度,这里是0弧度,表示圆的起始点。
  7. 2 * M_PI是结束角度,表示圆的结束点。SU_PI(可能是一个常数或宏定义)通常等于圆周率π的两倍,因此2 * SU_PI 表示一个完整的圆。
  8. cairo_stroke(m_cairo_render.m_cr);:
  9. cairo_stroke 函数是Cairo库的函数,用于在渲染上下文中描边已经绘制的图形。
#include <cairo/cairo.h>
#define M_PI       3.14159265358979323846   // pi
// 定义一个绘制圆的函数
void drawCircle(cairo_t *cr, double centerX, double centerY, double radius) {
    // 开始绘制路径
    cairo_new_path(cr);
    // 移动到圆心
    cairo_move_to(cr, centerX, centerY);
    // 绘制圆形
    cairo_arc(cr, centerX, centerY, radius, 0, 2 * M_PI);
    // 关闭路径
    cairo_close_path(cr);
    // 设置填充颜色
    cairo_set_source_rgb(cr, 0, 0, 0); // 黑色
    // 填充圆形
    cairo_fill(cr);
}

int main() {
    // 创建Cairo绘图上下文
    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 400, 400);
    cairo_t *cr = cairo_create(surface);
    // 绘制圆形
    double centerX = 200.0;
    double centerY = 200.0;
    double radius = 100.0;
    drawCircle(cr, centerX, centerY, radius);
    // 保存绘图到文件
    cairo_surface_write_to_png(surface, "./circle.png");
    // 清理资源
    cairo_destroy(cr);
    cairo_surface_destroy(surface);
    return 0;
}

实现效果
在这里插入图片描述

3. 填充颜色

#define M_PI       3.14159265358979323846   // pi
#include <cairo/cairo.h>
// 定义一个绘制六边形的函数
void drawHexagon(cairo_t* cr, double centerX, double centerY, double sideLength) {
    // 计算六边形的顶点坐标
    double x[6];
    double y[6];
    for (int i = 0; i < 6; ++i) {
        x[i] = centerX + sideLength * cos(i * M_PI / 3);
        y[i] = centerY + sideLength * sin(i * M_PI / 3);
    }

    // 开始绘制路径
    cairo_new_path(cr);
    // 移动到第一个顶点
    cairo_move_to(cr, x[0], y[0]);

    // 依次连接六个顶点
    for (int i = 1; i < 6; ++i) {
        cairo_line_to(cr, x[i], y[i]);
    }

    // 关闭路径
    cairo_close_path(cr);
    // 设置线段粗细
    cairo_set_line_width(cr, 3.0);
    // 设置内部填充颜色
    cairo_set_source_rgba(cr, 1.0, 1.0, 0.0, 1.0); // 黄色
    // 填充六边形
    cairo_fill_preserve(cr);
    // 设置边框颜色
    cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // 黑色
    // 绘制边框
    cairo_stroke(cr);

}

int main() {
    // 创建Cairo绘图上下文
    cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 400, 400);
    cairo_t* cr = cairo_create(surface);

    // 绘制六边形
    double centerX = 200.0;
    double centerY = 200.0;
    double sideLength = 100.0;
    drawHexagon(cr, centerX, centerY, sideLength);

    // 保存绘图到文件
    cairo_surface_write_to_png(surface, "../hexagon3.png");

    // 清理资源
    cairo_destroy(cr);
    cairo_surface_destroy(surface);

    return 0;
}

效果

在这里插入图片描述

在 Cairo 绘图库中,cairo_stroke(cr) 和 cairo_stroke_preserve(cr) 是两个不同的函数,它们的行为稍有不同。

cairo_stroke(cr):
    这个函数用于绘制当前路径的线段,也就是描绘路径的轮廓。
    在执行 cairo_stroke(cr) 后,路径将被清除,不再保留,因此你不能再在同一个路径上执行其他操作(如填充)。
    用于绘制路径的轮廓,并清除路径,以便进行其他绘图操作。

cairo_stroke_preserve(cr):
    这个函数与 cairo_stroke(cr) 的区别在于它绘制路径的线段,但不清除路径,因此路径保持在当前上下文中,你可以随后在相同路径上执行其他操作,比如填充。
    用于绘制路径的轮廓,但路径仍然保持在上下文中,可用于后续绘制操作。

所以,如果你想在同一个路径上同时绘制边框和填充,你应该使用 cairo_stroke_preserve(cr) 来先绘制边框,然后再进行填充,而不是 cairo_stroke(cr),因为后者会清除路径,使填充无法进行。

在 Cairo 绘图库中,cairo_fill(cr) 和 cairo_fill_preserve(cr) 也是两个有明显区别的函数:

1.cairo_fill(cr):

这个函数用于填充当前路径的内部区域。
执行完 cairo_fill(cr) 后,路径将被清除,不再保留。也就是说,你不能再在同一个路径上执行其他操作(如描边)。
主要用于填充路径的内部并清除路径,以便进行其他绘图操作。

2.cairo_fill_preserve(cr):

与 cairo_fill(cr) 的区别在于它填充路径的内部,但不清除路径。所以路径仍然存在于当前的上下文中,
这允许你随后在相同的路径上执行其他操作,比如描边。
主要用于填充路径的内部,但路径仍然存在于上下文中,可用于后续绘制操作。

所以,如果你想在同一个路径上同时进行填充和描边,你应该使用 cairo_fill_preserve(cr) 进行填充,然后再描边。这与先前我提到的 cairo_stroke_preserve(cr) 的工作方式相似,但它是用于填充而不是描边的。

4. 曲线图

    double x = 25.6, y = 128.0;
    double x1 = 102.4, y1 = 230.4, x2 = 153.6, y2 = 25.6, x3 = 230.4, y3 = 128.0;
    // 画曲线图
    cairo_move_to(cr, x, y);
    cairo_curve_to(cr, x1, y1, x2, y2, x3, y3);
    cairo_set_line_width(cr, 10.0);
    cairo_stroke(cr);
    // 曲线坐标对应的直线
    cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.8);
    cairo_set_line_width(cr, 6.0);
    cairo_move_to(cr, x, y);   
    cairo_line_to(cr, x1, y1);
    cairo_line_to(cr, x2, y2);
    cairo_line_to(cr, x3, y3);
    cairo_stroke(cr);

效果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何挑选多用户商城源码?

数字化时代&#xff0c;电子商务已经成为了商业发展的重要方向。无论是大型企业还是个人创业者&#xff0c;都希望能够通过搭建一个多用户商城来拓展自己的业务&#xff0c;并与更多的消费者建立联系。 对于大多数人来说&#xff0c;从零开始开发一个多用户商城是一项巨大的挑战…

PTA 小字辈(树)

题目 本题给定一个庞大家族的家谱&#xff0c;要请你给出最小一辈的名单。 输入格式&#xff1a; 输入在第一行给出家族人口总数 N&#xff08;不超过 100 000 的正整数&#xff09; —— 简单起见&#xff0c;我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号&#…

minikube创建一个pod并暴露端口(使用docker驱动安装)

因为minikube使用service暴露端口是使用nodeIP:nodePort 而不是 localhost:nodePort 公开访问。我们只能使用kubectl的端口转发功能或者使用iptables的转发功能来实现外网服务暴露。 我这里使用shiro来举例 apiVersion: apps/v1 kind: Deployment metadata:name: shiro550 spe…

财务对账-财务收发存-业务收发存

务对账是指将公司的账目与银行等第三方提供的相关账单进行核对比对&#xff0c;以确定公司记录的交易是否与银行或其他第三方的记录一致。对账的具体步骤通常包括以下几个方面&#xff1a; 收集资料&#xff1a;首先需要收集公司的财务记录&#xff0c;包括公司银行账户的流水…

学员分享| 一个普通学员的HCIE-DATACOM备考之路!

大家好&#xff0c;我是G-LAB IT实验室的周同学&#xff0c;在这篇文章中&#xff0c;我将分享我的备考HCIE数通方向的心路历程。我的备考之路&#x1f447; ——备考理论—— 我从一年前开始了HCIE数通方向的备考。一开始&#xff0c;我并没有完全了解这个认证的难度和复杂性…

免费Scrum管理工具-Leangoo领歌

Leangoo领歌是一款永久免费的专业的敏捷开发管理工具&#xff0c;提供端到端敏捷研发管理解决方案&#xff0c;涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 
 Leangoo领歌上手快、实施成本低&#xff0c;可帮助企业快速落地敏捷&#xff0c;提质增效、缩短周期、加速…

vue 插槽-默认插槽

vue 插槽-默认插槽 **创建 工程&#xff1a; H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day05\准备代码\07-插槽-默认插槽 vue --version vue create…

CMMI软件能力成熟度认证指南来了

CMMI能力成熟度模型集成&#xff0c;是一种评估或认证体系。其核心理念是&#xff1a;过程决定质量&#xff0c;这六个字能够让大家对CMMI有了一个大概的了解。是的&#xff0c;重点是过程&#xff0c;CMMI评估的核心内容也是过程。主要是CMMI研究院主任评估员根据CMMI模型检查…

torch版本对应的torch_geometric与torch-sprse/cluster/scatter库的正确安装

torch_geometric官网&#xff1a; Installation — pytorch_geometric documentation 使用上述标红命令即可快速安装需要的包&#xff08;确定自己环境中安装的pytorch版本以及cuda版本&#xff0c;使用对应的命令即可&#xff09; 如安装的pytorch为1.60&#xff0c;cuda为1…

10款远程办公软件,助你事半功倍,晋升快如闪电

选择一个易于使用和方便的远程软件&#xff0c;可以提高团队的整体效率&#xff0c;减少加班&#xff0c;使整个团队更受益。互联网行业从产品经理、UI/从UX设计师到技术开发和测试人员&#xff0c;每一个环节都需要密切沟通和跟踪&#xff0c;在远程沟通中及时发现问题&#x…

广东广西大量工地建筑支模

近年来&#xff0c;广东广西地区的建筑工地发展迅猛&#xff0c;为满足日益增长的建筑需求&#xff0c;大量工地都需要使用支模模板。支模模板是建筑施工中不可或缺的重要工具&#xff0c;用于搭建楼层、梁柱等结构的模板系统。在广东广西&#xff0c;有许多专业的支模模板厂家…

万物归宗系列01-html基本语法

万物归宗系列&#xff0c;即什么都懂一点系列。 HTML是标签语言&#xff0c;一般成双成对。 Hypertext Markup Language&#xff1a;超⽂本标记语⾔。是⽤来制作⽹页的⼀种标记语⾔。 1 基本框架 <!DOCTYPE html> <html lang"en"> <head><meta…

DAC8563数模转换模块的使用介绍

前言 DAC8563为16位低功耗、电压输出、双通道的数模转换器&#xff0c;其包括一个2.5V4ppm/C 内部基准&#xff0c;从而提供了一个 2.5V 或 5V 的满量程输出电压范围。 此内部基准有一精度&#xff0c;并且能够在 VREFIN/VREFOUT引脚上提供或吸收高个 5mV 的初始达 20mA 的电流…

【75. 颜色分类】

目录 一、题目描述二、算法思想三、代码实现 一、题目描述 二、算法思想 三、代码实现 class Solution { public:void sortColors(vector<int>& nums) {int nnums.size();for(int left-1,rightn,i0;i<right;){if(nums[i]0)swap(nums[i],nums[left]);else if(nums…

7+非肿瘤+WGCNA+分型+实验,筛选关键基因进一步分型以及表达验证

今天给同学们分享一篇非肿瘤WGCNA分型实验的生信文章“Identification of molecular subtypes and immune infiltration in endometriosis: a novel bioinformatics analysis and In vitro validation”&#xff0c;这篇文章于2023年8月18日发表在Front Immunol期刊上&#xff…

Net6集成Nacos实现服务注册

Net6集成Nacos实现服务注册 一、服务注册1.创建WebAPI项目2.安装Nuget包3.注册NacosNacos配置文件&#xff08;放在Appsetting.json或其他文件中&#xff09;4.创建Api控制器5.运行效果 二、配置中心1.设置配置2.读取配置3.展示效果4.设置多个配置项 Nacos安装 nacos-sdk-cshar…

Java自定义线程池

一、线程池的概念和作用 线程池是一种用于管理和重用线程的机制。它允许你创建一个线程池&#xff0c;然后将任务提交给这个线程池&#xff0c;线程池会自动分配线程来执行这些任务。 线程池的作用是优化线程的管理和资源利用&#xff0c;以减少线程创建和销毁的开销&#xff0…

竞赛选题 深度学习交通车辆流量分析 - 目标检测与跟踪 - python opencv

文章目录 0 前言1 课题背景2 实现效果3 DeepSORT车辆跟踪3.1 Deep SORT多目标跟踪算法3.2 算法流程 4 YOLOV5算法4.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; *…

保姆级教程,教你AI数字人应该怎么制作?!

随着人工智能的发展&#xff0c;利用数字人制作短视频已经成为当下火热的项目&#xff0c;因为这种方式不需要真人出镜&#xff0c;避免了个人不上镜或者不喜上镜而不能做短视频的缺点&#xff0c;用数字人代替真人&#xff0c;不仅内容里人物有了&#xff0c;而且这种形式还非…

智能井盖是什么?万宾科技智能井盖传感器有什么特点

智能井盖是一种基于物联网和人工智能技术的新型城市设施。它不仅具备传统井盖的功能&#xff0c;还能通过数字化、自动化的方式实现远程监控和智能管理&#xff0c;提升城市运行效率和服务水平。 WITBEE万宾智能井盖传感器EN100-C2是一款井盖异动监测的传感终端。对窨井盖状态(…