Bug 140120 - Wish: The rotage image dialog is too imprecise
Summary: Wish: The rotage image dialog is too imprecise
Status: RESOLVED FIXED
Alias: None
Product: krita
Classification: Unclassified
Component: General (show other bugs)
Version: 1.6.1
Platform: unspecified Linux
: NOR wishlist
Target Milestone: ---
Assignee: Krita Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-01-15 19:21 UTC by Thibaut Cousin
Modified: 2007-04-09 12:01 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thibaut Cousin 2007-01-15 19:21:05 UTC
Version:           1.6.1 (using KDE 3.5.5 "release 50.1" , openSUSE )
Compiler:          Target: x86_64-suse-linux
OS:                Linux (x86_64) release 2.6.18.2-34-default

The rotate image dialog allows to configure the rotation degree by degree. This is much too imprecise, for example when you want to straighten an image that wasn't properly placed on the glass during scanning.

Using Gimp to do this task, I found out that a precision of 0,1 degree is needed.

This task is only an example, but I hope I was clear about the problem here.

Thanks for your attention.
Comment 1 Camilla Boemann 2007-01-16 21:58:21 UTC
SVN commit 624246 by boemann:

Let rotate image and rotate layer dialogs accept 0.1 degree precision
For that the API have been changed too

BUG:140120


 M  +6 -7      core/kis_image.cc  
 M  +1 -1      core/kis_image.h  
 M  +1 -0      core/kis_image_iface.cc  
 M  +1 -1      core/kis_transform_worker.cc  
 M  +9 -9      plugins/viewplugins/rotateimage/dlg_rotateimage.cc  
 M  +3 -3      plugins/viewplugins/rotateimage/dlg_rotateimage.h  
 M  +7 -6      plugins/viewplugins/rotateimage/rotateimage.cc  
 M  +6 -3      plugins/viewplugins/rotateimage/wdg_rotateimage.ui  
 M  +9 -10     ui/kis_view.cc  
 M  +2 -2      ui/kis_view.h  


--- branches/koffice/1.6/koffice/krita/core/kis_image.cc #624245:624246
@@ -801,17 +801,16 @@
 
 
 
-void KisImage::rotate(double angle, KisProgressDisplayInterface *progress)
+void KisImage::rotate(double radians, KisProgressDisplayInterface *progress)
 {
     lock();
 
-    angle *= M_PI/180;
     Q_INT32 w = width();
     Q_INT32 h = height();
-    Q_INT32 tx = Q_INT32((w*cos(angle) - h*sin(angle) - w) / 2 + 0.5);
-    Q_INT32 ty = Q_INT32((h*cos(angle) + w*sin(angle) - h) / 2 + 0.5);
-    w = (Q_INT32)(width()*QABS(cos(angle)) + height()*QABS(sin(angle)) + 0.5);
-    h = (Q_INT32)(height()*QABS(cos(angle)) + width()*QABS(sin(angle)) + 0.5);
+    Q_INT32 tx = Q_INT32((w*cos(radians) - h*sin(radians) - w) / 2 + 0.5);
+    Q_INT32 ty = Q_INT32((h*cos(radians) + w*sin(radians) - h) / 2 + 0.5);
+    w = (Q_INT32)(width()*QABS(cos(radians)) + height()*QABS(sin(radians)) + 0.5);
+    h = (Q_INT32)(height()*QABS(cos(radians)) + width()*QABS(sin(radians)) + 0.5);
 
     tx -= (w - width()) / 2;
     ty -= (h - height()) / 2;
@@ -822,7 +821,7 @@
     }
 
     KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle"));
-    KisTransformVisitor visitor (this, 1.0, 1.0, 0, 0, angle, -tx, -ty, progress, filter);
+    KisTransformVisitor visitor (this, 1.0, 1.0, 0, 0, radians, -tx, -ty, progress, filter);
     m_rootLayer->accept(visitor);
 
     if (undo()) m_adapter->addCommand(new KisResizeImageCmd(undoAdapter(), this, w, h, width(), height()));
--- branches/koffice/1.6/koffice/krita/core/kis_image.h #624245:624246
@@ -159,7 +159,7 @@
     void resize(const QRect& rc, bool cropLayers = false);
 
     void scale(double sx, double sy, KisProgressDisplayInterface *m_progress, KisFilterStrategy *filterStrategy);
