笔者在写大一C++课程大作业的时候,想在VS2022里使用Cairo图形库来绘制SVG矢量图形。
在网上找了很多方法,包括编库、nuget程序包很多方法,但都很麻烦,而且在VS2022中尝尝会出现导入.lib和.dll库失败的情况,当时也是为此很抓狂,毕竟才大一也没有多少知识储备,而且选C++是作为选修课来学的。
后来发现,在VS2022的nuget程序包中,可以下载Cairo_static静态库,但很容易出现“不存在SVG表面”的情况,从而无法创建SVG图像。但同时还有一个程序包叫librsvg,在下载它后,使用方式同正常Cairo库相同,且可以正常的创建SVG文件。
下载量很少,但很好的解决了我的问题。
最后创建的效果也不错。下面的函数画出来的是坐标轴的箭头(通过输入坐标判断水平或竖直):
#include<iostream>
#include<stdlib.h>
#include"C:\Users\……\cairo.h"
#include"C:\Users\……\cairo-svg.h"//上面两个省略号处写完整的头文件路径(使用相对路径也可以)
#define WIDTH 300
#define HEIGHT 300//设置SVG表面的长与宽(实际上是宽与高)
using namespace std;
//绘制坐标轴的函数
void cairo_svg_draw_arrow(double x0, double y0, double x1, double y1, cairo_t *cr) {//接收参数分别为零点、轴上一点,箭头大小(设置为默认)和cairo画板的指针
cairo_set_line_width(cr, 1.0);//设置线条宽度
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);//设置线条颜色
cairo_move_to(cr, x0, y0);
cairo_line_to(cr, x1, y1);
cairo_stroke(cr);//绘制从(x0,y0)->(x1,y1)的线段
//取得方向
double xiebian = sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
double crsin = (y1 - y0) / xiebian;
double crcos = (x1 - x0) / xiebian;
//绘制x轴水平箭头
if (y0 == y1) {
//获得箭头顶点
double point1x = x1 + 8;
double point2x = x1 - 3.5;
double point2y1 = y0 + 3.5;
double point2y2 = y0 - 3.5;
//绘制箭头
cairo_move_to(cr, x1, y1);
cairo_line_to(cr, point2x, point2y2);
cairo_line_to(cr, point1x, y0);
cairo_line_to(cr, point2x, point2y1);
cairo_close_path(cr);
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);//设置颜色
cairo_fill(cr);//填充路径
}
//绘制y轴竖直箭头
if (x0 == x1) {
//获取箭头顶点
double point2y = y1 - 8;
double point1y = y1 + 3.5;
double pointx1 = x1 - 3.5;
double pointx2 = x1 + 3.5;
//绘制箭头
cairo_move_to(cr, x1, y1);
cairo_line_to(cr, pointx1, point1y);
cairo_line_to(cr, x0, point2y);
cairo_line_to(cr, pointx2, point1y);
cairo_close_path(cr);
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_fill(cr);
}
}
效果如下:
同时librsvg也可以为PNG等文件提供支持,免去了自己添加附加项、库目录等等的繁琐步骤,还是很好用的。
当然使用输出流也可以将SVG文件保存在磁盘上。但现在librsvg对于字体的嵌入支持的并不好(实际上librsvg内部也是Cairo库,只是将其打包好了可以直接用,免去了自己配置的繁琐步骤)。