Bug 137545

Summary: helper lines / cross wanted
Product: [Applications] digikam Reporter: Daniel Bauer <linux>
Component: Plugin-Editor-PerspectiveAssignee: Digikam Developers <digikam-bugs-null>
Status: RESOLVED WORKSFORME    
Severity: wishlist    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In: 0.9.1
Sentry Crash Report:
Attachments: a perspectively distorted image
using the perspective tool to correct distorted.jpg

Description Daniel Bauer 2006-11-18 18:36:11 UTC
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.
Comment 1 caulier.gilles 2007-01-18 15:49:59 UTC
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  
Comment 2 Daniel Bauer 2007-01-18 17:35:02 UTC
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  
Comment 3 Daniel Bauer 2007-01-18 17:37:11 UTC
Created attachment 19326 [details]
a perspectively distorted image
Comment 4 Daniel Bauer 2007-01-18 17:42:29 UTC
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).
Comment 5 caulier.gilles 2007-01-18 20:08:51 UTC
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;
 
Comment 6 Daniel Bauer 2007-01-19 09:48:39 UTC
perfect. thank you for this!