Skip to content

Commit

Permalink
Allow renderer caller to specify custom image and resolution to render.
Browse files Browse the repository at this point in the history
#fixes 210
#fixes 3798
  • Loading branch information
phymbert committed Dec 17, 2023
1 parent ea0b245 commit 842f8d0
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 2 deletions.
28 changes: 28 additions & 0 deletions include/tesseract/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ class TESS_API TessResultRenderer {
return imagenum_;
}

/**
* Allow the caller to choose alternate image to render with the extracted text.
* It must be called after BeginDocument and before AddImage methods.
*/
void SetRenderingImage(Pix *rendering_image) {
rendering_image_ = rendering_image;
}

/**
* Allow the caller to specify the target rendering resolution.
* If not set, rendering_dpi api params will be used.
*/
void SetRenderingResolution(int rendering_dpi) {
rendering_dpi_ = rendering_dpi;
}

protected:
/**
* Called by concrete classes.
Expand Down Expand Up @@ -139,13 +155,25 @@ class TESS_API TessResultRenderer {
// This method will grow the output buffer if needed.
void AppendData(const char *s, int len);

// Renderers can call this to get the actual image to render with extracted text.
// This method returns:
// - the rendering image set by the caller or
// - the input image scaled to the rendering_dpi field if defined or
// - the input image from the api otherwise
Pix* GetRenderingImage(TessBaseAPI *api);

// Resolution of the rendering image either set manually by the caller or with the rendering_dpi api parameter.
int GetRenderingResolution(TessBaseAPI *api);

private:
TessResultRenderer *next_; // Can link multiple renderers together
FILE *fout_; // output file pointer
const char *file_extension_; // standard extension for generated output
std::string title_; // title of document being rendered
int imagenum_; // index of last image added
bool happy_; // I get grumpy when the disk fills up, etc.
Pix *rendering_image_; // Image to render with the extracted text
int rendering_dpi_; // Resolution of the rendering_image
};

/**
Expand Down
4 changes: 2 additions & 2 deletions src/api/pdfrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,9 +809,9 @@ bool TessPDFRenderer::imageToPDFObj(Pix *pix, const char *filename, long int obj
}

bool TessPDFRenderer::AddImageHandler(TessBaseAPI *api) {
Pix *pix = api->GetInputImage();
Pix *pix = GetRenderingImage(api);
const char *filename = api->GetInputName();
int ppi = api->GetSourceYResolution();
int ppi = GetRenderingResolution(api);
if (!pix || ppi <= 0) {
return false;
}
Expand Down
58 changes: 58 additions & 0 deletions src/api/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
#ifdef HAVE_CONFIG_H
# include "config_auto.h"
#endif
#include <allheaders.h>
#include <tesseract/baseapi.h>
#include <tesseract/renderer.h>
#include <cstring>
#include <memory> // std::unique_ptr
#include <string> // std::string
#include "serialis.h" // Serialize
#include "tprintf.h"

namespace tesseract {

Expand Down Expand Up @@ -90,13 +92,69 @@ bool TessResultRenderer::AddImage(TessBaseAPI *api) {
return false;
}
++imagenum_;
Pix *rendering_image = rendering_image_;
int rendering_dpi = rendering_dpi_;
bool ok = AddImageHandler(api);
if (rendering_image_ != rendering_image) {
delete rendering_image_;
rendering_image_ = rendering_image;
}
if (rendering_dpi_ != rendering_dpi) {
rendering_dpi_ = rendering_dpi;
}
if (next_) {
ok = next_->AddImage(api) && ok;
}
return ok;
}

Pix* TessResultRenderer::GetRenderingImage(TessBaseAPI *api) {
if (!happy_) {
return nullptr;
}
if (!rendering_image_) {
Pix *input_image = api->GetInputImage();
int source_dpi = api->GetSourceYResolution();
if (!input_image || source_dpi <= 0) {
happy_ = false;
return nullptr;
}

int rendering_dpi = GetRenderingResolution(api);
if (rendering_dpi != source_dpi) {
float scale = (float)rendering_dpi / (float)source_dpi;

rendering_image_ = pixScale(input_image, scale, scale);
} else {
return input_image;
}
}
return rendering_image_;
}

int TessResultRenderer::GetRenderingResolution(tesseract::TessBaseAPI *api) {
if (rendering_dpi_) {
return rendering_dpi_;
}
int source_dpi = api->GetSourceYResolution();
int rendering_dpi;
if (api->GetIntVariable("rendering_dpi", &rendering_dpi) &&
rendering_dpi > 0 && rendering_dpi != source_dpi) {
if (rendering_dpi < kMinCredibleResolution ||
rendering_dpi > kMaxCredibleResolution) {
#if !defined(NDEBUG)
tprintf(
"Warning: User defined rendering dpi %d is outside of expected range "
"(%d - %d)!\n",
rendering_dpi, kMinCredibleResolution, kMaxCredibleResolution);
#endif
}
rendering_dpi_ = rendering_dpi;
return rendering_dpi_;
}
return source_dpi;
}

bool TessResultRenderer::EndDocument() {
if (!happy_) {
return false;
Expand Down
1 change: 1 addition & 0 deletions src/ccmain/tesseractclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ Tesseract::Tesseract()
, BOOL_MEMBER(textonly_pdf, false, "Create PDF with only one invisible text layer",
this->params())
, INT_MEMBER(jpg_quality, 85, "Set JPEG quality level", this->params())
, INT_MEMBER(rendering_dpi, 0, "Scale input image resolution for rendering", this->params())
, INT_MEMBER(user_defined_dpi, 0, "Specify DPI for input image", this->params())
, INT_MEMBER(min_characters_to_try, 50, "Specify minimum characters to try during OSD",
this->params())
Expand Down
1 change: 1 addition & 0 deletions src/ccmain/tesseractclass.h
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ class TESS_API Tesseract : public Wordrec {
BOOL_VAR_H(tessedit_create_pdf);
BOOL_VAR_H(textonly_pdf);
INT_VAR_H(jpg_quality);
INT_VAR_H(rendering_dpi);
INT_VAR_H(user_defined_dpi);
INT_VAR_H(min_characters_to_try);
STRING_VAR_H(unrecognised_char);
Expand Down

0 comments on commit 842f8d0

Please sign in to comment.