[SOLVED] Cursor and image coordinates(problem with scaling)
-
I modified it and now it looks like this:
@void ImageWidget::mousePressEvent( QMouseEvent * event )
{
double x = event->pos().x();
double y = event->pos().y();// Calculate scale and image sizes
double h = m_imageLabel->height();
double w = m_imageLabel->width();if(x>w || y>h)
return;if(h>size().height() || w>size().width())
{
m_scaleFactor = 1.0;
}x *= m_scaleFactor;
y *= m_scaleFactor;QRgb pixel = m_image.pixel(x,y);
QColor color = QColor::fromRgb(pixel);
}@ but I still have wrong coords(sometimes with some offset from right coords).
-
The whole source of ImageViever class is
*.cpp:
@#include "ImageWidget.h"//-----------------------------------------------------------------------------
ImageWidget::ImageWidget( QWidget * parent, const QString & filename ) : QWidget(parent)
{
m_imageLabel = new QLabel();
m_imageLabel->setBackgroundRole(QPalette::Base);
m_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
m_imageLabel->setScaledContents(true);m_scrollArea = new QScrollArea(this);
m_scrollArea->setBackgroundRole(QPalette::Dark);
m_scrollArea->setWidget(m_imageLabel);QVBoxLayout * layout = new QVBoxLayout();
layout->addWidget(m_scrollArea);
setLayout(layout);setWindowTitle(filename);
resize(500, 400);// open file
m_image = QImage(filename);
if (m_image.isNull()) {
QMessageBox::information(this, tr("Warning"),
tr("Cannot load %1.").arg(filename));
return;
}m_imageLabel->setPixmap(QPixmap::fromImage(m_image));
m_scaleFactor = 1.0;
normalSize();m_pixelatorFlag = false;
//connect(parent->ui.actionPixelator, SIGNAL(triggered()), this, SLOT(pixelatorOn()));
}
//-----------------------------------------------------------------------------
void ImageWidget::zoomIn()
{scaleImage(1.25);
}
//-----------------------------------------------------------------------------
void ImageWidget::zoomOut()
{
scaleImage(0.8);
}
//-----------------------------------------------------------------------------
void ImageWidget::normalSize()
{
m_imageLabel->adjustSize();
m_scaleFactor = 1.0;
}
//-----------------------------------------------------------------------------
void ImageWidget::fitToWindow( bool fitToWindow )
{
m_scrollArea->setWidgetResizable(fitToWindow);
if (!fitToWindow) {
normalSize();
}
}
//-----------------------------------------------------------------------------
void ImageWidget::scaleImage( double factor )
{
Q_ASSERT(m_imageLabel->pixmap());
m_scaleFactor *= factor;
m_imageLabel->resize(m_scaleFactor * m_imageLabel->pixmap()->size());adjustScrollBar(m_scrollArea->horizontalScrollBar(), factor);
adjustScrollBar(m_scrollArea->verticalScrollBar(), factor);
}
//-----------------------------------------------------------------------------
void ImageWidget::adjustScrollBar( QScrollBar *scrollBar, double factor )
{
scrollBar->setValue(int(factor * scrollBar->value()- ((factor - 1) * scrollBar->pageStep()/2)));
}
//-----------------------------------------------------------------------------
void ImageWidget::mousePressEvent( QMouseEvent * event )
{
double x = event->pos().x();
double y = event->pos().y();
// Calculate scale and image sizes
double h = m_imageLabel->height();
double w = m_imageLabel->width();if(x>w || y>h)
return;if(h>size().height() || w>size().width())
{
m_scaleFactor = 1.0;
}x *= m_scaleFactor;
y *= m_scaleFactor;QRgb pixel = m_image.pixel(x,y);
QColor color = QColor::fromRgb(pixel);
emit colorSelected(color.name(),x,y);
proccessImage(color,false);
}
//-----------------------------------------------------------------------------
void ImageWidget::proccessImage(QColor color, bool inverse)
{
// Search algorithmQImage image = m_image;
int difference = 20;for(int y = 0; y < image.height(); y++)
{
for(int x = 0; x < image.width(); x++)
{
QRgb currentPixel = image.pixel(x,y);if( qAbs(qRed(currentPixel) - color.red()) > difference &&
qAbs(qGreen(currentPixel) - color.green()) > difference &&
qAbs(qBlue(currentPixel) - color.blue()) > difference)
{
if(!inverse)
image.setPixel(x,y,qRgb(255,255,255));
}
else
{
if(inverse)
image.setPixel(x,y,qRgb(255,255,255));
}
}
}
m_imageLabel->setPixmap(QPixmap::fromImage(image));
}
//-----------------------------------------------------------------------------
void ImageWidget::pixelatorOn()
{
// QAction * act = (QAction *)QObject::sender();
//
// if(act == NULL)
// return;
//
// if(act->isChecked())
// m_pixelatorFlag = true;
// else
// m_pixelatorFlag = false;
}
//-----------------------------------------------------------------------------
@
*.h:
@#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H#include <QWidget>
#include <QScrollBar>
#include <QScrollArea>
#include <QLabel>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QColor>class ImageWidget : public QWidget
{
Q_OBJECTQLabel *m_imageLabel;
QScrollArea *m_scrollArea;
double m_scaleFactor;
QImage m_image;
bool m_pixelatorFlag;public:
ImageWidget(QWidget * parent, const QString & filename);
void zoomIn();
void zoomOut();
void normalSize();
void fitToWindow(bool fitToWindow);private:
void scaleImage(double factor);
void adjustScrollBar(QScrollBar *scrollBar, double factor);
void proccessImage(QColor color, bool inverse);protected:
void mousePressEvent(QMouseEvent * event);public slots:
void pixelatorOn();signals:
void colorSelected(const QString & color, int x, int y);};
#endif//IMAGEWIDGET_H
@Maybe I miss something when editing qt example and thats why I get wrong coords ?
- ((factor - 1) * scrollBar->pageStep()/2)));
-
Same trouble after some modificatin. When zoomOut and then make a click. Coordinates moved up left from real position, and after zoomOut its moved down right. Changed code looks like this:
*.h
@#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H#include <QWidget>
#include <QScrollBar>
#include <QScrollArea>
#include <QLabel>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QColor>
#include <QGraphicsItem>enum curAction {ePixel, eErase, eNoact};
class ImageWidget : public QWidget
{
Q_OBJECTQLabel *m_imageLabel;
QScrollArea *m_scrollArea;
double m_scaleFactor;
QImage m_image;
bool m_pixelatorFlag;
int m_difference;
QColor m_currentColor;
curAction m_action;public:
ImageWidget(QWidget * parent, const QString & filename);
void zoomIn();
void zoomOut();
void normalSize();
void fitToWindow(bool fitToWindow);
void setCurrentAction(curAction action);private:
void scaleImage(double factor);
void adjustScrollBar(QScrollBar *scrollBar, double factor);
void proccessImage(QColor color, bool inverse);
void eraseImage(const QPointF & startPoint,const QPointF & endPoint);
void revertChanges();protected:
void mousePressEvent(QMouseEvent * event);
void keyPressEvent (QKeyEvent * event);public slots:
void onChangeDifference(int difference);signals:
void colorSelected(const QString & color, int x, int y);};
#endif//IMAGEWIDGET_H
@ -
*.cpp
@#include "ImageWidget.h"//-----------------------------------------------------------------------------
ImageWidget::ImageWidget( QWidget * parent, const QString & filename ) : QWidget(parent)
{
m_imageLabel = new QLabel();
m_imageLabel->setBackgroundRole(QPalette::Base);
m_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
m_imageLabel->setScaledContents(true);m_scrollArea = new QScrollArea(this);
m_scrollArea->setBackgroundRole(QPalette::Dark);
m_scrollArea->setWidget(m_imageLabel);QVBoxLayout * layout = new QVBoxLayout();
layout->addWidget(m_scrollArea);
setLayout(layout);setWindowTitle(filename);
resize(500, 400);// open file
m_image = QImage(filename);
if (m_image.isNull()) {
QMessageBox::information(this, tr("Warning"),
tr("Cannot load %1.").arg(filename));
return;
}m_imageLabel->setPixmap(QPixmap::fromImage(m_image));
m_scaleFactor = 1.0;
normalSize();m_pixelatorFlag = false;
//connect(parent->ui.actionPixelator, SIGNAL(triggered()), this, SLOT(pixelatorOn()));
m_difference = 20;
m_currentColor = Qt::black;
}
//-----------------------------------------------------------------------------
void ImageWidget::zoomIn()
{scaleImage(1.25);
}
//-----------------------------------------------------------------------------
void ImageWidget::zoomOut()
{
scaleImage(0.8);
}
//-----------------------------------------------------------------------------
void ImageWidget::normalSize()
{
m_imageLabel->adjustSize();
m_scaleFactor = 1.0;
}
//-----------------------------------------------------------------------------
void ImageWidget::fitToWindow( bool fitToWindow )
{
m_scrollArea->setWidgetResizable(fitToWindow);
if (!fitToWindow) {
normalSize();
}
}
//-----------------------------------------------------------------------------
void ImageWidget::scaleImage( double factor )
{
Q_ASSERT(m_imageLabel->pixmap());
m_scaleFactor *= factor;
m_imageLabel->resize(m_scaleFactor * m_imageLabel->pixmap()->size());adjustScrollBar(m_scrollArea->horizontalScrollBar(), factor);
adjustScrollBar(m_scrollArea->verticalScrollBar(), factor);
}
//-----------------------------------------------------------------------------
void ImageWidget::adjustScrollBar( QScrollBar *scrollBar, double factor )
{
scrollBar->setValue(int(factor * scrollBar->value()- ((factor - 1) * scrollBar->pageStep()/2)));
}
//-----------------------------------------------------------------------------
void ImageWidget::mousePressEvent( QMouseEvent * event )
{
QPointF pos = m_imageLabel->mapFromParent(event->pos());
double x = pos.x();
double y = pos.y();// Calculate scale and image sizes
double h = m_imageLabel->height();
double w = m_imageLabel->width();if(x>w || y>h)
return;if(h>size().height() || w>size().width())
{
m_scaleFactor = 1.0;
}x *= m_scaleFactor;
y *= m_scaleFactor;pos = QPointF(x,y);
QRgb pixel = m_image.pixel(x,y);
m_currentColor = QColor::fromRgb(pixel);
emit colorSelected(m_currentColor.name(),x,y);
switch (m_action)
{
case ePixel:
proccessImage(m_currentColor,false);
break;
case eErase:
eraseImage(pos, QPointF(pos.x()+50,pos.y()+50));
break;
case eNoact:
break;
}
}
//-----------------------------------------------------------------------------
void ImageWidget::keyPressEvent( QKeyEvent * event )
{
switch(event->key())
{
case Qt::Key_Z:
{
if(event->modifiers() == Qt::ControlModifier)
revertChanges();
}
break;
default:
QWidget::keyPressEvent(event);
}
}
//-----------------------------------------------------------------------------
void ImageWidget::proccessImage(QColor color, bool inverse)
{
// Search algorithmQImage image = m_image;
for(int y = 0; y < image.height(); y++)
{
for(int x = 0; x < image.width(); x++)
{
QRgb currentPixel = image.pixel(x,y);if( qAbs(qRed(currentPixel) - color.red()) > m_difference &&
qAbs(qGreen(currentPixel) - color.green()) > m_difference &&
qAbs(qBlue(currentPixel) - color.blue()) > m_difference)
{
if(!inverse)
image.setPixel(x,y,qRgb(255,255,255));
}
else
{
if(inverse)
image.setPixel(x,y,qRgb(255,255,255));
}
}
}
m_imageLabel->setPixmap(QPixmap::fromImage(image));// QMessageBox::information(this, tr("Done"),
// tr("Processing image done.n"
// "The document has been modified."),
// QMessageBox::Ok);
}
//-----------------------------------------------------------------------------
void ImageWidget::eraseImage( const QPointF & startPoint,const QPointF & endPoint )
{
QImage image = m_image;for(int y = 0; y < image.height(); y++)
for(int x = 0; x < image.width(); x++)
if(y > startPoint.y() && y < endPoint.y())
if(x > startPoint.x() && x<endPoint.x())
image.setPixel(x,y,qRgb(255,255,255));m_imageLabel->setPixmap(QPixmap::fromImage(image));
m_image = image;
}
//-----------------------------------------------------------------------------
void ImageWidget::revertChanges()
{
QImage image = m_imageLabel->pixmap()->toImage();m_imageLabel->setPixmap(QPixmap::fromImage(m_image));
m_image = image;
}
//-----------------------------------------------------------------------------
void ImageWidget::onChangeDifference(int difference)
{
m_difference = difference;
//proccessImage(m_currentColor,false);
}
//-----------------------------------------------------------------------------
void ImageWidget::setCurrentAction( curAction action )
{
m_action = action;
}
//-----------------------------------------------------------------------------
@ - ((factor - 1) * scrollBar->pageStep()/2)));
-
I done this:
make m_scalefactor double;
When zoom in 0,8;
when zoom out 1,25;if(h>size().height() || w>size().width())
{
m_scaleFactor = 1.0;
}But I still have wrong coords in mouse press event x and y if I already make zomming, without zumming it's work correct. Please check somebody my code and make some corrections or recommendations.