Hugin trunk 0.1
Loading...
Searching...
No Matches
PerspectiveImageCtrl.cpp
Go to the documentation of this file.
1// -*- c-basic-offset: 4 -*-
10/* This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This software is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this software. If not, see
22 * <http://www.gnu.org/licenses/>.
23 *
24 */
25
26
27#include "panoinc_WX.h"
28#include "panoinc.h"
29#include "ToolboxApp.h"
30#include <wx/dcbuffer.h>
31#include "base_wx/platform.h"
33#include "vigra/transformimage.hxx"
35#include "nona/ImageRemapper.h"
36#include "base_wx/wxcms.h"
37
38// init some values
61
62void PerspectiveImageCtrl::setImage(const std::string& file, ImageRotation rot)
63{
64 if (!file.empty())
65 {
66 try
67 {
68 ImageCache::getInstance().softFlush();
69 m_img = ImageCache::getInstance().getImage(file);
70 }
71 catch (...)
72 {
73 // loading of image failed, set all to empty values
74 m_imageFilename = "";
77 // delete the image (release shared_ptr)
78 // create an empty image.
79 m_img = ImageCache::EntryPtr(new ImageCache::Entry);
80 SetVirtualSize(100, 100);
81 Refresh(true);
82 return;
83 }
85 m_imageFilename = file;
87 m_showRemappedImage = false;
89 // create initial rectangle
90 m_rectPoints.resize(4);
91 m_rectPoints[0] = vigra::Point2D(0.25 * m_realSize.GetWidth(), 0.25 * m_realSize.GetHeight());
92 m_rectPoints[1] = vigra::Point2D(0.75 * m_realSize.GetWidth(), 0.25 * m_realSize.GetHeight());
93 m_rectPoints[2] = vigra::Point2D(0.75 * m_realSize.GetWidth(), 0.75 * m_realSize.GetHeight());
94 m_rectPoints[3] = vigra::Point2D(0.25 * m_realSize.GetWidth(), 0.75 * m_realSize.GetHeight());
95 // clear lines
96 m_lines.clear();
97 Refresh();
98 }
99 else
100 {
102 m_bitmap = wxBitmap();
103 // delete the image (release shared_ptr)
104 // create an empty image.
105 m_img = ImageCache::EntryPtr(new ImageCache::Entry);
107 SetVirtualSize(100, 100);
108 m_lines.clear();
109 Refresh(true);
110 }
111}
112
114{
115 if (newRot != m_imgRotation)
116 {
117 // image rotation changed, rotate the rectangle
118 // update flag and redraw image
120 rescaleImage();
121 Refresh();
122 };
123}
124
126{
128 {
129 return;
130 };
132 {
133 // handle scrolling and break out
135 viewStart = viewStart - (mouse.GetPosition() - m_scrollPos);
137 m_scrollPos = mouse.GetPosition();
138 return;
139 };
141 CalcUnscrolledPosition(mouse.GetPosition().x, mouse.GetPosition().y, &mpos.x, &mpos.y);
144 switch (m_editorState)
145 {
146 case POINT_MOVING:
148 Refresh(false);
149 break;
150 case SEGMENT_MOVING:
152 {
156 };
157 Refresh(false);
158 break;
159 case RECT_MOVING:
161 {
163 for (auto& p : m_rectPoints)
164 {
165 p = p + delta;
166 };
167 };
168 Refresh(false);
169 break;
170 case LINE_CREATE:
172 if (!m_currentLine.empty())
173 {
174 m_currentLine[0].end = currentPos;
175 Refresh(false);
176 };
177 break;
178 case LINE_MOVING:
179 if (!m_currentLine.empty())
180 {
183 m_currentLine[0].start = m_currentLine[0].start + delta;
184 m_currentLine[0].end = m_currentLine[0].end + delta;
185 Refresh(false);
186 };
187 break;
188 default:
189 break;
190 }
191}
192
194{
196 {
197 return;
198 };
199 DEBUG_DEBUG("LEFT MOUSE DOWN");
200 CalcUnscrolledPosition(mouse.GetPosition().x, mouse.GetPosition().y, &m_dragStartPos.x, &m_dragStartPos.y);
203 if (!HasCapture())
204 CaptureMouse();
205 SetFocus();
206
208 {
209 if (m_showRect)
210 {
211 // in rect mode
213 if (m_movingPoint != -1)
214 {
215 // click is near one point of the rectangle
217 }
218 else
219 {
221 if (m_movingPoint != -1)
222 {
223 // click is near one line of the rectangle
226 }
227 else
228 {
230 {
231 // click is inside the rect
234 };
235 };
236 };
237 }
238 else
239 {
240 // in lines mode
241 bool isStart = true;
243 if (lineIndex != -1)
244 {
245 // click is near one point
248 if (isStart)
249 {
250 // if click is near end point, mirror point
251 // so we can move always the end point
253 }
254 m_currentLine.push_back(currentLine);
255 m_lines.erase(m_lines.begin() + lineIndex);
256 }
257 else
258 {
260 if (lineIndex != -1)
261 {
262 // click was near one line
266 m_lines.erase(m_lines.begin() + lineIndex);
267 }
268 else
269 {
270 // click is far from all lines, start creating a new line
273 };
274 };
275 };
276 };
277}
278
280{
281 if (pos.x < -PerspectiveOffset)
282 {
284 };
285 if (pos.x > m_realSize.GetWidth() + PerspectiveOffset)
286 {
287 pos.x = m_realSize.GetWidth() + PerspectiveOffset;
288 };
289 if (pos.y < -PerspectiveOffset)
290 {
292 };
293 if (pos.y > m_realSize.GetHeight() + PerspectiveOffset)
294 {
295 pos.y = m_realSize.GetHeight() + PerspectiveOffset;
296 };
297}
298
300{
302 {
303 return;
304 };
305 DEBUG_DEBUG("LEFT MOUSE UP");
307 CalcUnscrolledPosition(mouse.GetPosition().x, mouse.GetPosition().y, &mpos.x, &mpos.y);
308 // limit position to valid area
311 bool doUpdate = false;
312 switch (m_editorState)
313 {
314 case POINT_MOVING:
317 doUpdate = true;
318 break;
319 case SEGMENT_MOVING:
321 {
326 };
327 doUpdate = true;
328 break;
329 case RECT_MOVING:
331 {
334 for (auto& p : m_rectPoints)
335 {
336 p = p + delta;
337 };
338 };
339 doUpdate = true;
340 break;
341 case LINE_CREATE:
344 {
345 if (!m_currentLine.empty())
346 {
347 // update line position and add them to m_lines vector
348 m_currentLine[0].end = currentPos;
349 m_lines.push_back(m_currentLine[0]);
350 m_currentLine.clear();
351 };
352 };
353 doUpdate = true;
354 break;
355 case LINE_MOVING:
357 {
359 // update start and end position of the line
361 movedLine.start = movedLine.start + delta;
362 movedLine.end = movedLine.end + delta;
363 m_lines.push_back(movedLine);
364 m_currentLine.clear();
365 };
366 doUpdate = true;
367 break;
368 default:
369 break;
370 };
371 if (HasCapture())
372 {
373 ReleaseMouse();
374 };
375 if (doUpdate)
376 {
377 Refresh(false);
378 };
379}
380
382{
384 {
385 // do nothing when
386 // * showing remapped images
387 // * when scrolling with middle mouse button
388 // * when in rectangle mode
389 return;
390 };
391 DEBUG_DEBUG("RIGHT MOUSE UP");
393 CalcUnscrolledPosition(mouse.GetPosition().x, mouse.GetPosition().y, &mpos.x, &mpos.y);
396 {
397 // check if click is near one line
399 if (lineIndex != -1)
400 {
401 // delete the found line
402 m_lines.erase(m_lines.begin() + lineIndex);
403 Refresh();
404 };
405 };
406}
407
409{
411 {
412 return;
413 };
414 switch (m_editorState)
415 {
416 case SHOW_IMAGE:
417 if (!HasCapture())
418 {
419 CaptureMouse();
420 };
421 // store the scroll rate, the scroll rate set in rescaleImage is optimized for srolling
422 // with the cursor keys, but this is too high for mouse scrolling
423 // so change the scroll rate here and restore later in OnMiddleMouseUp
424 m_middleMouseScroll = true;
425 m_scrollPos = mouse.GetPosition();
426 break;
427 default:
428 // in other case ignore the middle mouse button
429 break;
430 };
431}
432
434{
436 {
437 return;
438 };
439 if (HasCapture())
440 {
441 ReleaseMouse();
442 };
443 m_middleMouseScroll = false;
444}
445
451
453{
454 if (HasCapture())
455 {
456 ReleaseMouse();
457 };
458}
459
465
466void PerspectiveImageCtrl::DrawRect(wxDC& dc, const std::vector<hugin_utils::FDiff2D>& rect)
467{
468 if (rect.size() == 4)
469 {
470 wxPoint* polygonPoints = new wxPoint[4];
471 for (unsigned int j = 0; j < 4; j++)
472 {
474 };
476 dc.SetBrush(*wxTRANSPARENT_BRUSH);
477 dc.DrawPolygon(4, polygonPoints);
478 // draw markers at each corner
479 dc.SetBrush(wxBrush(m_colour_selected));
480 for (unsigned int j = 0; j < 4; j++)
481 {
484 };
485 delete[]polygonPoints;
486 };
487}
488
489void PerspectiveImageCtrl::DrawLines(wxDC& dc, const std::vector<Line>& lines)
490{
491 if (!lines.empty())
492 {
494 // dc.SetBrush(*wxTRANSPARENT_BRUSH);
495 dc.SetBrush(wxBrush(m_colour_selected));
496 for (const auto& p : lines)
497 {
498 const wxPoint start = transform(applyRot(p.start));
499 const wxPoint end = transform(applyRot(p.end));
500 dc.DrawLine(start, end);
501 // draw markers
502 dc.DrawRectangle(start.x - polygonPointSize, start.y - polygonPointSize, 2 * polygonPointSize, 2 * polygonPointSize);
503 dc.DrawRectangle(end.x - polygonPointSize, end.y - polygonPointSize, 2 * polygonPointSize, 2 * polygonPointSize);
504 };
505 };
506}
507
509{
511 PrepareDC(dc);
512 dc.SetBackground(GetBackgroundColour());
513 dc.Clear();
515 {
516 // draw remapped image
517 if (m_remappedImg.IsOk() && m_remappedImg.GetWidth() > 0 && m_remappedImg.GetHeight() > 0)
518 {
519 dc.DrawBitmap(m_remappedImg, 0, 0);
520 };
521 }
522 else
523 {
524 // draw original image
525 if (m_bitmap.IsOk())
526 {
527 const int offset = scale(PerspectiveOffset);
528 dc.DrawBitmap(m_bitmap, offset, offset);
529 if (m_showRect)
530 {
531 // draw user rectangle
533 }
534 else
535 {
536 // draw lines
538 if (!m_currentLine.empty())
539 {
541 };
542 };
543 };
544 };
545}
546
548{
550 cp.image1Nr = index;
551 cp.x1 = p1.x;
552 cp.y1 = p1.y;
553 cp.x2 = p2.x;
554 cp.y2 = p2.y;
556 if (abs(cp.x1 - cp.x2) < abs(cp.y1 - cp.y2))
557 {
559 }
560 else
561 {
563 };
564 return cp;
565}
566
568{
569 if (m_showRect != newMode)
570 {
572 Refresh();
573 };
574}
575
577{
579 if (m_showRect)
580 {
581 // create control points from rect
582 controlPoints.push_back(GetCP(index, m_rectPoints[0], m_rectPoints[1]));
583 controlPoints.push_back(GetCP(index, m_rectPoints[1], m_rectPoints[2]));
584 controlPoints.push_back(GetCP(index, m_rectPoints[2], m_rectPoints[3]));
585 controlPoints.push_back(GetCP(index, m_rectPoints[3], m_rectPoints[0]));
586 }
587 else
588 {
589 // transform lines into HuginBase::ControlPoint
590 for (const auto& p : m_lines)
591 {
592 controlPoints.push_back(GetCP(index, p.start, p.end));
593 };
594 }
595 return controlPoints;
596}
597
599{
600 m_pano = pano.duplicate();
601 GenerateRemappedImage(GetClientSize().GetWidth(), GetClientSize().GetHeight());
602 m_showRemappedImage = true;
604 Refresh();
605}
606
608{
609 m_showRemappedImage = false;
611 Refresh();
612}
613
615{
616 m_lines.clear();
617 for (const auto& l : lines)
618 {
619 m_lines.push_back(Line(hugin_utils::FDiff2D(l.x1, l.y1), hugin_utils::FDiff2D(l.x2, l.y2)));
620 };
621 Refresh();
622}
623
625{
626 m_lines.clear();
627 Refresh();
628}
629
631{
632 // rescale m_bitmap if needed.
633 if (!m_imageFilename.empty())
634 {
635 if (m_fitToWindow)
636 {
637 setScale(0);
638 }
639 };
641 {
642 GenerateRemappedImage(e.GetSize().GetWidth(), e.GetSize().GetHeight());
643 };
644 e.Skip();
645}
646
648{
649 if (m_editorState == NO_IMAGE)
650 {
651 return;
652 }
654 if (img.GetWidth() == 0)
655 {
656 return;
657 }
658 m_imageSize = wxSize(img.GetWidth(), img.GetHeight());
661 if (m_fitToWindow)
662 {
664 };
665
666 //scaling image to screen size
667 if (getScaleFactor() != 1.0)
668 {
669 m_imageSize.SetWidth(scale(m_imageSize.GetWidth()));
670 m_imageSize.SetHeight(scale(m_imageSize.GetHeight()));
672 if (std::max(img.GetWidth(), img.GetHeight()) > (ULONG_MAX >> 16))
673 {
674 // wxIMAGE_QUALITY_NORMAL resizes the image with ResampleNearest
675 // this algorithm works only if image dimensions are smaller then
676 // ULONG_MAX >> 16 (actual size of unsigned long differ from system
677 // to system)
679 };
680 img = img.Scale(scale(m_realSize.GetWidth()), scale(m_realSize.GetHeight()), resizeQuality);
681 }
682 else
683 {
684 //the conversion to disabled m_bitmap would work on the original cached image file
685 //therefore we need to create a copy to work on it
686 img = img.Copy();
687 };
688 //and now rotating
689 switch (m_imgRotation)
690 {
691 case ROT90:
692 img = img.Rotate90(true);
693 break;
694 case ROT180:
695 img = img.Rotate180();
696 break;
697 case ROT270:
698 img = img.Rotate90(false);
699 break;
700 default:
701 break;
702 }
703 // do color correction only if input image has icc profile or if we found a monitor profile
704 if (!m_img->iccProfile->empty() || wxGetApp().GetToolboxFrame()->HasMonitorProfile())
705 {
706 HuginBase::Color::CorrectImage(img, *(m_img->iccProfile), wxGetApp().GetToolboxFrame()->GetMonitorProfile());
707 };
708 m_bitmap = wxBitmap(img);
710 Refresh(true);
711}
712
714{
716 {
717 SetVirtualSize(m_imageSize.GetHeight(), m_imageSize.GetWidth());
718 }
719 else
720 {
721 SetVirtualSize(m_imageSize.GetWidth(), m_imageSize.GetHeight());
722 };
723 SetScrollRate(1, 1);
724}
725
726void PerspectiveImageCtrl::GenerateRemappedImage(const unsigned int newWidth, const unsigned int newHeight)
727{
729 //fill options with actual size
731 const double scale = std::min((double)newWidth / opts.getROI().width(), (double)newHeight / opts.getROI().height());
732 opts.setWidth(opts.getWidth() * scale, true);
733 //now remap image
734 remapped->setPanoImage(m_pano.getSrcImage(0), opts, opts.getROI());
736 remapped->remapImage(vigra::srcImageRange(*(m_img->get8BitImage())), vigra_ext::INTERP_CUBIC, progress);
737 delete progress;
738 vigra::BRGBImage remappedImage = remapped->m_image;
740 remappedwxImage.SetData((unsigned char*)remappedImage.data(), remappedImage.width(), remappedImage.height(), true);
741 // apply color profiles
742 if (!m_img->iccProfile->empty() || wxGetApp().GetToolboxFrame()->HasMonitorProfile())
743 {
744 HuginBase::Color::CorrectImage(remappedwxImage, *(m_img->iccProfile), wxGetApp().GetToolboxFrame()->GetMonitorProfile());
745 };
746 delete remapped;
748}
749
752{
753 const hugin_utils::FDiff2D& r(b - a);
754 const double l = (p - a) * r / (r * r);
755 if (l >= 0.0 && l <= 1.0)
756 {
757 // check that footpoint is between both points
758 const hugin_utils::FDiff2D x = a + r * l;
759 return std::sqrt(x.squareDistance(p));
760 }
761 else
762 {
763 return DBL_MAX;
764 }
765}
766
768{
769 if (m_rectPoints.size() == 4)
770 {
771 double minDist = DBL_MAX;
772 int indexMin = -1;
773 for (int i = 0; i < 4; ++i)
774 {
775 const double dist = std::sqrt(p.squareDistance(m_rectPoints[i]));
776 if (dist < minDist)
777 {
778 minDist = dist;
779 indexMin = i;
780 };
781 };
783 {
784 return indexMin;
785 };
786 };
787 return -1;
788}
789
791{
792 if (m_rectPoints.size() == 4)
793 {
794 double minDist = DBL_MAX;
795 int indexMin = -1;
796 for (int i = 0; i < 4; ++i)
797 {
798 double dist = GetDistance(p, m_rectPoints[i], m_rectPoints[(i + 1) % 4]);
799 if (dist < minDist)
800 {
801 minDist = dist;
802 indexMin = i;
803 };
804 };
806 {
807 return indexMin;
808 };
809 };
810 return -1;
811}
812
814{
815 std::vector<double> xpos, ypos;
816 for (const auto& p : m_rectPoints)
817 {
818 xpos.push_back(p.x);
819 ypos.push_back(p.y);
820 };
821 std::sort(xpos.begin(), xpos.end());
822 std::sort(ypos.begin(), ypos.end());
823 const unsigned int index = (xpos.size() - 1) / 2;
824 return (p.x > xpos[index] && p.x < xpos[index + 1] && p.y > ypos[index] && p.y < ypos[index + 1]) ? true : false;
825}
826
828{
829 if (!m_lines.empty())
830 {
831 double minDist = DBL_MAX;
832 int minLineIndex = -1;
833 bool minLineStart = false;
834 for (int i = 0; i < m_lines.size(); ++i)
835 {
836 const double distStart = std::sqrt(p.squareDistance(m_lines[i].start));
837 const double distEnd = std::sqrt(p.squareDistance(m_lines[i].end));
838 // check if distance is shorter to start or end of line
839 if (distStart < distEnd)
840 {
841 if (distStart < minDist)
842 {
843 // distance is nearer than older one
845 minLineIndex = i;
846 minLineStart = true;
847 }
848 }
849 else
850 {
851 if (distEnd < minDist)
852 {
853 // distance is nearer than older one
855 minLineIndex = i;
856 minLineStart = false;
857 }
858 };
859 };
860 if (minLineIndex != -1 && minDist < DBL_MAX)
861 {
863 {
864 // distance is smaller than threshold, return nearest point
866 return minLineIndex;
867 };
868 };
869 };
870 return -1;
871}
872
874{
875 if (!m_lines.empty())
876 {
877 double minDist = DBL_MAX;
878 int indexMin = -1;
879 for (int i = 0; i < m_lines.size(); ++i)
880 {
881 double dist = GetDistance(p, m_lines[i].start, m_lines[i].end);
882 if (dist < minDist)
883 {
884 minDist = dist;
885 indexMin = i;
886 };
887 };
889 {
890 return indexMin;
891 };
892 };
893 return -1;
894}
895
897{
898 if (factor == 0)
899 {
900 m_fitToWindow = true;
902 }
903 else
904 {
905 m_fitToWindow = false;
906 }
907 DEBUG_DEBUG("new scale factor:" << factor);
908 // update if factor changed
909 if (factor != m_scaleFactor)
910 {
911 m_scaleFactor = factor;
912 // keep existing scale focussed.
913 rescaleImage();
914 }
915}
916
918{
919 return m_fitToWindow ? 0 : m_scaleFactor;
920}
921
923{
924 int w = size.GetWidth();
925 int h = size.GetHeight();
927 {
928 int t = w;
929 w = h;
930 h = t;
931 }
932
933 wxSize csize = GetSize();
934 DEBUG_DEBUG("csize: " << csize.GetWidth() << "x" << csize.GetHeight() << "image: " << w << "x" << h);
935 double s1 = (double)csize.GetWidth() / w;
936 double s2 = (double)csize.GetHeight() / h;
937 DEBUG_DEBUG("s1: " << s1 << " s2:" << s2);
938 return s1 < s2 ? s1 : s2;
939}
940
942{
943 return m_scaleFactor;
944}
945
946IMPLEMENT_DYNAMIC_CLASS(PerspectiveImageCtrl, wxScrolledWindow)
double GetDistance(const hugin_utils::FDiff2D &p, const hugin_utils::FDiff2D &a, const hugin_utils::FDiff2D &b)
returns distance between point p and line between points a and p, the footpoint of p has to be betwee...
declaration of preview for lens calibration gui
const int maxSelectionDistance
maximal distance for selection of one point
const int polygonPointSize
half size of markers
const int PerspectiveOffset
size of border at all sides
Contains functions to transform whole images.
Dummy progress display, without output.
represents a control point
@ X
evaluate x, points are on a vertical line
@ Y
evaluate y, points are on a horizontal line
struct to hold a image state for stitching
Panorama image options.
const vigra::Rect2D & getROI() const
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
unsigned int getWidth() const
Model for a panorama.
Definition Panorama.h:153
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition Panorama.h:481
SrcPanoImage getSrcImage(unsigned imgNr) const
get a description of a source image
Panorama duplicate() const
duplicate the panorama
image previewer for perspective correction
void RemoveLines()
remove all lines from the list
std::vector< hugin_utils::FDiff2D > m_rectPointsStartDrag
std::vector< Line > m_lines
int GetNearestRectanglePoint(const hugin_utils::FDiff2D &p)
return index of nearest rectangle point or -1 if the point is too far from rectangle
T applyRotInv(const T &p) const
PerspectiveEditorState m_editorState
HuginBase::CPVector GetControlPoints(const unsigned int index)
return list of control points
void DrawRect(wxDC &dc, const std::vector< hugin_utils::FDiff2D > &rect)
void OnMiddleMouseUp(wxMouseEvent &mouse)
event handler for middle mouse button, end scrolling
HuginBase::ControlPoint GetCP(const unsigned int index, const hugin_utils::FDiff2D &p1, const hugin_utils::FDiff2D &p2)
return the HuginBase::ControlPoint, using index as image index, p1 and p2 as position,...
void OnRightMouseUp(wxMouseEvent &mouse)
event handler when right mouse button is released
void AddLines(const HuginBase::CPVector &lines)
add the lines to the list
double getScaleFactor() const
get scale factor (calculates factor when fit to window is active)
void OnSize(wxSizeEvent &e)
handler called when size of control was changed
int GetNearestRectangleLine(const hugin_utils::FDiff2D &p)
return index of nearest rectangle line or -1 if the point is too far from the rectangle lines
void setOriginalMode()
show the original images with selected zoom ration, the mouse handlers are activated
void OnMiddleMouseDown(wxMouseEvent &mouse)
event handler for middle mouse button, start scrolling
HuginBase::Panorama m_pano
HuginBase::Panorama object for calculation of remapped image.
void rescaleImage()
rescale the image
double calcAutoScaleFactor(wxSize size)
calculate new scale factor for this image
bool IsInsideRect(const hugin_utils::FDiff2D &p)
return true, if the point p is inside the rect
int GetNearestLine(const hugin_utils::FDiff2D &p)
return index of nearest line or -1 if the point is too far from all lines
ImageCache::EntryPtr m_img
image cache entry for current image
void setScale(double factor)
set the scaling factor for mask editing display.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name="panel")
creates the control
void ChangeRotation(ImageRotation newRot)
int invtransform(int x) const
translate screen coordinates to image coordinates, considers additional added border
wxBitmap m_remappedImg
the remapped image as wxBitmap
int transform(int x) const
convert image coordinate to screen coordinates, considers additional added border
double getScale() const
return scale factor, 0 for autoscale
void UpdateVirtualSize()
update the virtual size of the control, necessary for correctly display the scrollbars
void SetLineColour(wxColour newColour)
sets the colour for the lines
void OnLeftMouseUp(wxMouseEvent &mouse)
event handler when right mouse button is released
void OnKillFocus(wxFocusEvent &e)
event handler, when editor lost focus, mainly cancels creating new polygon
std::vector< hugin_utils::FDiff2D > m_rectPoints
void DrawLines(wxDC &dc, const std::vector< Line > &lines)
void GenerateRemappedImage(const unsigned int newWidth, const unsigned int newHeight)
generates the remapped image suitable for wxBitmap
void OnCaptureLost(wxMouseCaptureLostEvent &e)
event handler, when mouse capture is lost, e.g.
int scale(int x) const
helper function for scale, offset and rotation
void OnMouseMove(wxMouseEvent &mouse)
event handler when mouse is moving
void OnPaint(wxPaintEvent &e)
drawing routine
std::vector< Line > m_currentLine
void setImage(const std::string &filename, ImageRotation rot)
set the current image and mask list, this loads also the image from cache
void ClipPos(hugin_utils::FDiff2D &pos)
clip the given pos to image size + offset
void SetRemappedMode(const HuginBase::Panorama &pano)
set the panorama object for remapping, the mouse handler are deactivated
void SetRectMode(bool newMode)
set line or rect mode
T applyRot(const T &p) const
int GetNearestLinePoint(const hugin_utils::FDiff2D &p, bool &isStart)
return index of nearest line or -1 if the point to far from line
void OnLeftMouseDown(wxMouseEvent &mouse)
event handler when left mouse button is pressed
implementation of huginApp Class
#define DEBUG_DEBUG(msg)
Definition utils.h:68
void CorrectImage(wxImage &image, const vigra::ImageImportInfo::ICCProfile &iccProfile, const cmsHPROFILE &monitorProfile)
apply color correction to given image using input iccProfile and monitor profile
Definition wxcms.cpp:218
std::vector< ControlPoint > CPVector
include file for the hugin project
include file for the hugin project
T squareDistance(TDiff2D< T > other) const
Return square of the distance to another point.
Definition hugin_math.h:147
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41
wxImage imageCacheEntry2wxImage(ImageCache::EntryPtr e)