Version: digikam 0.9 svn (using KDE KDE 3.5.5) Installed from: SuSE RPMs OS: Linux In perspective correction tool there are no horzontal/vertical helper lines (the movable "cross" like in the other distortion or "free turning" tools). It would be a great help to have them here too.
SVN commit 624957 by cgilles: digikam from trunk : Perspective tool : - Add new option to draw a guide grid (15x15). - Fix Restore/Save settings between plugin sessions. CCMAIL: digikam-devel@kde.org BUG: 131170 BUG: 137545 M +20 -16 imageeffect_perspective.cpp M +4 -3 imageeffect_perspective.h M +231 -183 perspectivewidget.cpp M +7 -0 perspectivewidget.h
Hi Gilles, thanks for that - it looks like in a 3d-rendering app :-) but (although this grid is also helpful) my wish is different: I'd like to have a vertical/horizontal helper line, just the same as in "free rotation". It could also be the grid (if thats easier to solve) but having a switch to leave the grid unchanged while changing the angles of the image. The reason for my wish is: Often you use "Adjust Perspective" to correct horizontal and vertical lines that are tilted because of the view-position the picture was taken from. But when distorting an image it is not easy to see whether the lines in the image are really horizontal/vertical. I'll tinker an example picture to illustrate what I mean. Hope you don't mind, when I reopen this wish again :-) Daniel
Created attachment 19326 [details] a perspectively distorted image
Created attachment 19327 [details] using the perspective tool to correct distorted.jpg the red lines would help to make the horizontal/vertical lines in the image really vertical and horizontal, while when doing it just "by eye" it is almost impossible to get a correct result in this regard. (The sample is extreme but I hope it illustrates what I mean).
SVN commit 625037 by cgilles: digikam from trunk : Perspective Tool : add Horizontal/Vertical guide lines like with Free Rotation tool CCMAIL: digikam-devel@kde.org CCBUGS: 137545, 131170 M +37 -7 imageeffect_perspective.cpp M +7 -0 imageeffect_perspective.h M +58 -4 perspectivewidget.cpp M +12 -3 perspectivewidget.h --- trunk/extragear/graphics/digikamimageplugins/perspective/imageeffect_perspective.cpp #625036:625037 @@ -25,6 +25,7 @@ #include <qvgroupbox.h> #include <qlabel.h> +#include <qspinbox.h> #include <qpushbutton.h> #include <qwhatsthis.h> #include <qlayout.h> @@ -33,6 +34,7 @@ // KDE includes. +#include <kcolorbutton.h> #include <kcursor.h> #include <kconfig.h> #include <klocale.h> @@ -83,7 +85,7 @@ QFrame *frame = new QFrame(plainPage()); frame->setFrameStyle(QFrame::Panel|QFrame::Sunken); - QVBoxLayout* l = new QVBoxLayout(frame, 5, 0); + QVBoxLayout* l = new QVBoxLayout(frame, 5, 0); m_previewWidget = new PerspectiveWidget(525, 350, frame); l->addWidget(m_previewWidget); QWhatsThis::add( m_previewWidget, i18n("<p>This is the perspective transformation operation preview. " @@ -97,7 +99,7 @@ Digikam::ImageIface iface(0, 0); QWidget *gbox2 = new QWidget(plainPage()); - QGridLayout *gridLayout = new QGridLayout( gbox2, 11, 2, marginHint(), spacingHint()); + QGridLayout *gridLayout = new QGridLayout( gbox2, 13, 2, marginHint(), spacingHint()); QLabel *label1 = new QLabel(i18n("New width:"), gbox2); m_newWidthLabel = new QLabel(temp.setNum( iface.originalWidth()) + i18n(" px"), gbox2); @@ -148,8 +150,23 @@ m_drawGridCheckBox = new QCheckBox(i18n("Draw grid"), gbox2); gridLayout->addMultiCellWidget(m_drawGridCheckBox, 10, 10, 0, 2); - gridLayout->setRowStretch(11, 10); + // ------------------------------------------------------------- + QLabel *label7 = new QLabel(i18n("Guide color:"), gbox2); + m_guideColorBt = new KColorButton( QColor( Qt::red ), gbox2 ); + QWhatsThis::add( m_guideColorBt, i18n("<p>Set here the color used to draw guides dashed-lines.")); + gridLayout->addMultiCellWidget(label7, 11, 11, 0, 0); + gridLayout->addMultiCellWidget(m_guideColorBt, 11, 11, 2, 2); + + QLabel *label8 = new QLabel(i18n("Guide width:"), gbox2); + m_guideSize = new QSpinBox( 1, 5, 1, gbox2); + QWhatsThis::add( m_guideSize, i18n("<p>Set here the width in pixels used to draw guides dashed-lines.")); + gridLayout->addMultiCellWidget(label8, 12, 12, 0, 0); + gridLayout->addMultiCellWidget(m_guideSize, 12, 12, 2, 2); + + gridLayout->setColStretch(1, 10); + gridLayout->setRowStretch(13, 10); + setUserAreaWidget(gbox2); // ------------------------------------------------------------- @@ -158,10 +175,16 @@ this, SLOT(slotUpdateInfo(QRect, float, float, float, float))); connect(m_drawWhileMovingCheckBox, SIGNAL(toggled(bool)), - m_previewWidget, SLOT(toggleDrawWhileMoving(bool))); + m_previewWidget, SLOT(slotToggleDrawWhileMoving(bool))); connect(m_drawGridCheckBox, SIGNAL(toggled(bool)), - m_previewWidget, SLOT(toggleDrawGrid(bool))); + m_previewWidget, SLOT(slotToggleDrawGrid(bool))); + + connect(m_guideColorBt, SIGNAL(changed(const QColor &)), + m_previewWidget, SLOT(slotChangeGuideColor(const QColor &))); + + connect(m_guideSize, SIGNAL(valueChanged(int)), + m_previewWidget, SLOT(slotChangeGuideSize(int))); } ImageEffect_Perspective::~ImageEffect_Perspective() @@ -170,12 +193,17 @@ void ImageEffect_Perspective::readUserSettings(void) { + QColor defaultGuideColor(Qt::red); KConfig *config = kapp->config(); config->setGroup("perspective Tool Dialog"); m_drawWhileMovingCheckBox->setChecked(config->readBoolEntry("Draw While Moving", true)); m_drawGridCheckBox->setChecked(config->readBoolEntry("Draw Grid", false)); - m_previewWidget->toggleDrawWhileMoving(m_drawWhileMovingCheckBox->isChecked()); - m_previewWidget->toggleDrawGrid(m_drawGridCheckBox->isChecked()); + m_guideColorBt->setColor(config->readColorEntry("Guide Color", &defaultGuideColor)); + m_guideSize->setValue(config->readNumEntry("Guide Width", 1)); + m_previewWidget->slotToggleDrawWhileMoving(m_drawWhileMovingCheckBox->isChecked()); + m_previewWidget->slotToggleDrawGrid(m_drawGridCheckBox->isChecked()); + m_previewWidget->slotChangeGuideColor(m_guideColorBt->color()); + m_previewWidget->slotChangeGuideSize(m_guideSize->value()); } void ImageEffect_Perspective::writeUserSettings(void) @@ -184,6 +212,8 @@ config->setGroup("perspective Tool Dialog"); config->writeEntry("Draw While Moving", m_drawWhileMovingCheckBox->isChecked()); config->writeEntry("Draw Grid", m_drawGridCheckBox->isChecked()); + config->writeEntry("Guide Color", m_guideColorBt->color()); + config->writeEntry("Guide Width", m_guideSize->value()); config->sync(); } --- trunk/extragear/graphics/digikamimageplugins/perspective/imageeffect_perspective.h #625036:625037 @@ -32,7 +32,10 @@ class QLabel; class QCheckBox; +class QSpinBox; +class KColorButton; + namespace DigikamPerspectiveImagesPlugin { @@ -71,6 +74,10 @@ QCheckBox *m_drawWhileMovingCheckBox; QCheckBox *m_drawGridCheckBox; + QSpinBox *m_guideSize; + + KColorButton *m_guideColorBt; + PerspectiveWidget *m_previewWidget; }; --- trunk/extragear/graphics/digikamimageplugins/perspective/perspectivewidget.cpp #625036:625037 @@ -65,6 +65,8 @@ m_drawGrid = false; m_drawWhileMoving = true; m_currentResizing = ResizingNone; + m_guideColor = Qt::red; + m_guideSize = 1; m_iface = new Digikam::ImageIface(w, h); uchar *data = m_iface->setPreviewImageSize(w, h); @@ -168,6 +170,9 @@ m_bottomRightPoint.setX(m_w-1); m_bottomRightPoint.setY(m_h-1); + m_spot.setX(m_w / 2); + m_spot.setY(m_h / 2); + m_antiAlias = true; updatePixmap(); repaint(false); @@ -196,25 +201,39 @@ targetImg.bits(), targetImg.width(), targetImg.height()); } -void PerspectiveWidget::toggleAntiAliasing(bool a) +void PerspectiveWidget::slotToggleAntiAliasing(bool a) { m_antiAlias = a; updatePixmap(); repaint(false); } -void PerspectiveWidget::toggleDrawWhileMoving(bool draw) +void PerspectiveWidget::slotToggleDrawWhileMoving(bool draw) { m_drawWhileMoving = draw; } -void PerspectiveWidget::toggleDrawGrid(bool grid) +void PerspectiveWidget::slotToggleDrawGrid(bool grid) { m_drawGrid = grid; updatePixmap(); repaint(false); } +void PerspectiveWidget::slotChangeGuideColor(const QColor &color) +{ + m_guideColor = color; + updatePixmap(); + repaint(false); +} + +void PerspectiveWidget::slotChangeGuideSize(int size) +{ + m_guideSize = size; + updatePixmap(); + repaint(false); +} + void PerspectiveWidget::updatePixmap(void) { m_topLeftCorner.setRect(m_topLeftPoint.x() + m_rect.topLeft().x(), @@ -314,6 +333,17 @@ p.drawEllipse( m_transformedCenter.x()+m_rect.topLeft().x(), m_transformedCenter.y()+m_rect.topLeft().y(), 4, 4 ); + // Drawing vertical and horizontal guide lines. + + int xspot = m_spot.x() + m_rect.x(); + int yspot = m_spot.y() + m_rect.y(); + p.setPen(QPen(Qt::white, m_guideSize, Qt::SolidLine)); + p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom()); + p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot); + p.setPen(QPen(m_guideColor, m_guideSize, Qt::DotLine)); + p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom()); + p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot); + p.end(); emit signalPerspectiveChanged(getTargetSize(), getAngleTopLeft(), getAngleTopRight(), @@ -603,6 +633,9 @@ void PerspectiveWidget::resizeEvent(QResizeEvent * e) { + int old_w = m_w; + int old_h = m_h; + delete m_pixmap; int w = e->size().width(); int h = e->size().height(); @@ -629,6 +662,9 @@ m_transformedCenter = QPoint(lroundf(m_transformedCenter.x()*xFactor), lroundf(m_transformedCenter.y()*yFactor)); + m_spot.setX((int)((float)m_spot.x() * ( (float)m_w / (float)old_w))); + m_spot.setY((int)((float)m_spot.y() * ( (float)m_h / (float)old_h))); + updatePixmap(); } @@ -645,10 +681,15 @@ m_currentResizing = ResizingTopRight; else if ( m_bottomLeftCorner.contains( e->x(), e->y() ) ) m_currentResizing = ResizingBottomLeft; + else + { + m_spot.setX(e->x()-m_rect.x()); + m_spot.setY(e->y()-m_rect.y()); + } } } -void PerspectiveWidget::mouseReleaseEvent ( QMouseEvent * ) +void PerspectiveWidget::mouseReleaseEvent ( QMouseEvent * e ) { if ( m_currentResizing != ResizingNone ) { @@ -662,6 +703,13 @@ repaint(false); } } + else + { + m_spot.setX(e->x()-m_rect.x()); + m_spot.setY(e->y()-m_rect.y()); + updatePixmap(); + repaint(false); + } } void PerspectiveWidget::mouseMoveEvent ( QMouseEvent * e ) @@ -758,6 +806,12 @@ setCursor( KCursor::sizeFDiagCursor() ); } + else + { + m_spot.setX(e->x()-m_rect.x()); + m_spot.setY(e->y()-m_rect.y()); + } + updatePixmap(); repaint(false); } --- trunk/extragear/graphics/digikamimageplugins/perspective/perspectivewidget.h #625036:625037 @@ -30,6 +30,7 @@ #include <qwidget.h> #include <qpoint.h> +#include <qcolor.h> #include <qrect.h> // Digikam includes. @@ -77,10 +78,13 @@ public slots: - void toggleAntiAliasing(bool a); - void toggleDrawWhileMoving(bool draw); - void toggleDrawGrid(bool grid); + void slotToggleAntiAliasing(bool a); + void slotToggleDrawWhileMoving(bool draw); + void slotToggleDrawGrid(bool grid); + void slotChangeGuideColor(const QColor &color); + void slotChangeGuideSize(int size); + signals: void signalPerspectiveChanged( QRect newSize, float topLeftAngle, float topRightAngle, @@ -130,6 +134,8 @@ int m_currentResizing; + int m_guideSize; + QRect m_rect; // Tranformed center area for mouse position control. @@ -147,7 +153,10 @@ QPoint m_topRightPoint; QPoint m_bottomLeftPoint; QPoint m_bottomRightPoint; + QPoint m_spot; + QColor m_guideColor; + // 60 points will be stored to compute a grid of 15x15 lines. QPointArray m_grid;
perfect. thank you for this!