/document.cpp

https://github.com/tnzk/shineshockd · C++ · 125 lines · 95 code · 20 blank · 10 comment · 10 complexity · e3b44514fefe238a4e1ab3be8da0c478 MD5 · raw file

  1. #include "document.h"
  2. Detection::Detection( int x, int y, double sim)
  3. {
  4. this->x = x;
  5. this->y = y;
  6. this->sim = sim;
  7. }
  8. Document::Document( string src_name, string tmpl_name)
  9. {
  10. this->src_name = src_name;
  11. this->tmpl_name = tmpl_name;
  12. src = NULL;
  13. tmpl = NULL;
  14. // Initialize FreeType2
  15. printf("Initialize FreeType2...");
  16. FT_Error error;
  17. FT_Init_FreeType( &library );
  18. FT_New_Face( library, "F910ComicW4.otf", 0, &face );
  19. FT_Set_Char_Size( face, 0, 13 * 64, 300, 300);
  20. printf("Done.\n");
  21. // Pase GRUB table
  22. printf("Parse GSUB table...");
  23. unsigned long length = 0;
  24. unsigned char* buf = (unsigned char*)malloc(2800000);
  25. error = FT_Load_Sfnt_Table( face, FT_MAKE_TAG('G','S','U','B'), 0, buf, &length);
  26. error = FT_Load_Sfnt_Table( face, FT_MAKE_TAG('G','S','U','B'), 0, buf, NULL);
  27. gsubt.LoadGSUBTable((FT_Bytes)buf);
  28. printf("Done.\n");
  29. }
  30. bool Document::Load()
  31. {
  32. // Load the source image and template
  33. // TODO: use any other file name
  34. src = cvLoadImage("ex-t06.png", CV_LOAD_IMAGE_COLOR);
  35. tmpl = cvLoadImage("template.bmp", CV_LOAD_IMAGE_COLOR);
  36. if(src == 0 || tmpl == 0) return false;
  37. // Create target image and generate buffer for template matching
  38. said = cvCloneImage(src);
  39. result = cvCreateImage( cvSize( src->width - tmpl->width + 1, src->height - tmpl->height + 1), 32, 1);
  40. return true;
  41. }
  42. int Document::Match( double threshould)
  43. {
  44. cvMatchTemplate(src, tmpl, result, CV_TM_CCOEFF_NORMED);
  45. for( int y = 0; y < result->height; y++) {
  46. for( int x = 0; x < result->width; x++) {
  47. CvScalar s = cvGet2D(result,y,x);
  48. if(s.val[0] >= threshould)
  49. detections.push_back( Detection( x, y, s.val[0]));
  50. }
  51. }
  52. return detections.size();
  53. }
  54. bool Document::Say( char* s, int detection_id)
  55. {
  56. // Draw the string specified onto a marker detected
  57. Utf8Decoder u8d(s, (int)strlen(s));
  58. IplImage* dst = this->said;
  59. Detection detection = detections[detection_id];
  60. int cpos_x = detection.x + 200;
  61. int cpos_y = detection.y;
  62. // TODO: make these modifiable
  63. unsigned char fcr = 0x00;
  64. unsigned char fcg = 0x00;
  65. unsigned char fcb = 0x00;
  66. cvRectangle( dst, cvPoint( detection.x, detection.y), cvPoint( detection.x + 200, detection.y + 200), CV_RGB( 0xff, 0xff, 0xff), CV_FILLED, 0, 0);
  67. for ( int n = 0; n < u8d.length(); n++ ){
  68. // Get correspoindng glyph ID from Unicode index.
  69. // Use vertical substitution if the glyph has.
  70. // TODO: Use ICU to do this
  71. long int unicode_index = u8d.get(n);
  72. long int glyph_index = FT_Get_Char_Index( face, unicode_index);
  73. uint32_t substitute_glyph;
  74. if( gsubt.GetVerticalGlyph( glyph_index, &substitute_glyph)) {
  75. glyph_index = substitute_glyph;
  76. }
  77. FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER | FT_LOAD_VERTICAL_LAYOUT);
  78. FT_GlyphSlot slot = face->glyph;
  79. FT_Bitmap bitmap = slot->bitmap;
  80. int offset_x = cpos_x + slot->metrics.vertBearingX / 64;
  81. int offset_y = cpos_y + slot->metrics.vertBearingY / 64;
  82. for( int i = 0; i < bitmap.rows * bitmap.width; i++){
  83. int x = ( i % bitmap.width) + offset_x;
  84. int y = offset_y + ( i / bitmap.width);
  85. unsigned char* src_b = (unsigned char*)(dst->imageData + dst->widthStep * y + x * 3);
  86. unsigned char* src_g = (unsigned char*)(dst->imageData + dst->widthStep * y + x * 3 + 1);
  87. unsigned char* src_r = (unsigned char*)(dst->imageData + dst->widthStep * y + x * 3 + 2);
  88. double gph_a = (double)bitmap.buffer[i] / 255.0;
  89. double src_a = 1.0 - gph_a;
  90. int tmp;
  91. tmp = fcr * gph_a + *src_r * src_a;
  92. *src_r = (tmp > 255) ? 255 : tmp;
  93. tmp = fcg * gph_a + *src_g * src_a;
  94. *src_g = (tmp > 255) ? 255 : tmp;
  95. tmp = fcb * gph_a + *src_b * src_a;
  96. *src_b = (tmp > 255) ? 255 : tmp;
  97. }
  98. cpos_y += (slot->metrics.vertAdvance) / 64;
  99. }
  100. return true;
  101. }
  102. void Document::Everything()
  103. {
  104. cvSaveImage( "shineshok_result.png", this->said);
  105. }