Mercurial > hg > orthanc-stone
comparison Applications/Samples/SingleFrameEditorApplication.h @ 342:4297d6c5eef9 am-2
moving bitmap
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 22 Oct 2018 09:44:52 +0200 |
parents | 7bebbfa56bde |
children | 712acc87fa2e |
comparison
equal
deleted
inserted
replaced
341:7bebbfa56bde | 342:4297d6c5eef9 |
---|---|
62 unsigned int cropX_; | 62 unsigned int cropX_; |
63 unsigned int cropY_; | 63 unsigned int cropY_; |
64 unsigned int cropWidth_; | 64 unsigned int cropWidth_; |
65 unsigned int cropHeight_; | 65 unsigned int cropHeight_; |
66 Matrix transform_; | 66 Matrix transform_; |
67 | 67 double pixelSpacingX_; |
68 double pixelSpacingY_; | |
69 double panX_; | |
70 double panY_; | |
71 | |
72 | |
73 void UpdateTransform() | |
74 { | |
75 transform_ = LinearAlgebra::IdentityMatrix(3); | |
76 | |
77 transform_(0, 0) = pixelSpacingX_; | |
78 transform_(1, 1) = pixelSpacingY_; | |
79 transform_(0, 2) = panX_; | |
80 transform_(1, 2) = panY_; | |
81 | |
82 | |
83 #if 0 | |
84 double a = 10.0 / 180.0 * boost::math::constants::pi<double>(); | |
85 Matrix m; | |
86 const double v[] = { cos(a), -sin(a), 0, | |
87 sin(a), cos(a), 0, | |
88 0, 0, 1 }; | |
89 LinearAlgebra::FillMatrix(m, 3, 3, v); | |
90 transform_ = LinearAlgebra::Product(m, transform_); | |
91 #endif | |
92 } | |
93 | |
94 | |
68 void ApplyConverter() | 95 void ApplyConverter() |
69 { | 96 { |
70 if (source_.get() != NULL && | 97 if (source_.get() != NULL && |
71 converter_.get() != NULL) | 98 converter_.get() != NULL) |
72 { | 99 { |
105 Bitmap() : | 132 Bitmap() : |
106 visible_(true), | 133 visible_(true), |
107 width_(0), | 134 width_(0), |
108 height_(0), | 135 height_(0), |
109 hasCrop_(false), | 136 hasCrop_(false), |
110 transform_(LinearAlgebra::IdentityMatrix(3)) | 137 pixelSpacingX_(1), |
111 { | 138 pixelSpacingY_(1), |
139 panX_(0), | |
140 panY_(0) | |
141 { | |
142 UpdateTransform(); | |
112 } | 143 } |
113 | 144 |
114 void ResetCrop() | 145 void ResetCrop() |
115 { | 146 { |
116 hasCrop_ = false; | 147 hasCrop_ = false; |
178 | 209 |
179 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && | 210 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && |
180 LinearAlgebra::ParseVector(pixelSpacing, tmp) && | 211 LinearAlgebra::ParseVector(pixelSpacing, tmp) && |
181 pixelSpacing.size() == 2) | 212 pixelSpacing.size() == 2) |
182 { | 213 { |
183 transform_(0, 0) = pixelSpacing[0]; | 214 pixelSpacingX_ = pixelSpacing[0]; |
184 transform_(1, 1) = pixelSpacing[1]; | 215 pixelSpacingY_ = pixelSpacing[1]; |
185 } | 216 } |
186 | 217 |
187 | |
188 #if 0 | |
189 double a = 10.0 / 180.0 * boost::math::constants::pi<double>(); | |
190 Matrix m; | |
191 const double v[] = { cos(a), -sin(a), 0, | |
192 sin(a), cos(a), 0, | |
193 0, 0, 1 }; | |
194 LinearAlgebra::FillMatrix(m, 3, 3, v); | |
195 transform_ = LinearAlgebra::Product(m, transform_); | |
196 | |
197 #else | |
198 static unsigned int c = 0; | 218 static unsigned int c = 0; |
199 if (c == 0) | 219 if (c == 0) |
200 { | 220 { |
201 transform_(0, 2) = 400; | 221 panX_ = 400; |
202 c ++; | 222 c ++; |
203 } | 223 } |
204 #endif | |
205 | 224 |
206 OrthancPlugins::DicomDatasetReader reader(dataset); | 225 OrthancPlugins::DicomDatasetReader reader(dataset); |
207 | 226 |
208 if (!reader.GetUnsignedIntegerValue(width_, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) || | 227 if (!reader.GetUnsignedIntegerValue(width_, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) || |
209 !reader.GetUnsignedIntegerValue(height_, ConvertTag(Orthanc::DICOM_TAG_ROWS))) | 228 !reader.GetUnsignedIntegerValue(height_, ConvertTag(Orthanc::DICOM_TAG_ROWS))) |
210 { | 229 { |
211 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | 230 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
212 } | 231 } |
232 | |
233 UpdateTransform(); | |
213 } | 234 } |
214 | 235 |
215 | 236 |
216 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership | 237 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership |
217 { | 238 { |
246 | 267 |
247 double dx = static_cast<double>(x) - 0.5; | 268 double dx = static_cast<double>(x) - 0.5; |
248 double dy = static_cast<double>(y) - 0.5; | 269 double dy = static_cast<double>(y) - 0.5; |
249 double dwidth = static_cast<double>(width); | 270 double dwidth = static_cast<double>(width); |
250 double dheight = static_cast<double>(height); | 271 double dheight = static_cast<double>(height); |
272 | |
273 LinearAlgebra::Print(transform_); | |
251 | 274 |
252 AddToExtent(extent, dx, dy); | 275 AddToExtent(extent, dx, dy); |
253 AddToExtent(extent, dx + dwidth, dy); | 276 AddToExtent(extent, dx + dwidth, dy); |
254 AddToExtent(extent, dx, dy + dheight); | 277 AddToExtent(extent, dx, dy + dheight); |
255 AddToExtent(extent, dx + dwidth, dy + dheight); | 278 AddToExtent(extent, dx + dwidth, dy + dheight); |
262 const ViewportGeometry& view) const | 285 const ViewportGeometry& view) const |
263 { | 286 { |
264 if (converted_.get() != NULL) | 287 if (converted_.get() != NULL) |
265 { | 288 { |
266 Matrix m = LinearAlgebra::Product(view.GetMatrix(), transform_); | 289 Matrix m = LinearAlgebra::Product(view.GetMatrix(), transform_); |
267 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); | 290 //ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); |
291 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Nearest, false); | |
268 } | 292 } |
269 } | 293 } |
270 | 294 |
271 | 295 |
272 bool Contains(double x, | 296 bool Contains(double x, |
284 { | 308 { |
285 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 309 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
286 } | 310 } |
287 else | 311 else |
288 { | 312 { |
313 printf("at: (%.02f, %.02f)\n", q[0], q[1]); | |
289 return (q[0] >= 0 && | 314 return (q[0] >= 0 && |
290 q[1] >= 0 && | 315 q[1] >= 0 && |
291 q[0] <= static_cast<double>(width_) && | 316 q[0] <= static_cast<double>(width_) && |
292 q[1] <= static_cast<double>(height_)); | 317 q[1] <= static_cast<double>(height_)); |
293 } | 318 } |
319 } | |
320 | |
321 | |
322 void SetPan(double x, | |
323 double y) | |
324 { | |
325 panX_ = x; | |
326 panY_ = y; | |
327 UpdateTransform(); | |
328 } | |
329 | |
330 | |
331 double GetPanX() const | |
332 { | |
333 return panX_; | |
334 } | |
335 | |
336 | |
337 double GetPanY() const | |
338 { | |
339 return panY_; | |
294 } | 340 } |
295 }; | 341 }; |
296 | 342 |
297 | 343 |
298 typedef std::map<size_t, Bitmap*> Bitmaps; | 344 typedef std::map<size_t, Bitmap*> Bitmaps; |
452 return extent; | 498 return extent; |
453 } | 499 } |
454 | 500 |
455 | 501 |
456 void Render(Orthanc::ImageAccessor& buffer, | 502 void Render(Orthanc::ImageAccessor& buffer, |
457 const ViewportGeometry& view) | 503 const ViewportGeometry& view) const |
458 { | 504 { |
459 Orthanc::ImageProcessing::Set(buffer, 0); | 505 Orthanc::ImageProcessing::Set(buffer, 0); |
460 | 506 |
461 for (Bitmaps::const_iterator it = bitmaps_.begin(); | 507 for (Bitmaps::const_iterator it = bitmaps_.begin(); |
462 it != bitmaps_.end(); ++it) | 508 it != bitmaps_.end(); ++it) |
463 { | 509 { |
464 assert(it->second != NULL); | 510 assert(it->second != NULL); |
465 it->second->Render(buffer, view); | 511 it->second->Render(buffer, view); |
466 } | 512 } |
467 } | 513 } |
514 | |
515 | |
516 bool LookupBitmap(size_t& index /* out */, | |
517 double x, | |
518 double y) const | |
519 { | |
520 for (Bitmaps::const_iterator it = bitmaps_.begin(); | |
521 it != bitmaps_.end(); ++it) | |
522 { | |
523 assert(it->second != NULL); | |
524 if (it->second->Contains(x, y)) | |
525 { | |
526 index = it->first; | |
527 return true; | |
528 } | |
529 } | |
530 | |
531 return false; | |
532 } | |
533 | |
534 | |
535 void SetPan(size_t index, | |
536 double panX, | |
537 double panY) | |
538 { | |
539 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
540 if (bitmap != bitmaps_.end()) | |
541 { | |
542 assert(bitmap->second != NULL); | |
543 bitmap->second->SetPan(panX, panY); | |
544 } | |
545 } | |
546 | |
547 | |
548 void GetPan(double& panX, | |
549 double& panY, | |
550 size_t index) const | |
551 { | |
552 Bitmaps::const_iterator bitmap = bitmaps_.find(index); | |
553 if (bitmap != bitmaps_.end()) | |
554 { | |
555 assert(bitmap->second != NULL); | |
556 panX = bitmap->second->GetPanX(); | |
557 panY = bitmap->second->GetPanY(); | |
558 } | |
559 else | |
560 { | |
561 panX = 0; | |
562 panY = 0; | |
563 } | |
564 } | |
468 }; | 565 }; |
469 | 566 |
470 | 567 |
471 class BitmapStackInteractor : public IWorldSceneInteractor | 568 class BitmapStackInteractor : public IWorldSceneInteractor |
472 { | 569 { |
570 private: | |
571 BitmapStack& stack_; | |
572 | |
573 | |
574 class MoveBitmapTracker : public IWorldSceneMouseTracker | |
575 { | |
576 private: | |
577 WorldSceneWidget& widget_; | |
578 BitmapStack& stack_; | |
579 size_t bitmap_; | |
580 double clickX_; | |
581 double clickY_; | |
582 | |
583 public: | |
584 MoveBitmapTracker(WorldSceneWidget& widget, | |
585 BitmapStack& stack, | |
586 size_t bitmap, | |
587 double x, | |
588 double y) : | |
589 widget_(widget), | |
590 stack_(stack), | |
591 bitmap_(bitmap), | |
592 clickX_(x), | |
593 clickY_(y) | |
594 { | |
595 double panX, panY; | |
596 stack.GetPan(panX, panY, bitmap_); | |
597 clickX_ -= panX; | |
598 clickY_ -= panY; | |
599 } | |
600 | |
601 virtual bool HasRender() const | |
602 { | |
603 return false; | |
604 } | |
605 | |
606 virtual void Render(CairoContext& context, | |
607 double zoom) | |
608 { | |
609 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
610 } | |
611 | |
612 virtual void MouseUp() | |
613 { | |
614 } | |
615 | |
616 virtual void MouseMove(int displayX, | |
617 int displayY, | |
618 double sceneX, | |
619 double sceneY) | |
620 { | |
621 stack_.SetPan(bitmap_, sceneX - clickX_, sceneY - clickY_); | |
622 } | |
623 }; | |
624 | |
625 | |
473 public: | 626 public: |
627 BitmapStackInteractor(BitmapStack& stack) : | |
628 stack_(stack) | |
629 { | |
630 } | |
631 | |
474 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, | 632 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
475 const ViewportGeometry& view, | 633 const ViewportGeometry& view, |
476 MouseButton button, | 634 MouseButton button, |
477 KeyboardModifiers modifiers, | 635 KeyboardModifiers modifiers, |
478 double x, | 636 double x, |
479 double y, | 637 double y, |
480 IStatusBar* statusBar) | 638 IStatusBar* statusBar) |
481 { | 639 { |
482 printf("CLICK\n"); | 640 if (button == MouseButton_Left) |
483 return NULL; | 641 { |
642 size_t bitmap; | |
643 if (stack_.LookupBitmap(bitmap, x, y)) | |
644 { | |
645 printf("CLICK on bitmap %d\n", bitmap); | |
646 return new MoveBitmapTracker(widget, stack_, bitmap, x, y); | |
647 } | |
648 else | |
649 { | |
650 printf("CLICK outside\n"); | |
651 return NULL; | |
652 } | |
653 } | |
654 else | |
655 { | |
656 return NULL; | |
657 } | |
484 } | 658 } |
485 | 659 |
486 virtual void MouseOver(CairoContext& context, | 660 virtual void MouseOver(CairoContext& context, |
487 WorldSceneWidget& widget, | 661 WorldSceneWidget& widget, |
488 const ViewportGeometry& view, | 662 const ViewportGeometry& view, |
503 KeyboardKeys key, | 677 KeyboardKeys key, |
504 char keyChar, | 678 char keyChar, |
505 KeyboardModifiers modifiers, | 679 KeyboardModifiers modifiers, |
506 IStatusBar* statusBar) | 680 IStatusBar* statusBar) |
507 { | 681 { |
682 if (keyChar == 's') | |
683 widget.FitContent(); | |
508 } | 684 } |
509 }; | 685 }; |
510 | 686 |
511 | 687 |
512 | 688 |
538 BitmapStack& stack, | 714 BitmapStack& stack, |
539 const std::string& name) : | 715 const std::string& name) : |
540 WorldSceneWidget(name), | 716 WorldSceneWidget(name), |
541 IObservable(broker), | 717 IObservable(broker), |
542 IObserver(broker), | 718 IObserver(broker), |
543 stack_(stack) | 719 stack_(stack), |
720 myInteractor_(stack_) | |
544 { | 721 { |
545 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); | 722 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); |
546 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); | 723 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); |
547 | 724 |
548 SetInteractor(myInteractor_); | 725 SetInteractor(myInteractor_); |