7
7
* Description : a widget class to edit perspective.
9
* Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
10
* Copyright (C) 2006-2008 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
9
* Copyright (C) 2005-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
10
* Copyright (C) 2006-2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
12
12
* Matrix3 implementation inspired from gimp 2.0
13
13
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
71
70
setMinimumSize(w, h);
72
71
setMouseTracking(true);
75
m_drawWhileMoving = true;
76
m_currentResizing = ResizingNone;
77
m_guideColor = Qt::red;
74
m_drawWhileMoving = true;
75
m_inverseTransformation = false;
76
m_currentResizing = ResizingNone;
77
m_guideColor = Qt::red;
80
80
m_iface = new Digikam::ImageIface(w, h);
81
81
uchar *data = m_iface->setPreviewImageSize(w, h);
210
210
targetImg.bits(), targetImg.width(), targetImg.height());
213
void PerspectiveWidget::slotInverseTransformationChanged(bool isEnabled)
215
m_inverseTransformation = isEnabled;
213
220
void PerspectiveWidget::slotToggleAntiAliasing(bool a)
277
284
m_pixmap->fill(palette().color(QPalette::Background));
286
if(m_inverseTransformation)
288
m_transformedCenter = buildPerspective(QPoint(0, 0), QPoint(m_w, m_h),
289
m_topLeftPoint, m_topRightPoint,
290
m_bottomLeftPoint, m_bottomRightPoint);
292
m_iface->putPreviewImage(m_previewImage.bits());
293
m_iface->paint(m_pixmap, m_rect.x(), m_rect.y(),
294
m_rect.width(), m_rect.height());
279
296
// if we are resizing with the mouse, compute and draw only if drawWhileMoving is set
280
if (m_currentResizing == ResizingNone || m_drawWhileMoving)
298
else if ((m_currentResizing == ResizingNone || m_drawWhileMoving))
282
300
// Create preview image
345
363
// Drawing vertical and horizontal guide lines.
347
int xspot = m_spot.x() + m_rect.x();
348
int yspot = m_spot.y() + m_rect.y();
349
p.setPen(QPen(Qt::white, m_guideSize, Qt::SolidLine));
350
p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom());
351
p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot);
352
p.setPen(QPen(m_guideColor, m_guideSize, Qt::DotLine));
353
p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom());
354
p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot);
365
if(!m_inverseTransformation)
367
int xspot = m_spot.x() + m_rect.x();
368
int yspot = m_spot.y() + m_rect.y();
369
p.setPen(QPen(Qt::white, m_guideSize, Qt::SolidLine));
370
p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom());
371
p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot);
372
p.setPen(QPen(m_guideColor, m_guideSize, Qt::DotLine));
373
p.drawLine(xspot, m_rect.top(), xspot, m_rect.bottom());
374
p.drawLine(m_rect.left(), yspot, m_rect.right(), yspot);
456
477
transform.scale (scalex, scaley);
457
478
transform.multiply (matrix);
459
// Compute perspective transformation to image if image data containers exist.
460
if (orgImage && destImage)
461
transformAffine(orgImage, destImage, transform, background);
480
if(orgImage && destImage)
482
if(m_inverseTransformation)
484
Matrix inverseTransform = transform;
485
inverseTransform.invert();
487
//Transform the matrix so it puts the result into the getTargetSize() rectangle
488
Matrix transformIntoBounds;
489
transformIntoBounds.scale(double(getTargetSize().width()) / double(orgImage->width()), double(getTargetSize().height()) / double(orgImage->height()));
490
transformIntoBounds.translate(getTargetSize().left(), getTargetSize().top());
491
inverseTransform.multiply(transformIntoBounds);
492
transformAffine(orgImage, destImage, inverseTransform, background);
496
// Compute perspective transformation to image if image data containers exist.
497
transformAffine(orgImage, destImage, transform, background);
463
501
// Calculate the grid array points.
464
502
double newX, newY;
584
622
// u, v coordinates into source
589
//TODO: Check why anti-aliasing doesn't work
624
//In inverse transformation we always enable anti-aliasing, because there is always under-sampling
625
if (m_antiAlias || m_inverseTransformation)
627
double finalU = u[0] - u1;
628
double finalV = v[0] - v1;
594
632
unsigned short *d16 = (unsigned short *)d;
595
633
filters.pixelAntiAliasing16((unsigned short *)data,
596
width, height, u, v, d16+3, d16+2, d16+1, d16);
634
width, height, finalU, finalV, d16+3, d16+2, d16+1, d16);
600
filters.pixelAntiAliasing(data, width, height, u, v,
638
filters.pixelAntiAliasing(data, width, height, finalU, finalV,
601
639
d+3, d+2, d+1, d);
606
offset = (v * width * bytesDepth) + (u * bytesDepth);
607
color.setColor(data + offset, sixteenBit);
646
offset = (v * width * bytesDepth) + (u * bytesDepth);
647
color.setColor(data + offset, sixteenBit);
758
798
QRegion unsableArea(unsablePoints);
760
if ( unsableArea.contains(pm) ) return;
800
if ( unsableArea.contains(pm) && !m_inverseTransformation ) return;
762
802
m_topLeftPoint = pm - m_rect.topLeft();
763
803
setCursor( Qt::SizeFDiagCursor );
776
816
QRegion unsableArea(unsablePoints);
778
if ( unsableArea.contains(pm) ) return;
818
if ( unsableArea.contains(pm) && !m_inverseTransformation ) return;
780
820
m_topRightPoint = pm - m_rect.topLeft();
781
821
setCursor( Qt::SizeBDiagCursor );
794
834
QRegion unsableArea(unsablePoints);
796
if ( unsableArea.contains(pm) ) return;
836
if ( unsableArea.contains(pm) && !m_inverseTransformation ) return;
798
838
m_bottomLeftPoint = pm - m_rect.topLeft();
799
839
setCursor( Qt::SizeBDiagCursor );
812
852
QRegion unsableArea(unsablePoints);
814
if ( unsableArea.contains(pm) ) return;
854
if ( unsableArea.contains(pm) && !m_inverseTransformation ) return;
816
856
m_bottomRightPoint = pm - m_rect.topLeft();
817
857
setCursor( Qt::SizeFDiagCursor );