-    void rotate(double angle, KisProgressDisplayInterface *m_progress);
+    void rotate(double radians, KisProgressDisplayInterface *m_progress);
     void shear(double angleX, double angleY, KisProgressDisplayInterface *m_progress);
 
     /**
--- branches/koffice/1.6/koffice/krita/core/kis_image_iface.cc #624245:624246
@@ -68,6 +68,7 @@
 void KisImageIface::rotate(double angle)
 {
     // XXX: Add progressdisplay if there is a view
+    angle *= M_PI/180;
     m_img->rotate(angle, 0);
 }
 
--- branches/koffice/1.6/koffice/krita/core/kis_transform_worker.cc #624245:624246
@@ -576,7 +576,7 @@
             m_progressTotalSteps = r.width() * r.height();
             break;
         case 3:
-            rotation += M_PI/2 + 2*M_PI;
+            rotation -= -M_PI/2 + 2*M_PI;
             tmp = xscale;
             xscale = yscale;
             yscale = tmp;
--- branches/koffice/1.6/koffice/krita/plugins/viewplugins/rotateimage/dlg_rotateimage.cc #624245:624246
@@ -53,8 +53,8 @@
 
     connect(this, SIGNAL(okClicked()),
         this, SLOT(okClicked()));
-        connect( m_page->intCustom, SIGNAL( valueChanged ( int ) ),
-                 this, SLOT( slotAngleValueChanged( int ) ) );
+        connect( m_page->doubleCustom, SIGNAL( valueChanged ( double ) ),
+                 this, SLOT( slotAngleValueChanged( double ) ) );
 
 }
 
@@ -63,12 +63,12 @@
     delete m_page;
 }
 
-void DlgRotateImage::slotAngleValueChanged( int )
+void DlgRotateImage::slotAngleValueChanged( double )
 {
     m_page->radioCustom->setChecked(true);
 }
 
-void DlgRotateImage::setAngle(Q_UINT32 angle)
+void DlgRotateImage::setAngle(double angle)
 {
     if (angle == 90) {
         m_page->radio90->setChecked(true);
@@ -81,7 +81,7 @@
     }
     else {
         m_page->radioCustom->setChecked(true);
-        m_page->intCustom->setValue(angle);
+        m_page->doubleCustom->setValue(angle);
     }
 
     if (m_oldAngle != angle)
@@ -91,7 +91,7 @@
 
 }
 
-Q_INT32 DlgRotateImage::angle()
+double DlgRotateImage::angle()
 {
     double angle = 0;
     if (m_page->radio90->isChecked()) {
@@ -104,13 +104,13 @@
         angle = 270;
     }
     else {
-        angle = qRound(m_page->intCustom->value());
+        angle = qRound(m_page->doubleCustom->value());
     }
     if (m_page->radioCW->isChecked()) {
-        return Q_INT32(angle);
+        return angle;
     }
     else {
-        return Q_INT32(-angle);
+        return -angle;
     }
 }
 
--- branches/koffice/1.6/koffice/krita/plugins/viewplugins/rotateimage/dlg_rotateimage.h #624245:624246
@@ -42,8 +42,8 @@
              const char* name = 0);
     ~DlgRotateImage();
 
-    void setAngle(Q_UINT32 w);
-    Q_INT32 angle();
+    void setAngle(double w);
+    double angle();
 
     void setDirection (enumRotationDirection direction);
     enumRotationDirection direction();
@@ -52,7 +52,7 @@
 
     void okClicked();
     void resetPreview();
-    void slotAngleValueChanged( int );
+    void slotAngleValueChanged( double );
 
 private:
 
--- branches/koffice/1.6/koffice/krita/plugins/viewplugins/rotateimage/rotateimage.cc #624245:624246
@@ -89,7 +89,8 @@
     dlgRotateImage->setCaption(i18n("Rotate Image"));
 
         if (dlgRotateImage->exec() == QDialog::Accepted) {
-        Q_INT32 angle = dlgRotateImage->angle();
+        double angle = dlgRotateImage->angle();
+        angle *= M_PI/180;
         m_view->rotateCurrentImage(angle);
     }
     delete dlgRotateImage;
@@ -97,18 +98,18 @@
 
 void RotateImage::slotRotateImage90()
 {
-    m_view->rotateCurrentImage( 90 );
+    m_view->rotateCurrentImage( M_PI/2);
 }
 
 void RotateImage::slotRotateImage180()
 {
-    m_view->rotateCurrentImage( 180 );
+    m_view->rotateCurrentImage( M_PI );
 }
 
 
 void RotateImage::slotRotateImage270()
 {
-    m_view->rotateCurrentImage( 270 );
+    m_view->rotateCurrentImage( - M_PI/2 + M_PI*2 );
 }
 
 void RotateImage::slotRotateLayer()
@@ -123,9 +124,9 @@
     dlgRotateImage->setCaption(i18n("Rotate Layer"));
 
     if (dlgRotateImage->exec() == QDialog::Accepted) {
-                Q_INT32 angle = dlgRotateImage->angle();
+        double angle = dlgRotateImage->angle();
+        angle *= M_PI/180;
         m_view->rotateLayer(angle);
-
     }
     delete dlgRotateImage;
 }
--- branches/koffice/1.6/koffice/krita/plugins/viewplugins/rotateimage/wdg_rotateimage.ui #624245:624246
@@ -194,13 +194,16 @@
                                 <bool>true</bool>
                             </property>
                         </widget>
-                        <widget class="KIntSpinBox">
+                        <widget class="KDoubleSpinBox">
                             <property name="name">
-                                <cstring>intCustom</cstring>
+                                <cstring>doubleCustom</cstring>
                             </property>
                             <property name="maxValue">
-                                <number>359</number>
+                                <number>360</number>
                             </property>
+                            <property name="lineStep">
+                                <number>1</number>
+                            </property>
                         </widget>
                     </hbox>
                 </widget>
--- branches/koffice/1.6/koffice/krita/ui/kis_view.cc #624245:624246
@@ -1770,17 +1770,17 @@
 
 void KisView::rotateLayer180()
 {
-    rotateLayer( 180 );
+    rotateLayer( M_PI );
 }
 
 void KisView::rotateLayerLeft90()
 {
-    rotateLayer( 270 );
+    rotateLayer( M_PI/2 - 2*M_PI );
 }
 
 void KisView::rotateLayerRight90()
 {
-    rotateLayer( 90 );
+    rotateLayer( M_PI/2 );
 }
 
 void KisView::mirrorLayerX()
@@ -1848,7 +1848,7 @@
     updateCanvas();
 }
 
-void KisView::rotateLayer(double angle)
+void KisView::rotateLayer(double radians)
 {
     if (!currentImg()) return;
 
@@ -1862,7 +1862,6 @@
     }
 
     KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(KisID("Triangle"));
-    angle *= M_PI/180;
     QRect r;
     if(dev->hasSelection())
         r = dev->selection()->selectedExactRect();
@@ -1870,10 +1869,10 @@
         r = dev->exactBounds();
     double cx = r.x()+r.width()/2.0;
     double cy = r.y()+r.height()/2.0;
-    Q_INT32 tx = Q_INT32(cx*cos(angle) - cy*sin(angle) - cx + 0.5);
-    Q_INT32 ty = Q_INT32(cy*cos(angle) + cx*sin(angle) - cy + 0.5);
+    Q_INT32 tx = Q_INT32(cx*cos(radians) - cy*sin(radians) - cx + 0.5);
+    Q_INT32 ty = Q_INT32(cy*cos(radians) + cx*sin(radians) - cy + 0.5);
 
-    KisTransformWorker tw(dev, 1.0, 1.0, 0, 0, angle, -tx, -ty, m_progress, filter);
+    KisTransformWorker tw(dev, 1.0, 1.0, 0, 0, radians, -tx, -ty, m_progress, filter);
     tw.run();
 
     if (t) undoAdapter()->addCommand(t);
@@ -3282,10 +3281,10 @@
     layersUpdated();
 }
 
-void KisView::rotateCurrentImage(double angle)
+void KisView::rotateCurrentImage(double radians)
 {
     if (!currentImg()) return;
-    currentImg()->rotate(angle, m_progress);
+    currentImg()->rotate(radians, m_progress);
     m_doc->setModified(true);
     layersUpdated();
 }
--- branches/koffice/1.6/koffice/krita/ui/kis_view.h #624245:624246
@@ -193,7 +193,7 @@
     void mirrorLayerX();
     void mirrorLayerY();
     void scaleLayer(double sx, double sy, KisFilterStrategy *filterStrategy);
-    void rotateLayer(double angle);
+    void rotateLayer(double radians);
     void shearLayer(double angleX, double angleY);
 
     void slotCreateMask();
@@ -215,7 +215,7 @@
 
     void resizeCurrentImage(Q_INT32 w, Q_INT32 h, bool cropLayers = false);
     void scaleCurrentImage(double sx, double sy, KisFilterStrategy *filterStrategy);
-    void rotateCurrentImage(double angle);
+    void rotateCurrentImage(double radians);
     void shearCurrentImage(double angleX, double angleY);
 
     void insertPart(const QRect& viewRect, const KoDocumentEntry& entry,
Comment 2 Thibaut Cousin 2007-01-17 16:48:09 UTC
I'm deeply impressed by this quick answer and very grateful for this patch. I'll try to apply to Krita 1.6.1 right away. :) Thank you very much.
Comment 3 Thibaut Cousin 2007-01-20 22:30:04 UTC
Just a little feedback: I applied the patch to KOffice 1.6.1 shipped with OpenSUSE 10.2 x86_64. It works very well and I'm happy now. :)

My next hope would be a live preview of the rotated image, but that's a much bigger change... Is it part of KOffice 2.0's roadmap?
Comment 4 Halla Rempt 2007-01-20 22:35:38 UTC
Not really... I mean, I had wanted to do the life update for 1.5, but I
never managed to get round to doing it.
Comment 5 Thibaut Cousin 2007-01-20 22:45:16 UTC
Should I open a bugreport to submit this wish, then? I'm sorry I can't help more, I'm not a developer.
Comment 6 Camilla Boemann 2007-01-20 22:48:49 UTC
nah, that won't make any difference
Comment 7 Thibaut Cousin 2007-01-20 22:51:57 UTC
OK. Thanks for the current patch, in any case.
Comment 8 Thibaut Cousin 2007-04-09 12:01:20 UTC
Even if it's not worth reopening this bugreport, as message #6 says, I have to say that, after trying to use Krita with this patch for weeks, I can't. Trying to guess the rotation angle I need, with a precision of 0,1°, without dynamic preview is simply impossible, or takes too many tries.

As I'm no developer, I can't do more than provide feedback and I apologise for it. At least I'm willing to try any patch you may come up with.

In any case, thanks for the patch above. :-)