From 6cc206f5e4f734ba178c18e5a962563aace35018 Mon Sep 17 00:00:00 2001 From: David Hendricks Date: Sat, 6 Feb 2016 19:15:12 -0800 Subject: [PATCH] Add a command-line argument to set visible PDF image Fix issue #210. This adds an optional command-line argument to set the image which will be used when generating a PDF image. This addresses a niche case where the user wishes to use an optimized image for OCR but maintain the visual appearance of the original image when generating a PDF. Signed-off-by: David Hendricks --- api/baseapi.cpp | 32 ++++++++++++++++++++++++++++++++ api/baseapi.h | 6 ++++++ api/pdfrenderer.cpp | 14 +++++++++++++- api/tesseractmain.cpp | 9 +++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/api/baseapi.cpp b/api/baseapi.cpp index 13137c6a78..5e18ca311e 100644 --- a/api/baseapi.cpp +++ b/api/baseapi.cpp @@ -122,6 +122,8 @@ TessBaseAPI::TessBaseAPI() page_res_(NULL), input_file_(NULL), input_image_(NULL), + visible_pdf_image_file_(NULL), + visible_pdf_image_(NULL), output_file_(NULL), datapath_(NULL), language_(NULL), @@ -205,6 +207,14 @@ void TessBaseAPI::SetInputName(const char* name) { *input_file_ = name; } +void TessBaseAPI::SetVisiblePdfImageFilename(const char* name) { + if (visible_pdf_image_file_ == NULL) + visible_pdf_image_file_ = new STRING(name); + else + *visible_pdf_image_file_ = name; +} + + /** Set the name of the output files. Needed only for debugging. */ void TessBaseAPI::SetOutputName(const char* name) { if (output_file_ == NULL) @@ -941,16 +951,34 @@ void TessBaseAPI::SetInputImage(Pix *pix) { input_image_ = pixCopy(NULL, pix); } +void TessBaseAPI::SetVisiblePdfImage(Pix *pix) { + if (visible_pdf_image_) + pixDestroy(&visible_pdf_image_); + visible_pdf_image_ = NULL; + if (pix) + visible_pdf_image_ = pixCopy(NULL, pix); +} + Pix* TessBaseAPI::GetInputImage() { return input_image_; } +Pix* TessBaseAPI::GetVisiblePdfImage() { + return visible_pdf_image_; +} + const char * TessBaseAPI::GetInputName() { if (input_file_) return input_file_->c_str(); return NULL; } +const char * TessBaseAPI::GetVisiblePdfImageFilename() { + if (visible_pdf_image_file_) + return visible_pdf_image_file_->c_str(); + return NULL; +} + const char * TessBaseAPI::GetDatapath() { return tesseract_->datadir.c_str(); } @@ -1962,6 +1990,10 @@ void TessBaseAPI::End() { pixDestroy(&input_image_); input_image_ = NULL; } + if (visible_pdf_image_ != NULL) { + pixDestroy(&visible_pdf_image_); + visible_pdf_image_ = NULL; + } if (output_file_ != NULL) { delete output_file_; output_file_ = NULL; diff --git a/api/baseapi.h b/api/baseapi.h index d75fde9485..80b53ef520 100644 --- a/api/baseapi.h +++ b/api/baseapi.h @@ -146,6 +146,10 @@ class TESS_API TessBaseAPI { Pix* GetInputImage(); int GetSourceYResolution(); const char* GetDatapath(); + void SetVisiblePdfImageFilename(const char* name); + const char *GetVisiblePdfImageFilename(); + void SetVisiblePdfImage(Pix *pix); + Pix* GetVisiblePdfImage(); /** Set the name of the bonus output files. Needed only for debugging. */ void SetOutputName(const char* name); @@ -867,6 +871,8 @@ class TESS_API TessBaseAPI { PAGE_RES* page_res_; ///< The page-level data. STRING* input_file_; ///< Name used by training code. Pix* input_image_; ///< Image used for searchable PDF + STRING* visible_pdf_image_file_; + Pix* visible_pdf_image_; ///< Image used in output PDF STRING* output_file_; ///< Name used by debug code. STRING* datapath_; ///< Current location of tessdata. STRING* language_; ///< Last initialized language. diff --git a/api/pdfrenderer.cpp b/api/pdfrenderer.cpp index fd266085db..3f4a0e387b 100644 --- a/api/pdfrenderer.cpp +++ b/api/pdfrenderer.cpp @@ -823,9 +823,19 @@ bool TessPDFRenderer::imageToPDFObj(Pix *pix, bool TessPDFRenderer::AddImageHandler(TessBaseAPI* api) { size_t n; char buf[kBasicBufSize]; - Pix *pix = api->GetInputImage(); char *filename = (char *)api->GetInputName(); int ppi = api->GetSourceYResolution(); + Pix *pix; + int destroy_pix = 0; + + if (api->GetVisiblePdfImageFilename()) { + pix = pixRead(api->GetVisiblePdfImageFilename()); + api->SetVisiblePdfImage(pix); + destroy_pix = 1; + } else { + pix = api->GetInputImage(); + } + if (!pix || ppi <= 0) return false; double width = pixGetWidth(pix) * 72.0 / ppi; @@ -897,6 +907,8 @@ bool TessPDFRenderer::AddImageHandler(TessBaseAPI* api) { AppendData(pdf_object, objsize); AppendPDFObjectDIY(objsize); delete[] pdf_object; + if (destroy_pix) + pixDestroy(&pix); return true; } diff --git a/api/tesseractmain.cpp b/api/tesseractmain.cpp index db73d72174..8445401790 100644 --- a/api/tesseractmain.cpp +++ b/api/tesseractmain.cpp @@ -199,6 +199,7 @@ void ParseArgs(const int argc, char** argv, const char** image, const char** outputbase, const char** datapath, + const char **visible_pdf_image_file, bool* list_langs, bool* print_parameters, GenericVector* vars_vec, @@ -256,6 +257,9 @@ void ParseArgs(const int argc, char** argv, } else if (strcmp(argv[i], "-c") == 0 && i + 1 < argc) { // handled properly after api init ++i; + } else if (strcmp(argv[i], "--visible-pdf-image") == 0 && i + 1 < argc) { + *visible_pdf_image_file = argv[i + 1]; + ++i; } else if (*image == NULL) { *image = argv[i]; } else if (*outputbase == NULL) { @@ -340,6 +344,7 @@ int main(int argc, char **argv) { const char* image = NULL; const char* outputbase = NULL; const char* datapath = NULL; + const char *visible_pdf_image_file = NULL; bool list_langs = false; bool print_parameters = false; GenericVector vars_vec, vars_values; @@ -348,6 +353,7 @@ int main(int argc, char **argv) { ParseArgs(argc, argv, &lang, &image, &outputbase, &datapath, + &visible_pdf_image_file, &list_langs, &print_parameters, &vars_vec, &vars_values, &arg_i, &pagesegmode); @@ -380,6 +386,9 @@ int main(int argc, char **argv) { FixPageSegMode(&api, pagesegmode); + if (visible_pdf_image_file) + api.SetVisiblePdfImageFilename(visible_pdf_image_file); + if (pagesegmode == tesseract::PSM_AUTO_ONLY) { int ret_val = 0;