动态多维数组-multi_array

本站有 AGGCImg 的图像处理教程,AGG库倾向于矢量绘图,CImg倾向于图像处理。我们可以考虑双剑合壁,共同来生成我们要的图像。可是它们的内部数据格式却不完全相同:
  1. AGG的内部格式是 color buf[y][x][v]
    CImg的内部格式是 color buf[v][y][x]
    其中color为单通道颜色值、v代表颜色通道(如RGB三色)、x,y是坐标。我们这里让CImg的z轴为1,即二维图像。
  2. 我们得找个方法可以方便地互相转换,这里我们选用multi_array来做这件事(另,GIL也是一个不错的候选方案,见本站GIL教程 )。
  3. #include "boost/multi_array.hpp" // multi_array
  4. #include "cimg.h" // CImg
  5. #include <agg_pixfmt_rgb.h> //后面全是AGG的
  6. #include <agg_scanline_u.h>
  7. #include <agg_renderer_scanline.h>
  8. #include <../font_win32_tt/agg_font_win32_tt.h>
  9. #include <agg_font_cache_manager.h>
  10. #include <agg_conv_bspline.h>
  11. #include <agg_path_storage.h>
  12. #include <agg_conv_curve.h>
  13. #include <agg_conv_transform.h>
  14. #include <agg_ellipse.h>
  15. #include <agg_trans_single_path.h>
  16.  
  17. using  cimg_library::CImg;
  18. int  main () {
  19.     // AGG画图,写了一行字
  20.     char  buf[200][300][3];
  21.     agg::rendering_buffer rbuf(
  22.             (unsigned char *)buf,
  23.             300, 200,
  24.             300*3);
  25.     agg::pixfmt_rgb24 pixf(rbuf);
  26.     agg::renderer_base<agg::pixfmt_rgb24> renb(pixf);
  27.  
  28.     typedef  agg::font_engine_win32_tt_int16 fe_type;
  29.     typedef  agg::font_cache_manager<fe_type> fcman_type;
  30.  
  31.     renb.clear(agg::rgba(0.5,0.5,1));
  32.     fe_type font(::GetDC(0));
  33.     fcman_type font_manager(font);
  34.     font.height(32.0);
  35.     font.flip_y(true );
  36.     font.hinting(true );
  37.     if (!font.create_font( "Comic Sans MS" ,agg::glyph_ren_outline))  return  -1;
  38.     //坐标转换管道
  39.     typedef  agg::conv_curve<
  40.         fcman_type::path_adaptor_type
  41.     > cc_pa_type;
  42.     cc_pa_type ccpath(font_manager.path_adaptor());
  43.  
  44.     typedef  agg::conv_transform<cc_pa_type,
  45.         agg::trans_single_path> ct_cc_pa_type;
  46.     agg::trans_single_path trans_path;
  47.     ct_cc_pa_type ctpath(ccpath, trans_path);
  48.     
  49.     agg::path_storage ps;
  50.     ps.move_to(20,100);
  51.     ps.line_rel(80,50);
  52.     ps.line_rel(100,-100);
  53.     ps.line_rel(100,100);
  54.     
  55.     agg::conv_bspline<agg::path_storage> cb_ps(ps);
  56.     trans_path.add_path(cb_ps);
  57.  
  58.     agg::rasterizer_scanline_aa<> ras;
  59.     agg::scanline_u8 sl;
  60.     
  61.     double  x=0, y=0;
  62.     for ( const   wchar_t  *p = L "http://www.cppprog.com" ; *p; p++)
  63.     {
  64.         const  agg::glyph_cache* gc = font_manager.glyph(*p);
  65.         if (gc)
  66.         {
  67.             font_manager.init_embedded_adaptors(gc, x, y);
  68.             ras.add_path(ctpath);
  69.  
  70.             x += gc->advance_x;
  71.             y += gc->advance_y;
  72.         }
  73.     }
  74.     agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(1,0,0));
  75.  
  76.     // 定义CImg
  77.     CImg<unsigned char > img(300,200,1,3);
  78.  
  79.     // 用multi_array把AGG图像数据转成CImg
  80.     typedef  boost::multi_array_ref<unsigned  char ,3> array_type;
  81.     // AGG->多维数组
  82.     /**
  83.     * AGG排列是[y][x][v], CImg是[v][y][x]
  84.     * 设y=2, x=1, v=0(C语言默认顺序)
  85.     * 则AGG的[2][1][0]对应CImg就是[0][2][1]
  86.     */
  87.     typedef  boost::general_storage_order<3> storage;
  88.     array_type::size_type ordering[] = {0,2,1};
  89.     bool  ascending[] = { true , true , true };
  90.     array_type array_agg((unsigned char *)buf,boost::extents[3][200][300],storage(ordering,ascending));
  91.     // 把AGG图像数据赋值给CImg,multi_array_ref内部做转换工作
  92.     array_type(img.data, boost::extents[3][200][300]) = array_agg;
  93.  
  94.     // CImg图像处理
  95.     img.blur(6).noise(10).erode(4);
  96.  
  97.     // 把CImg处理过的图像又传给AGG
  98.     array_agg = array_type(img.data, boost::extents[3][200][300]);
  99.  
  100.     // AGG在此基础上画图
  101.     agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba(1,1,0));
  102.  
  103.     // 给CImg显示
  104.     array_type(img.data, boost::extents[3][200][300]) = array_agg;
  105.     img.erode(2);
  106.     img.display("view" );  
  107.     return  0;
  108. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值