This program reads in a text file consisting of feature samples from a training page in the following format:
The result of this program is a binary inttemp file used by the OCR engine.
421 if (FLAGS_list_available_fonts) {
422 const std::vector<string>& all_fonts = FontUtils::ListAvailableFonts();
423 for (
unsigned int i = 0; i < all_fonts.size(); ++i) {
424 printf(
"%3u: %s\n", i, all_fonts[i].c_str());
426 "Font %s is unrecognized.\n", all_fonts[i].c_str());
432 if (FLAGS_text.empty()) {
433 tprintf(
"'--text' option is missing!\n");
436 if (FLAGS_outputbase.empty()) {
437 tprintf(
"'--outputbase' option is missing!\n");
440 if (!FLAGS_unicharset_file.empty() && FLAGS_render_ngrams) {
441 tprintf(
"Use '--unicharset_file' only if '--render_ngrams' is set.\n");
445 if (!FLAGS_find_fonts && !FontUtils::IsAvailableFont(FLAGS_font.c_str())) {
447 if (!FontUtils::IsAvailableFont(FLAGS_font.c_str(), &pango_name)) {
448 tprintf(
"Could not find font named %s.\n", FLAGS_font.c_str());
449 if (!pango_name.empty()) {
450 tprintf(
"Pango suggested font %s.\n", pango_name.c_str());
452 tprintf(
"Please correct --font arg.\n");
457 if (FLAGS_render_ngrams)
458 FLAGS_output_word_boxes =
true;
460 char font_desc_name[1024];
461 snprintf(font_desc_name, 1024,
"%s %d", FLAGS_font.c_str(),
462 static_cast<int>(FLAGS_ptsize));
464 render.set_add_ligatures(FLAGS_ligatures);
465 render.set_leading(FLAGS_leading);
466 render.set_resolution(FLAGS_resolution);
467 render.set_char_spacing(FLAGS_char_spacing * FLAGS_ptsize);
468 render.set_h_margin(FLAGS_margin);
469 render.set_v_margin(FLAGS_margin);
470 render.set_output_word_boxes(FLAGS_output_word_boxes);
471 render.set_box_padding(FLAGS_box_padding);
472 render.set_strip_unrenderable_words(FLAGS_strip_unrenderable_words);
473 render.set_underline_start_prob(FLAGS_underline_start_prob);
474 render.set_underline_continuation_prob(FLAGS_underline_continuation_prob);
477 if (FLAGS_writing_mode ==
"horizontal") {
479 render.set_vertical_text(
false);
480 render.set_gravity_hint_strong(
false);
481 render.set_render_fullwidth_latin(
false);
482 }
else if (FLAGS_writing_mode ==
"vertical") {
484 render.set_vertical_text(
true);
485 render.set_gravity_hint_strong(
false);
486 render.set_render_fullwidth_latin(
false);
487 }
else if (FLAGS_writing_mode ==
"vertical-upright") {
493 render.set_vertical_text(
true);
494 render.set_gravity_hint_strong(
true);
495 render.set_render_fullwidth_latin(
true);
497 tprintf(
"Invalid writing mode: %s\n", FLAGS_writing_mode.c_str());
503 if (!File::ReadFileToString(FLAGS_text.c_str(), &src_utf8)) {
504 tprintf(
"Failed to read file: %s\n", FLAGS_text.c_str());
509 if (strncmp(src_utf8.c_str(),
"\xef\xbb\xbf", 3) == 0) {
510 src_utf8.erase(0, 3);
512 tlog(1,
"Render string of size %d\n", src_utf8.length());
514 if (FLAGS_render_ngrams || FLAGS_only_extract_font_properties) {
517 const string kSeparator = FLAGS_render_ngrams ?
" " :
" ";
521 const unsigned int kCharsPerLine = (FLAGS_ptsize > 20) ? 50 : 100;
524 if (FLAGS_render_ngrams && !FLAGS_unicharset_file.empty() &&
526 tprintf(
"Failed to load unicharset from file %s\n",
527 FLAGS_unicharset_file.c_str());
534 const char *str8 = src_utf8.c_str();
535 int len = src_utf8.length();
537 std::vector<std::pair<int, int> > offsets;
539 while (offset < len) {
541 offsets.push_back(std::make_pair(offset, step));
545 if (FLAGS_render_ngrams)
546 std::random_shuffle(offsets.begin(), offsets.end());
548 for (
size_t i = 0, line = 1; i < offsets.size(); ++i) {
549 const char *curr_pos = str8 + offsets[i].first;
550 int ngram_len = offsets[i].second;
552 if (!FLAGS_unicharset_file.empty() &&
556 rand_utf8.append(curr_pos, ngram_len);
557 if (rand_utf8.length() > line * kCharsPerLine) {
558 rand_utf8.append(
" \n");
560 if (line & 0x1) rand_utf8.append(kSeparator);
562 rand_utf8.append(kSeparator);
565 tlog(1,
"Rendered ngram string of size %d\n", rand_utf8.length());
566 src_utf8.swap(rand_utf8);
568 if (FLAGS_only_extract_font_properties) {
569 tprintf(
"Extracting font properties only\n");
576 std::vector<float> page_rotation;
577 const char* to_render_utf8 = src_utf8.c_str();
581 std::vector<string> font_names;
585 int num_pass = FLAGS_bidirectional_rotation ? 2 : 1;
586 for (
int pass = 0; pass < num_pass; ++pass) {
589 for (
size_t offset = 0; offset < strlen(to_render_utf8); ++im, ++page_num) {
590 tlog(1,
"Starting page %d\n", im);
592 if (FLAGS_find_fonts) {
593 offset += render.RenderAllFontsToImage(FLAGS_min_coverage,
594 to_render_utf8 + offset,
595 strlen(to_render_utf8 + offset),
598 offset += render.RenderToImage(to_render_utf8 + offset,
599 strlen(to_render_utf8 + offset), &pix);
601 if (pix !=
nullptr) {
605 rotation = -1 * page_rotation[page_num];
607 if (FLAGS_degrade_image) {
609 FLAGS_rotate_image ? &rotation :
nullptr);
611 render.RotatePageBoxes(rotation);
615 page_rotation.push_back(rotation);
618 Pix* gray_pix = pixConvertTo8(pix,
false);
620 Pix* binary = pixThresholdToBinary(gray_pix, 128);
621 pixDestroy(&gray_pix);
622 char tiff_name[1024];
623 if (FLAGS_find_fonts) {
624 if (FLAGS_render_per_font) {
625 string fontname_for_file = tesseract::StringReplace(
626 font_used,
" ",
"_");
627 snprintf(tiff_name, 1024,
"%s.%s.tif", FLAGS_outputbase.c_str(),
628 fontname_for_file.c_str());
629 pixWriteTiff(tiff_name, binary, IFF_TIFF_G4,
"w");
630 tprintf(
"Rendered page %d to file %s\n", im, tiff_name);
632 font_names.push_back(font_used);
635 snprintf(tiff_name, 1024,
"%s.tif", FLAGS_outputbase.c_str());
636 pixWriteTiff(tiff_name, binary, IFF_TIFF_G4, im == 0 ?
"w" :
"a");
637 tprintf(
"Rendered page %d to file %s\n", im, tiff_name);
640 if (FLAGS_output_individual_glyph_images) {
642 tprintf(
"ERROR: Individual glyphs not saved\n");
647 if (FLAGS_find_fonts && offset != 0) {
654 if (!FLAGS_find_fonts) {
655 string box_name = FLAGS_outputbase.c_str();
657 render.WriteAllBoxes(box_name);
658 }
else if (!FLAGS_render_per_font && !font_names.empty()) {
659 string filename = FLAGS_outputbase.c_str();
660 filename +=
".fontlist.txt";
661 FILE* fp = fopen(filename.c_str(),
"wb");
663 tprintf(
"Failed to create output font list %s\n", filename.c_str());
665 for (
size_t i = 0; i < font_names.size(); ++i) {
666 fprintf(fp,
"%s\n", font_names[i].c_str());
int SpanUTF8NotWhitespace(const char *text)
#define ASSERT_HOST_MSG(x,...)
void ExtractFontProperties(const string &utf8_text, StringRenderer *render, const string &output_base)
bool MakeIndividualGlyphs(Pix *pix, const std::vector< BoxChar *> &vbox, const int input_tiff_page)
bool encodable_string(const char *str, int *first_bad_position) const
bool load_from_file(const char *const filename, bool skip_fragments)
Pix * DegradeImage(Pix *input, int exposure, TRand *randomizer, float *rotation)
void set_seed(uinT64 seed)
int SpanUTF8Whitespace(const char *text)
void ParseCommandLineFlags(const char *usage, int *argc, char ***argv, const bool remove_flags)