一生一世学坛

 找回密码
 立即注册
搜索
查看: 8535|回复: 2
打印 上一主题 下一主题

C++使用svg++开源库处理svg矢量图文件--遍历所有元素

[复制链接]

334

主题

385

帖子

6816

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
6816
跳转到指定楼层
楼主
发表于 2019-3-5 10:19:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
C++使用svg++开源库处理svg矢量图文件--遍历所有元素

svg++是一个基于boost的开源的头文件库,可以用来处理svg文件

下载svg++:https://github.com/svgpp/svgpp

解压后待使用。同时把third_party文件夹下的几个文件夹也拷贝到\svgpp-master\include 下方便使用。

编译好boost库,我编译的是静态lib库,不需要动态库dll文件,待用。

新建win32项目,设置头文件目录:
E:\Projects\boost_1_68_0\boost_1_68_0   boost库的头文件位置
svgpp-master\svgpp-master\include       svg++库的头文件位置
设置库文件目录:
E:\Projects\boost_1_68_0\boost_1_68_0\stage\lib   boost库编译出的lib文件的路径

编写示例代码:
#include  "svgpp/document_traversal.hpp"
#include "rapidxml_ns/rapidxml_ns.hpp"
#include "svgpp/policy/xml/rapidxml_ns.hpp"
#include "svgpp/svgpp.hpp"
#include "rapidxml_ns/rapidxml_ns_utils.hpp"

using namespace svgpp;
typedef rapidxml_ns::xml_node<> const * xml_element_t;

//输出遍历到每种元素时的打印信息
void printMessage(std::string msg)
{
        std::cout << msg.c_str() << std::endl;
}

//此类实现遍历到每种元素时打印相关信息,此处限于篇幅,只实现遍历path元素时打印信息
class Context
{
public:
        void path_move_to(double x, double y, tag::coordinate::absolute) {
                printMessage("path_move_to");
        };
        void path_line_to(double x, double y, tag::coordinate::absolute) {
                printMessage("path_line_to");
        };
        void path_line_to_ortho(double coord, bool horizontal, tag::coordinate::absolute)
        {
                printMessage("path_line_to_ortho");
        }
        void path_cubic_bezier_to(
                double x1, double y1,
                double x2, double y2,
                double x, double y,
                tag::coordinate::absolute) {
                printMessage("path_cubic_bezier_to");
        };
        void path_quadratic_bezier_to(
                double x1, double y1,
                double x, double y,
                tag::coordinate::absolute) {
                printMessage("path_quadratic_bezier_to");
        };
        void path_quadratic_bezier_to(
                double x, double y,
                tag::coordinate::absolute) {
                printMessage("path_quadratic_bezier_to 2");
        };
        void path_elliptical_arc_to(
                double rx, double ry, double x_axis_rotation,
                bool large_arc_flag, bool sweep_flag,
                double x, double y,
                tag::coordinate::absolute) {
                printMessage("path_elliptical_arc_to");
        };
        void path_close_subpath() {
                printMessage("path_close_subpath");
        };
        void path_exit() {
                printMessage("path_exit");
        };

        void on_enter_element(tag::element::any) {
                printMessage("on_enter_element");
        };
        void on_exit_element() {
                printMessage("on_exit_element");
        };

        void transform_matrix(const boost::array<double, 6> & matrix) {
                printMessage("transform_matrix");
        }
};

//为了需要遍历的各种元素
typedef
boost::mpl::set<
        // SVG Structural Elements
        tag::element::svg,
        tag::element::g,
        // SVG Shape Elements
        tag::element::circle,
        tag::element::ellipse,
        tag::element::line,
        tag::element::path,
        tag::element::polygon,
        tag::element::polyline,
        tag::element::rect
>::type processed_elements_t;

//shapes_attributes_by_element for 遍历元素的各种属性
//transform for 遍历元素的变换矩阵
typedef
boost::mpl::insert<
        traits::shapes_attributes_by_element,
        tag::attribute::transform
>::type processed_attributes_t;

void loadSvg(xml_element_t xml_root_element)
{
        Context context;
        document_traversal<
                processed_elements<processed_elements_t>,               
                processed_attributes<processed_attributes_t>
        >::load_document(xml_root_element, context);
}

void test1()
{
        try
        {
               
游客,如果您要查看本帖隐藏内容请回复
               
        }
        catch (std::exception const & e)
        {
                std::cerr << "Error: " << e.what() << "\n";
                return;
        }
        
}

int main()
{
        test1();
}

svg文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1322pt" height="1653pt" viewBox="0 0 1322 1653" version="1.1">
<g id="surface0">
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(100%,0%,0%);fill-opacity:1;" d="M 60.136719 1577.839844 L 1262.730469 1577.839844 L 1262.730469 74.773438 L 60.136719 74.773438 L 60.136719 1577.839844 Z M 60.136719 1577.839844 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 931.25 1549.910156 C 931.25 1546.789063 926.570313 1546.789063 926.570313 1549.910156 C 926.570313 1553.03125 931.25 1553.03125 931.25 1549.910156 "/>
<path style="fill:none;stroke-width:0.008;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M -1446456719.25 -366325561.25 L -1446456719.25 -366325561.25 " transform="matrix(0.00000000000119844,0,0,-0.00000000000119844,533.03689,1460.48003)"/>
<rect x=".01" y=".01" width="4.98" height="2.98" fill="none" stroke="blue" stroke-width=".03"/>
</g>
</svg>

//以下是程序的输出结果
on_enter_element
on_enter_element
path_move_to
path_line_to
path_line_to
path_line_to
path_line_to
path_close_subpath
path_move_to
path_exit
on_exit_element
on_enter_element
path_move_to
path_cubic_bezier_to
path_cubic_bezier_to
path_exit
on_exit_element
on_enter_element
path_move_to
path_line_to
path_exit
on_exit_element
on_enter_element
path_move_to
path_line_to
path_line_to
path_line_to
path_close_subpath
path_exit
on_exit_element
on_exit_element

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|分享学习  

GMT+8, 2024-5-2 10:04 , Processed in 0.046529 second(s), 6 queries , File On.

声明:本站严禁任何人以任何形式发表违法言论!

本站内容由网友原创或转载,如果侵犯了您的合法权益,请及时联系处理!© 2017 zamxqun@163.com

皖公网安备 34010402700634号

皖ICP备17017002号-1

快速回复 返回顶部 返回列表