Add a 'Stamp' widget.
Place one or multiple stamps on scanned pages in defined locations. A stamp is understood here as - a transparent text in a transparent frame with no borders - an opaque text on an opaque background with no borders. Stamp parameters: - text - font - foreground colour - background colour - angle of rotation - transparency. Locations: - centre - cardinal directions - inter-cardinal directions.
This commit is contained in:
121
Resources/StampWidget/StampWorker.cpp
Normal file
121
Resources/StampWidget/StampWorker.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
// /*
|
||||
// * File: StampWorker.cpp
|
||||
// * Author: Saleem Edah-Tally - nmset@yandex.com
|
||||
// * License : CeCILL-C
|
||||
// * Copyright Saleem Edah-Tally - © 2025
|
||||
// *
|
||||
// * Created on 02 07 2025, 21:23
|
||||
// */
|
||||
|
||||
#include "StampWorker.h"
|
||||
#include <math.h> // M_PI
|
||||
|
||||
wxImage StampWorker::CreateStamp(StampDescriptor * descriptor, int scanResolution)
|
||||
{
|
||||
/*
|
||||
* Rescale the font point size of the stamp according to the scan resolution.
|
||||
* Exclude rescaling on v4l that does not have a resolution parameter.
|
||||
*/
|
||||
wxFont dcFont(descriptor->font);
|
||||
double scale = (scanResolution > 0)
|
||||
? (double) scanResolution / 72.0
|
||||
:1.0;
|
||||
|
||||
wxCoord extentWidth, extentHeight, textLineHeight;
|
||||
{
|
||||
wxMemoryDC dc;
|
||||
if (scale != 1.0)
|
||||
dcFont.SetFractionalPointSize(descriptor->font.GetFractionalPointSize() * scale);
|
||||
dc.SetFont(dcFont); // Mandatory despite set below.
|
||||
dc.GetMultiLineTextExtent(descriptor->text, &extentWidth, &extentHeight, &textLineHeight, &dcFont);
|
||||
}
|
||||
wxBitmap bmp;
|
||||
// bmp.UseAlpha(true); // Not mandatory.
|
||||
bmp.Create(extentWidth, extentHeight); // Memo: See CreateWithDIPSize
|
||||
wxImage img0, img;
|
||||
|
||||
wxMemoryDC dc(bmp);
|
||||
dc.SetFont(dcFont);
|
||||
if (descriptor->transparent)
|
||||
{
|
||||
// +++, Use the red channel only: used by ConvertColourToAlpha().
|
||||
// The chosen value is inversely proportional to the transparency of the text itself.
|
||||
dc.SetTextForeground(wxColour(128, 0, 0)); // A good mean is reasonable.
|
||||
dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.SetTextForeground(descriptor->foregroundColour);
|
||||
dc.SetTextBackground(descriptor->backgroundColour);
|
||||
dc.SetBackgroundMode(wxBRUSHSTYLE_SOLID);
|
||||
}
|
||||
|
||||
dc.DrawText(descriptor->text, wxPoint(0, 0));
|
||||
|
||||
img0 = bmp.ConvertToImage();
|
||||
if (!descriptor->transparent)
|
||||
img0.InitAlpha(); // So that there is no dark surrounding if it is rotated.
|
||||
|
||||
img = img0.Rotate((M_PI / 180.0) * descriptor->rotationAngle, wxPoint(0, 0));
|
||||
if (descriptor->transparent)
|
||||
{
|
||||
img.ConvertColourToAlpha(descriptor->foregroundColour.GetRed(),
|
||||
descriptor->foregroundColour.GetGreen(),
|
||||
descriptor->foregroundColour.GetBlue()); // The target colour is passed in.
|
||||
img.ChangeSaturation(-0.7); // Slightly better looking.
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void StampWorker::StampBackground(wxImage& background,
|
||||
const wxImage& stamp, int location)
|
||||
{
|
||||
// Simply pasting the stamp on the background, i.e., the scanned page.
|
||||
wxPoint bgCentre(background.GetWidth() / 2, background.GetHeight() / 2);
|
||||
wxPoint stampCentre(stamp.GetWidth() / 2, stamp.GetHeight() / 2);
|
||||
int x = 0, y = 0;
|
||||
switch (location)
|
||||
{
|
||||
case NORTH:
|
||||
x = bgCentre.x - stampCentre.x;
|
||||
y = 0;
|
||||
break;
|
||||
case SOUTH:
|
||||
x = bgCentre.x - stampCentre.x;
|
||||
y = background.GetHeight() - stamp.GetHeight();
|
||||
break;
|
||||
case EAST:
|
||||
x = background.GetWidth() - stamp.GetWidth();
|
||||
y = bgCentre.y - stampCentre.y;
|
||||
break;
|
||||
case WEST:
|
||||
x = 0;
|
||||
y = bgCentre.y - stampCentre.y;
|
||||
break;
|
||||
case NORTH_EAST:
|
||||
x = background.GetWidth() - stamp.GetWidth();
|
||||
y = 0;
|
||||
break;
|
||||
case NORTH_WEST:
|
||||
x = 0;
|
||||
y = 0;
|
||||
break;
|
||||
case SOUTH_EAST:
|
||||
x = background.GetWidth() - stamp.GetWidth();
|
||||
y = background.GetHeight() - stamp.GetHeight();
|
||||
break;
|
||||
case SOUTH_WEST:
|
||||
x = 0;
|
||||
y = background.GetHeight() - stamp.GetHeight();
|
||||
break;
|
||||
default: // CENTRE
|
||||
x = bgCentre.x - stampCentre.x;
|
||||
y = bgCentre.y - stampCentre.y;
|
||||
break;
|
||||
}
|
||||
|
||||
wxPoint stampLocation(x, y);
|
||||
background.Paste(stamp, stampLocation.x, stampLocation.y, wxIMAGE_ALPHA_BLEND_COMPOSE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user