1
0
This commit is contained in:
Jarosław Wieczorek 2021-04-06 23:20:11 +02:00
parent 90fb90b2a8
commit e1cc7ef031
2 changed files with 198 additions and 201 deletions

View File

@ -685,8 +685,7 @@ void Tools::setViewer(ImageViewer* iv)
m_iv = iv; m_iv = iv;
} }
bool Tools::SupportedImageFormat(ImageViewer* iv, bool Tools::SupportedImageFormat(ImageViewer* iv, QList<QImage::Format> formats)
QList<QImage::Format> formats)
{ {
if (!iv) if (!iv)
return false; return false;

View File

@ -1,199 +1,197 @@
#include "transformation.h" #include "transformation.h"
Transformation::Transformation(PNM* image) : Transformation::Transformation(PNM* image) :
QThread(0) QThread(0)
{ {
parameters = new QHash<QString, QVariant>; parameters = new QHash<QString, QVariant>;
this->image = image; this->image = image;
this->supervisor = 0; this->supervisor = 0;
} }
Transformation::Transformation(PNM* image, ImageViewer* iv) : Transformation::Transformation(PNM* image, ImageViewer* iv) :
QThread(0) QThread(0)
{ {
parameters = new QHash<QString, QVariant>; parameters = new QHash<QString, QVariant>;
this->image = image; this->image = image;
this->supervisor = iv; this->supervisor = iv;
if (iv) if (iv)
{ {
connect(this, SIGNAL(started()), iv, SLOT(transformationStarted())); connect(this, SIGNAL(started()), iv, SLOT(transformationStarted()));
connect(this, SIGNAL(finished()), iv, SLOT(transformationFinished())); connect(this, SIGNAL(finished()), iv, SLOT(transformationFinished()));
connect(this, SIGNAL(message(QString)), iv, SLOT(toolMessage(QString))); connect(this, SIGNAL(message(QString)), iv, SLOT(toolMessage(QString)));
connect(this, SIGNAL(progress(int)), iv, SLOT(toolProgress(int))); connect(this, SIGNAL(progress(int)), iv, SLOT(toolProgress(int)));
connect(this, SIGNAL(resultReady(PNM*)), iv, SLOT(updateImage(PNM*))); connect(this, SIGNAL(resultReady(PNM*)), iv, SLOT(updateImage(PNM*)));
connect(this, SIGNAL(finished()), iv, SLOT(toolFinished())); connect(this, SIGNAL(finished()), iv, SLOT(toolFinished()));
} }
} }
Transformation::~Transformation() Transformation::~Transformation()
{ {
delete parameters; delete parameters;
if (supervisor) if (supervisor)
{ {
disconnect(this, SIGNAL(started())); disconnect(this, SIGNAL(started()));
disconnect(this, SIGNAL(message(QString))); disconnect(this, SIGNAL(message(QString)));
disconnect(this, SIGNAL(progress(int))); disconnect(this, SIGNAL(progress(int)));
disconnect(this, SIGNAL(resultReady(PNM*))); disconnect(this, SIGNAL(resultReady(PNM*)));
disconnect(this, SIGNAL(finished())); disconnect(this, SIGNAL(finished()));
} }
} }
/** Sets a parameter param of the transformation /** Sets a parameter param of the transformation
* with the value. * with the value.
* If the parameter was already set it is overridden * If the parameter was already set it is overridden
* Returns the pointer to the Transformation object so it can be used as a factory. * Returns the pointer to the Transformation object so it can be used as a factory.
*/ */
Transformation* Transformation::setParameter(QString param, QVariant value) Transformation* Transformation::setParameter(QString param, QVariant value)
{ {
parameters->insert(param, value); parameters->insert(param, value);
return this; return this;
} }
/** Returns the value of the given param. /** Returns the value of the given param.
* If the param isn't set returns a default QVariant() * If the param isn't set returns a default QVariant()
* which is an invalid variant * which is an invalid variant
* @see QVariant::QVariant() * @see QVariant::QVariant()
*/ */
QVariant Transformation::getParameter(QString param) QVariant Transformation::getParameter(QString param)
{ {
return parameters->value(param, QVariant()); return parameters->value(param, QVariant());
} }
void Transformation::run() void Transformation::run()
{ {
PNM* image = this->transform(); PNM* image = this->transform();
emit resultReady(image); emit resultReady(image);
} }
/** /**
* /virtual, abstract!/ * /virtual, abstract!/
* Virtual method that do some transformations (based on parameter Hash) * Virtual method that do some transformations (based on parameter Hash)
* in the Transformation class it returns a pointer to * in the Transformation class it returns a pointer to
* the loaded image or a new null PNM image * the loaded image or a new null PNM image
*/ */
PNM* Transformation::transform() PNM* Transformation::transform()
{ {
if (image) if (image)
return image; return image;
else else
return new PNM(); return new PNM();
} }
/** Returns a pointer to the image stored in the class */ /** Returns a pointer to the image stored in the class */
PNM* Transformation::getImage() PNM* Transformation::getImage()
{ {
return image; return image;
} }
/** Returns a pixel value at given coordinates using different modes */ /** Returns a pixel value at given coordinates using different modes */
QRgb Transformation::getPixel(int x, int y, Mode mode) QRgb Transformation::getPixel(int x, int y, Mode mode)
{ {
switch (mode) { switch (mode) {
case CyclicEdge: return getPixelCyclic(x,y); case CyclicEdge: return getPixelCyclic(x,y);
case NullEdge: return getPixelNull(x,y); case NullEdge: return getPixelNull(x,y);
case RepeatEdge: return getPixelRepeat(x,y); case RepeatEdge: return getPixelRepeat(x,y);
default: return image->pixel(x,y); default: return image->pixel(x,y);
} }
} }
/** Returns a pixel using the Cyclic mode: /** Returns a pixel using the Cyclic mode:
* pixel(x,y) = pixel(x%width, y%width); * pixel(x,y) = pixel(x%width, y%width);
*/ */
QRgb Transformation::getPixelCyclic(int x, int y) QRgb Transformation::getPixelCyclic(int x, int y)
{ {
int width = image->width(); int width = image->width();
int height = image->height(); int height = image->height();
// Return a pixel by looping the image // Return a pixel by looping the image
x = x % width; x = x % width;
y = y % height; y = y % height;
// Return pixel // Return pixel
return image->pixel(x,y); return image->pixel(x,y);
} }
/** /**
* Returns a given pixel * Returns a given pixel
* If the pixel is out of image boundaries Black is returned; * If the pixel is out of image boundaries Black is returned;
*/ */
QRgb Transformation::getPixelNull(int x, int y) QRgb Transformation::getPixelNull(int x, int y)
{ {
int width = image->width(); int width = image->width();
int height = image->height(); int height = image->height();
// Return black as a pixel when out of range // Return black as a pixel when out of range
if (x > width || x < 0 || y > height || y < 0){ if (x > width || x < 0 || y > height || y < 0){
return Qt::black; return Qt::black;
} }
// Return pixel // Return pixel
return image->pixel(x,y); return image->pixel(x,y);
} }
/** /**
* Returns given pixel. * Returns given pixel.
* If the pixel is out of image boundaries * If the pixel is out of image boundaries
* the nearest edge pixel is given * the nearest edge pixel is given
*/ */
QRgb Transformation::getPixelRepeat(int x, int y) QRgb Transformation::getPixelRepeat(int x, int y)
{ {
int width = image->width(); int width = image->width();
int height = image->height(); int height = image->height();
// Copy nearest edge pixel // Copy nearest edge pixel
if (x<0 && y<0) return image->pixel(0,0); if (x<0 && y<0) return image->pixel(0,0);
else if (x>=width && y<0) return image->pixel(width-1,0); else if (x>=width && y<0) return image->pixel(width-1,0);
else if (x>=width && y>=height) return image->pixel(width-1,height-1); else if (x>=width && y>=height) return image->pixel(width-1,height-1);
else if (x<0 && y>=height) return image->pixel(0,height-1); else if (x<0 && y>=height) return image->pixel(0,height-1);
else if (x<0) return image->pixel(0,y); else if (x<0) return image->pixel(0,y);
else if (y<0) return image->pixel(x,0); else if (y<0) return image->pixel(x,0);
else if (x>=width) return image->pixel(width-1,y); else if (x>=width) return image->pixel(width-1,y);
else if (y>=height) return image->pixel(x,height-1); else if (y>=height) return image->pixel(x,height-1);
else return image->pixel(x,y); else return image->pixel(x,y);
return image->pixel(x,y); return image->pixel(x,y);
} }
/** Returns a size x size part of the image centered around (x,y) */ /** Returns a size x size part of the image centered around (x,y) */
math::matrix<float> Transformation::getWindow(int x, int y, int size, math::matrix<float> Transformation::getWindow(int x, int y, int size, Channel channel, Mode mode = RepeatEdge)
Channel channel, {
Mode mode = RepeatEdge) math::matrix<float> window(size,size);
{
math::matrix<float> window(size,size); // Calculate center
int center = size/2;
// Calculate center
int center = size/2; // Get window
for (int i=0; i < size; i++)
// Get window {
for (int i=0; i < size; i++) for (int j=0; j < size; j++)
{ {
for (int j=0; j < size; j++) QRgb pixelVal = getPixel(x-center+i, y-center+j, mode);
{ if (channel == RChannel)
QRgb pixelVal = getPixel(x-center+i, y-center+j, mode); {
if (channel == RChannel) window[i][j] = qRed(pixelVal);
{ }
window[i][j] = qRed(pixelVal); else if (channel == GChannel)
} {
else if (channel == GChannel) window[i][j] = qGreen(pixelVal);
{ }
window[i][j] = qGreen(pixelVal); else if (channel == BChannel)
} {
else if (channel == BChannel) window[i][j] = qBlue(pixelVal);
{ }
window[i][j] = qBlue(pixelVal); else if (channel == LChannel)
} {
else if (channel == LChannel) window[i][j] = qGray(pixelVal);
{ }
window[i][j] = qGray(pixelVal); }
} }
} return window;
} }
return window;
} ImageViewer* Transformation::getSupervisor()
{
ImageViewer* Transformation::getSupervisor() return supervisor;
{ }
return supervisor;
}