[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创代码] [POGL]利用 Imager 模块渲染文字

本帖最后由 523066680 于 2018-11-18 11:26 编辑

效果:


之前用 Font::FreeType,真是繁琐。
  1. =info
  2.     Auth: 523066680
  3.     Date: 2018-11
  4. =cut
  5. use utf8;
  6. use Encode;
  7. use feature 'state';
  8. use Time::HiRes qw/time sleep/;
  9. use OpenGL qw/ :all /;
  10. use OpenGL::Config;
  11. use Data::Dumper;
  12. use Imager;
  13. STDOUT->autoflush(1);
  14. our $SIZE_X = 620;
  15. our $SIZE_Y = 520;
  16. our $WinID;
  17. our $pause = 0;
  18. INIT
  19. {
  20.     our $SIZE = 30;
  21.     our $font = Imager::Font->new(file  => encode('gbk', 'C:/windows/fonts/STXINGKA.TTF'), #STXINGKA.TTF
  22.                               size  => $SIZE );
  23.     our $bbox = $font->bounding_box(string=>"");
  24.     our @TEXT = split("", "十步杀一人,千里不留行。事了拂衣去,深藏身与名。" );
  25.     our @TEXT_DATA = map { {} } ( 0 .. $#TEXT );
  26.     for my $id ( 0 .. $#TEXT )
  27.     {
  28.         get_text_map( $TEXT[$id] , $TEXT_DATA[$id] );
  29.         printf "%d %d\n", $TEXT_DATA[$id]->{h}, $TEXT_DATA[$id]->{w};
  30.     }
  31. }
  32. Main();
  33. sub get_text_map
  34. {
  35.     our ($font, $SIZE);
  36.     my ( $char, $ref ) = @_;
  37.     my $bbox = $font->bounding_box( string => $char );
  38.     my $img = Imager->new(xsize=>$bbox->display_width+$bbox->left_bearing,
  39.                           ysize=>$bbox->font_height, channels=>4);
  40.     my $h = $img->getheight();
  41.     my $w = $img->getwidth();
  42.     $img->string(
  43.                font  => $font,
  44.                text  => $char,
  45.                x     => 0,
  46.                y     => $h + $bbox->global_descent,   # 基线 = 总高度 - 下沉
  47.                size  => $SIZE,
  48.                color => 'gold',
  49.                aa    => 1,     # anti-alias
  50.             );
  51.     $ref->{h} = $h, $ref->{w} = $w;
  52.     my @rasters;
  53.     my @colors;
  54.     for my $y ( reverse 0 .. $h - 1 )
  55.     {
  56.         @colors = $img->getpixel( x => [ 0 .. $w - 1 ], y => [$y] );
  57.         grep { push @rasters, $_->rgba  } @colors;
  58.     }
  59.     $ref->{array} = OpenGL::Array->new( scalar( @rasters ), GL_UNSIGNED_BYTE );
  60.     $ref->{array}->assign(0, @rasters);
  61. }
  62. sub display
  63. {
  64.     our ($bbox);
  65.     state $iter = -1;
  66.     my $xbase = 0.0;
  67.     my $ybase = 50.0;
  68.     glClear(GL_COLOR_BUFFER_BIT);
  69.     my $ref;
  70.     for my $id ( 0 .. $iter )
  71.     {
  72.         $ref = $TEXT_DATA[ $id ];
  73.         glRasterPos3f( $xbase , $ybase, 0.0 );
  74.         glDrawPixels_c( $ref->{w}, $ref->{h}, GL_RGBA, GL_UNSIGNED_BYTE, $ref->{array}->ptr() );
  75.         $xbase += $SIZE;
  76.         if ( $TEXT[$id] eq "。" ) { $ybase -= $bbox->font_height , $xbase = 0.0 }
  77.     }
  78.     $iter ++ if ($iter < $#TEXT and $pause == 0);
  79.     glutSwapBuffers();
  80. }
  81. sub init
  82. {
  83.     glClearColor(0.3, 0.6, 0.8, 1.0);
  84.    
  85.     # 通过开启混合,来避免位图的透明背景变黑问题
  86.     glEnable(GL_BLEND);
  87.     #glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA);
  88.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  89.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  90. }
  91. sub idle
  92. {
  93.     sleep 0.2;
  94.     glutPostRedisplay();
  95. }
  96. sub reshape
  97. {
  98.     my ($w, $h) = (shift, shift);
  99.     #Same with screen size
  100.     my $hz_half = $w/2.0;
  101.     my $vt_half = $h/2.0;
  102.     my $fa = 10.0;
  103.     glViewport(0, 0, $w, $h);
  104.     glMatrixMode(GL_PROJECTION);
  105.     glLoadIdentity();
  106.     glOrtho( 0.0, $h, 0.0, $w, 0.0, $fa*2.0);
  107.     glMatrixMode(GL_MODELVIEW);
  108.     glLoadIdentity();
  109.     gluLookAt(0.0,0.0,$fa, 0.0,0.0,0.0, 0.0,1.0, $fa);
  110. }
  111. sub hitkey
  112. {
  113.     my $key = shift;
  114.     glutDestroyWindow($WinID) if ( lc(chr($key)) eq 'q' );
  115.     if ( chr($key) eq 'p' ) { $pause = !$pause; }
  116. }
  117. sub Main
  118. {
  119.     glutInit();
  120.     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );
  121.     glutInitWindowSize($SIZE_X, $SIZE_Y);
  122.     glutInitWindowPosition(5, 100);
  123.     our $WinID = glutCreateWindow("Imager::Font");
  124.     &init();
  125.     glutDisplayFunc(\&display);
  126.     glutKeyboardFunc(\&hitkey);
  127.     glutReshapeFunc(\&reshape);
  128.     glutIdleFunc(\&idle);
  129.     glutMainLoop();
  130. }
复制代码
2

评分人数

    • CrLf: 好久没给你加技了技术 + 1
    • happy886rr: 好久没给你加技了技术 + 1

本帖最后由 523066680 于 2018-11-21 15:03 编辑

文本渲染
看完这篇后才发现 FreeType也可以直接生成字形的bitmap
face->glyph->bitmap
比起提取轮廓,用Bezier函数细分轮廓曲线,外加三角剖分函数填充,要省事得多。(虽然矢量填充很繁琐,但是缩放起来赏心悦目,哪种方案,视情况而定。)

TOP

这个厉害了

TOP

好一个pogl

TOP

返回列表