Mercurial > hg > orthanc-stone
annotate Applications/Samples/SingleFrameEditorApplication.h @ 344:fdec8e6893cb am-2
ordering of bitmap layers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 22 Oct 2018 14:48:18 +0200 |
parents | 712acc87fa2e |
children | 55438b1ca317 |
rev | line source |
---|---|
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1 /** |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2 * Stone of Orthanc |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
6 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
7 * This program is free software: you can redistribute it and/or |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Affero General Public License |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
9 * as published by the Free Software Foundation, either version 3 of |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
10 * the License, or (at your option) any later version. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
11 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
12 * This program is distributed in the hope that it will be useful, but |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
13 * WITHOUT ANY WARRANTY; without even the implied warranty of |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
15 * Affero General Public License for more details. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
16 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Affero General Public License |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
19 **/ |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
20 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
21 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
22 #pragma once |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
23 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
24 #include "SampleApplicationBase.h" |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
25 |
339 | 26 #include "../../Framework/Toolbox/GeometryToolbox.h" |
27 #include "../../Framework/Toolbox/ImageGeometry.h" | |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
28 #include "../../Framework/Layers/OrthancFrameLayerSource.h" |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
29 |
338 | 30 #include <Core/DicomFormat/DicomArray.h> |
343 | 31 #include <Core/Images/FontRegistry.h> |
339 | 32 #include <Core/Images/ImageProcessing.h> |
338 | 33 #include <Core/Images/PamReader.h> |
343 | 34 #include <Core/Images/PngWriter.h> //TODO |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
35 #include <Core/Logging.h> |
338 | 36 #include <Plugins/Samples/Common/FullOrthancDataset.h> |
339 | 37 #include <Plugins/Samples/Common/DicomDatasetReader.h> |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
38 |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
39 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
40 #include <boost/math/constants/constants.hpp> |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
41 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
42 namespace OrthancStone |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
43 { |
338 | 44 class BitmapStack : |
337 | 45 public IObserver, |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
46 public IObservable |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
47 { |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
48 public: |
338 | 49 typedef OriginMessage<MessageType_Widget_GeometryChanged, BitmapStack> GeometryChangedMessage; |
50 typedef OriginMessage<MessageType_Widget_ContentChanged, BitmapStack> ContentChangedMessage; | |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
51 |
337 | 52 private: |
338 | 53 class Bitmap : public boost::noncopyable |
54 { | |
55 private: | |
343 | 56 bool visible_; |
57 bool hasSize_; | |
58 unsigned int width_; | |
59 unsigned int height_; | |
60 bool hasCrop_; | |
61 unsigned int cropX_; | |
62 unsigned int cropY_; | |
63 unsigned int cropWidth_; | |
64 unsigned int cropHeight_; | |
65 Matrix transform_; | |
66 double pixelSpacingX_; | |
67 double pixelSpacingY_; | |
68 double panX_; | |
69 double panY_; | |
338 | 70 |
342 | 71 |
72 void UpdateTransform() | |
73 { | |
74 transform_ = LinearAlgebra::IdentityMatrix(3); | |
75 | |
76 transform_(0, 0) = pixelSpacingX_; | |
77 transform_(1, 1) = pixelSpacingY_; | |
78 transform_(0, 2) = panX_; | |
79 transform_(1, 2) = panY_; | |
80 | |
81 | |
82 #if 0 | |
83 double a = 10.0 / 180.0 * boost::math::constants::pi<double>(); | |
84 Matrix m; | |
85 const double v[] = { cos(a), -sin(a), 0, | |
86 sin(a), cos(a), 0, | |
87 0, 0, 1 }; | |
88 LinearAlgebra::FillMatrix(m, 3, 3, v); | |
89 transform_ = LinearAlgebra::Product(m, transform_); | |
90 #endif | |
91 } | |
92 | |
93 | |
339 | 94 void AddToExtent(Extent2D& extent, |
95 double x, | |
96 double y) const | |
97 { | |
98 Vector p; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
99 LinearAlgebra::AssignVector(p, x, y, 1); |
339 | 100 |
101 Vector q = LinearAlgebra::Product(transform_, p); | |
102 | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
103 if (!LinearAlgebra::IsNear(q[2], 1.0)) |
339 | 104 { |
105 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
106 } | |
107 else | |
108 { | |
109 extent.AddPoint(q[0], q[1]); | |
110 } | |
111 } | |
112 | |
113 | |
338 | 114 public: |
341 | 115 Bitmap() : |
339 | 116 visible_(true), |
343 | 117 hasSize_(false), |
339 | 118 width_(0), |
119 height_(0), | |
120 hasCrop_(false), | |
342 | 121 pixelSpacingX_(1), |
122 pixelSpacingY_(1), | |
123 panX_(0), | |
124 panY_(0) | |
339 | 125 { |
342 | 126 UpdateTransform(); |
339 | 127 } |
128 | |
343 | 129 virtual ~Bitmap() |
130 { | |
131 } | |
132 | |
339 | 133 void ResetCrop() |
134 { | |
135 hasCrop_ = false; | |
136 } | |
137 | |
138 void Crop(unsigned int x, | |
139 unsigned int y, | |
140 unsigned int width, | |
141 unsigned int height) | |
142 { | |
143 hasCrop_ = true; | |
144 cropX_ = x; | |
145 cropY_ = y; | |
146 cropWidth_ = width; | |
147 cropHeight_ = height; | |
148 } | |
149 | |
150 void GetCrop(unsigned int& x, | |
151 unsigned int& y, | |
152 unsigned int& width, | |
153 unsigned int& height) const | |
338 | 154 { |
339 | 155 if (hasCrop_) |
156 { | |
157 x = cropX_; | |
158 y = cropY_; | |
159 width = cropWidth_; | |
160 height = cropHeight_; | |
161 } | |
162 else | |
163 { | |
164 x = 0; | |
165 y = 0; | |
166 width = width_; | |
167 height = height_; | |
168 } | |
169 } | |
170 | |
171 bool IsVisible() const | |
172 { | |
173 return visible_; | |
174 } | |
175 | |
176 void SetVisible(bool visible) | |
177 { | |
178 visible_ = visible; | |
179 } | |
180 | |
181 | |
343 | 182 void SetSize(unsigned int width, |
183 unsigned int height) | |
338 | 184 { |
343 | 185 if (hasSize_ && |
186 (width != width_ || | |
187 height != height_)) | |
339 | 188 { |
343 | 189 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
190 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
191 |
343 | 192 hasSize_ = true; |
193 width_ = width; | |
194 height_ = height; | |
338 | 195 } |
196 | |
343 | 197 |
198 void CheckSize(unsigned int width, | |
199 unsigned int height) | |
338 | 200 { |
343 | 201 if (hasSize_ && |
202 (width != width_ || | |
203 height != height_)) | |
338 | 204 { |
343 | 205 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
339 | 206 } |
207 } | |
343 | 208 |
339 | 209 |
210 Extent2D GetExtent() const | |
211 { | |
212 Extent2D extent; | |
213 | |
214 unsigned int x, y, width, height; | |
215 GetCrop(x, y, width, height); | |
216 | |
217 double dx = static_cast<double>(x) - 0.5; | |
218 double dy = static_cast<double>(y) - 0.5; | |
219 double dwidth = static_cast<double>(width); | |
220 double dheight = static_cast<double>(height); | |
342 | 221 |
339 | 222 AddToExtent(extent, dx, dy); |
223 AddToExtent(extent, dx + dwidth, dy); | |
224 AddToExtent(extent, dx, dy + dheight); | |
225 AddToExtent(extent, dx + dwidth, dy + dheight); | |
226 | |
227 return extent; | |
228 } | |
229 | |
230 | |
343 | 231 virtual void Render(Orthanc::ImageAccessor& buffer, |
232 const ViewportGeometry& view) const = 0; | |
341 | 233 |
234 | |
235 bool Contains(double x, | |
236 double y) const | |
237 { | |
238 Matrix inv; | |
239 LinearAlgebra::InvertMatrix(inv, transform_); | |
240 | |
241 Vector p; | |
242 LinearAlgebra::AssignVector(p, x, y, 1); | |
243 | |
244 Vector q = LinearAlgebra::Product(inv, p); | |
245 | |
246 if (!LinearAlgebra::IsNear(q[2], 1.0)) | |
247 { | |
248 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
249 } | |
250 else | |
251 { | |
342 | 252 printf("at: (%.02f, %.02f)\n", q[0], q[1]); |
341 | 253 return (q[0] >= 0 && |
254 q[1] >= 0 && | |
255 q[0] <= static_cast<double>(width_) && | |
256 q[1] <= static_cast<double>(height_)); | |
257 } | |
258 } | |
342 | 259 |
260 | |
261 void SetPan(double x, | |
262 double y) | |
263 { | |
264 panX_ = x; | |
265 panY_ = y; | |
266 UpdateTransform(); | |
267 } | |
268 | |
269 | |
343 | 270 void SetPixelSpacing(double x, |
271 double y) | |
272 { | |
273 pixelSpacingX_ = x; | |
274 pixelSpacingY_ = y; | |
275 UpdateTransform(); | |
276 } | |
277 | |
278 | |
342 | 279 double GetPanX() const |
280 { | |
281 return panX_; | |
282 } | |
283 | |
284 | |
285 double GetPanY() const | |
286 { | |
287 return panY_; | |
288 } | |
343 | 289 |
290 | |
291 virtual bool GetDefaultWindowing(float& center, | |
292 float& width) const | |
293 { | |
294 return false; | |
295 } | |
296 | |
297 | |
298 const Matrix& GetTransform() const | |
299 { | |
300 return transform_; | |
301 } | |
338 | 302 }; |
303 | |
304 | |
343 | 305 |
306 class DicomBitmap : public Bitmap | |
307 { | |
308 private: | |
309 std::auto_ptr<Orthanc::ImageAccessor> source_; // Content of PixelData | |
310 std::auto_ptr<DicomFrameConverter> converter_; | |
311 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 or RGB24 | |
312 | |
313 | |
314 void ApplyConverter() | |
315 { | |
316 if (source_.get() != NULL && | |
317 converter_.get() != NULL) | |
318 { | |
319 converted_.reset(converter_->ConvertFrame(*source_)); | |
320 } | |
321 } | |
322 | |
323 public: | |
324 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag) | |
325 { | |
326 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement()); | |
327 } | |
328 | |
329 void SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset) | |
330 { | |
331 converter_.reset(new DicomFrameConverter); | |
332 converter_->ReadParameters(dataset); | |
333 ApplyConverter(); | |
334 | |
335 std::string tmp; | |
336 Vector pixelSpacing; | |
337 | |
338 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && | |
339 LinearAlgebra::ParseVector(pixelSpacing, tmp) && | |
340 pixelSpacing.size() == 2) | |
341 { | |
342 SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]); | |
343 } | |
344 | |
345 static unsigned int c = 0; | |
346 if (c == 0) | |
347 { | |
348 SetPan(400, 0); | |
349 c ++; | |
350 } | |
351 | |
352 OrthancPlugins::DicomDatasetReader reader(dataset); | |
353 | |
354 unsigned int width, height; | |
355 if (!reader.GetUnsignedIntegerValue(width, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) || | |
356 !reader.GetUnsignedIntegerValue(height, ConvertTag(Orthanc::DICOM_TAG_ROWS))) | |
357 { | |
358 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
359 } | |
360 else | |
361 { | |
362 SetSize(width, height); | |
363 } | |
364 } | |
365 | |
366 | |
367 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership | |
368 { | |
369 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
370 | |
371 if (image == NULL) | |
372 { | |
373 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
374 } | |
375 | |
376 SetSize(image->GetWidth(), image->GetHeight()); | |
377 | |
378 source_ = raii; | |
379 ApplyConverter(); | |
380 } | |
381 | |
382 | |
383 virtual void Render(Orthanc::ImageAccessor& buffer, | |
384 const ViewportGeometry& view) const | |
385 { | |
386 if (converted_.get() != NULL) | |
387 { | |
388 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform()); | |
389 //ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); | |
390 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Nearest, false); | |
391 } | |
392 } | |
393 | |
394 | |
395 virtual bool GetDefaultWindowing(float& center, | |
396 float& width) const | |
397 { | |
398 if (converter_.get() != NULL && | |
399 converter_->HasDefaultWindow()) | |
400 { | |
401 center = static_cast<float>(converter_->GetDefaultWindowCenter()); | |
402 width = static_cast<float>(converter_->GetDefaultWindowWidth()); | |
403 return true; | |
404 } | |
405 else | |
406 { | |
407 return false; | |
408 } | |
409 } | |
410 }; | |
411 | |
412 | |
413 | |
414 | |
415 class AlphaBitmap : public Bitmap | |
416 { | |
417 private: | |
418 const BitmapStack& stack_; | |
419 std::auto_ptr<Orthanc::ImageAccessor> alpha_; // Grayscale8 | |
420 bool useWindowing_; | |
421 float foreground_; | |
422 | |
423 public: | |
424 AlphaBitmap(const BitmapStack& stack) : | |
425 stack_(stack), | |
426 useWindowing_(true), | |
427 foreground_(0) | |
428 { | |
429 } | |
430 | |
431 | |
432 void SetForegroundValue(float foreground) | |
433 { | |
434 useWindowing_ = false; | |
435 foreground_ = foreground; | |
436 } | |
437 | |
438 | |
439 void SetAlpha(Orthanc::ImageAccessor* image) | |
440 { | |
441 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
442 | |
443 if (image == NULL) | |
444 { | |
445 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
446 } | |
447 | |
448 if (image->GetFormat() != Orthanc::PixelFormat_Grayscale8) | |
449 { | |
450 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
451 } | |
452 | |
453 SetSize(image->GetWidth(), image->GetHeight()); | |
454 alpha_ = raii; | |
455 } | |
456 | |
457 | |
458 void LoadText(const Orthanc::Font& font, | |
459 const std::string& utf8) | |
460 { | |
461 SetAlpha(font.RenderAlpha(utf8)); | |
462 } | |
463 | |
464 | |
465 virtual void Render(Orthanc::ImageAccessor& buffer, | |
466 const ViewportGeometry& view) const | |
467 { | |
468 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32) | |
469 { | |
470 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
471 } | |
472 | |
473 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform()); | |
474 | |
475 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false); | |
476 ApplyProjectiveTransform(tmp, *alpha_, m, ImageInterpolation_Nearest, true /* clear */); | |
477 | |
478 // Blit | |
479 const unsigned int width = buffer.GetWidth(); | |
480 const unsigned int height = buffer.GetHeight(); | |
481 | |
482 float value = foreground_; | |
483 | |
484 if (useWindowing_) | |
485 { | |
486 float center, width; | |
487 if (stack_.GetWindowing(center, width)) | |
488 { | |
489 value = center + width / 2.0f; | |
490 } | |
491 } | |
492 | |
493 for (unsigned int y = 0; y < height; y++) | |
494 { | |
495 float *q = reinterpret_cast<float*>(buffer.GetRow(y)); | |
496 const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y)); | |
497 | |
498 for (unsigned int x = 0; x < width; x++, p++, q++) | |
499 { | |
500 float a = static_cast<float>(*p) / 255.0f; | |
501 | |
502 *q = (a * value + (1.0f - a) * (*q)); | |
503 } | |
504 } | |
505 } | |
506 }; | |
507 | |
508 | |
509 | |
341 | 510 typedef std::map<size_t, Bitmap*> Bitmaps; |
338 | 511 |
341 | 512 OrthancApiClient& orthanc_; |
513 size_t countBitmaps_; | |
514 bool hasWindowing_; | |
515 float windowingCenter_; | |
516 float windowingWidth_; | |
517 Bitmaps bitmaps_; | |
338 | 518 |
519 public: | |
520 BitmapStack(MessageBroker& broker, | |
521 OrthancApiClient& orthanc) : | |
522 IObserver(broker), | |
523 IObservable(broker), | |
524 orthanc_(orthanc), | |
341 | 525 countBitmaps_(0), |
338 | 526 hasWindowing_(false), |
527 windowingCenter_(0), // Dummy initialization | |
528 windowingWidth_(0) // Dummy initialization | |
529 { | |
530 } | |
531 | |
532 | |
533 virtual ~BitmapStack() | |
534 { | |
535 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++) | |
536 { | |
537 assert(it->second != NULL); | |
538 delete it->second; | |
539 } | |
540 } | |
339 | 541 |
542 | |
343 | 543 bool GetWindowing(float& center, |
544 float& width) const | |
339 | 545 { |
546 if (hasWindowing_) | |
547 { | |
548 center = windowingCenter_; | |
549 width = windowingWidth_; | |
343 | 550 return true; |
339 | 551 } |
552 else | |
553 { | |
343 | 554 return false; |
339 | 555 } |
556 } | |
338 | 557 |
558 | |
343 | 559 size_t LoadText(const Orthanc::Font& font, |
560 const std::string& utf8, | |
561 double x, | |
562 double y) | |
563 { | |
564 std::auto_ptr<AlphaBitmap> alpha(new AlphaBitmap(*this)); | |
565 alpha->LoadText(font, utf8); | |
566 | |
567 size_t bitmap = countBitmaps_++; | |
568 | |
569 bitmaps_[bitmap] = alpha.release(); | |
570 | |
571 return bitmap; | |
572 } | |
573 | |
574 | |
341 | 575 size_t LoadFrame(const std::string& instance, |
576 unsigned int frame, | |
577 bool httpCompression) | |
338 | 578 { |
341 | 579 size_t bitmap = countBitmaps_++; |
338 | 580 |
343 | 581 bitmaps_[bitmap] = new DicomBitmap; |
338 | 582 |
583 | |
584 { | |
585 IWebService::Headers headers; | |
586 std::string uri = "/instances/" + instance + "/tags"; | |
587 orthanc_.GetBinaryAsync(uri, headers, | |
588 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
589 (*this, &BitmapStack::OnTagsReceived), NULL, | |
341 | 590 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 591 } |
592 | |
593 { | |
594 IWebService::Headers headers; | |
595 headers["Accept"] = "image/x-portable-arbitrarymap"; | |
596 | |
597 if (httpCompression) | |
598 { | |
599 headers["Accept-Encoding"] = "gzip"; | |
600 } | |
601 | |
602 std::string uri = "/instances/" + instance + "/frames/" + boost::lexical_cast<std::string>(frame) + "/image-uint16"; | |
603 orthanc_.GetBinaryAsync(uri, headers, | |
604 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
605 (*this, &BitmapStack::OnFrameReceived), NULL, | |
341 | 606 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 607 } |
608 | |
341 | 609 return bitmap; |
338 | 610 } |
611 | |
612 | |
613 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
614 { | |
341 | 615 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); |
338 | 616 |
341 | 617 printf("JSON received: [%s] (%ld bytes) for bitmap %ld\n", |
618 message.Uri.c_str(), message.AnswerSize, index); | |
338 | 619 |
341 | 620 Bitmaps::iterator bitmap = bitmaps_.find(index); |
338 | 621 if (bitmap != bitmaps_.end()) |
622 { | |
623 assert(bitmap->second != NULL); | |
624 | |
625 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize); | |
343 | 626 dynamic_cast<DicomBitmap*>(bitmap->second)->SetDicomTags(dicom); |
338 | 627 |
628 float c, w; | |
629 if (!hasWindowing_ && | |
630 bitmap->second->GetDefaultWindowing(c, w)) | |
631 { | |
632 hasWindowing_ = true; | |
633 windowingCenter_ = c; | |
634 windowingWidth_ = w; | |
635 } | |
636 | |
637 EmitMessage(GeometryChangedMessage(*this)); | |
638 } | |
639 } | |
640 | |
641 | |
642 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
643 { | |
341 | 644 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); |
338 | 645 |
341 | 646 printf("Frame received: [%s] (%ld bytes) for bitmap %ld\n", |
647 message.Uri.c_str(), message.AnswerSize, index); | |
648 | |
649 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
338 | 650 if (bitmap != bitmaps_.end()) |
651 { | |
652 assert(bitmap->second != NULL); | |
653 | |
654 std::string content; | |
655 if (message.AnswerSize > 0) | |
656 { | |
657 content.assign(reinterpret_cast<const char*>(message.Answer), message.AnswerSize); | |
658 } | |
659 | |
660 std::auto_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader); | |
661 reader->ReadFromMemory(content); | |
343 | 662 dynamic_cast<DicomBitmap*>(bitmap->second)->SetSourceImage(reader.release()); |
338 | 663 |
664 EmitMessage(ContentChangedMessage(*this)); | |
665 } | |
666 } | |
339 | 667 |
668 | |
669 Extent2D GetSceneExtent() const | |
670 { | |
671 Extent2D extent; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
672 |
339 | 673 for (Bitmaps::const_iterator it = bitmaps_.begin(); |
674 it != bitmaps_.end(); ++it) | |
675 { | |
676 assert(it->second != NULL); | |
677 extent.Union(it->second->GetExtent()); | |
678 } | |
679 | |
680 return extent; | |
681 } | |
682 | |
683 | |
684 void Render(Orthanc::ImageAccessor& buffer, | |
342 | 685 const ViewportGeometry& view) const |
339 | 686 { |
687 Orthanc::ImageProcessing::Set(buffer, 0); | |
688 | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
689 // Render layers in the background-to-foreground order |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
690 for (size_t index = 0; index < countBitmaps_; index++) |
339 | 691 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
692 Bitmaps::const_iterator it = bitmaps_.find(index); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
693 if (it != bitmaps_.end()) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
694 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
695 assert(it->second != NULL); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
696 it->second->Render(buffer, view); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
697 } |
339 | 698 } |
699 } | |
342 | 700 |
701 | |
702 bool LookupBitmap(size_t& index /* out */, | |
703 double x, | |
704 double y) const | |
705 { | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
706 // Render layers in the foreground-to-background order |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
707 for (size_t i = countBitmaps_; i > 0; i--) |
342 | 708 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
709 index = i - 1; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
710 Bitmaps::const_iterator it = bitmaps_.find(index); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
711 if (it != bitmaps_.end()) |
342 | 712 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
713 assert(it->second != NULL); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
714 if (it->second->Contains(x, y)) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
715 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
716 return true; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
717 } |
342 | 718 } |
719 } | |
720 | |
721 return false; | |
722 } | |
723 | |
724 | |
725 void SetPan(size_t index, | |
726 double panX, | |
727 double panY) | |
728 { | |
729 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
730 if (bitmap != bitmaps_.end()) | |
731 { | |
732 assert(bitmap->second != NULL); | |
733 bitmap->second->SetPan(panX, panY); | |
734 } | |
735 } | |
736 | |
737 | |
738 void GetPan(double& panX, | |
739 double& panY, | |
740 size_t index) const | |
741 { | |
742 Bitmaps::const_iterator bitmap = bitmaps_.find(index); | |
743 if (bitmap != bitmaps_.end()) | |
744 { | |
745 assert(bitmap->second != NULL); | |
746 panX = bitmap->second->GetPanX(); | |
747 panY = bitmap->second->GetPanY(); | |
748 } | |
749 else | |
750 { | |
751 panX = 0; | |
752 panY = 0; | |
753 } | |
754 } | |
338 | 755 }; |
756 | |
341 | 757 |
758 class BitmapStackInteractor : public IWorldSceneInteractor | |
759 { | |
342 | 760 private: |
761 BitmapStack& stack_; | |
762 | |
763 | |
764 class MoveBitmapTracker : public IWorldSceneMouseTracker | |
765 { | |
766 private: | |
767 BitmapStack& stack_; | |
768 size_t bitmap_; | |
769 double clickX_; | |
770 double clickY_; | |
343 | 771 double panX_; |
772 double panY_; | |
773 bool oneAxis_; | |
342 | 774 |
775 public: | |
343 | 776 MoveBitmapTracker(BitmapStack& stack, |
342 | 777 size_t bitmap, |
778 double x, | |
343 | 779 double y, |
780 bool oneAxis) : | |
342 | 781 stack_(stack), |
782 bitmap_(bitmap), | |
783 clickX_(x), | |
343 | 784 clickY_(y), |
785 oneAxis_(oneAxis) | |
342 | 786 { |
343 | 787 stack.GetPan(panX_, panY_, bitmap_); |
342 | 788 } |
789 | |
790 virtual bool HasRender() const | |
791 { | |
792 return false; | |
793 } | |
794 | |
795 virtual void Render(CairoContext& context, | |
796 double zoom) | |
797 { | |
798 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
799 } | |
800 | |
801 virtual void MouseUp() | |
802 { | |
803 } | |
804 | |
805 virtual void MouseMove(int displayX, | |
806 int displayY, | |
807 double sceneX, | |
808 double sceneY) | |
809 { | |
343 | 810 double dx = sceneX - clickX_; |
811 double dy = sceneY - clickY_; | |
812 | |
813 if (oneAxis_) | |
814 { | |
815 if (fabs(dx) > fabs(dy)) | |
816 { | |
817 stack_.SetPan(bitmap_, dx + panX_, panY_); | |
818 } | |
819 else | |
820 { | |
821 stack_.SetPan(bitmap_, panX_, dy + panY_); | |
822 } | |
823 } | |
824 else | |
825 { | |
826 stack_.SetPan(bitmap_, dx + panX_, dy + panY_); | |
827 } | |
342 | 828 } |
829 }; | |
830 | |
831 | |
341 | 832 public: |
342 | 833 BitmapStackInteractor(BitmapStack& stack) : |
834 stack_(stack) | |
835 { | |
836 } | |
837 | |
341 | 838 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
839 const ViewportGeometry& view, | |
840 MouseButton button, | |
841 KeyboardModifiers modifiers, | |
842 double x, | |
843 double y, | |
844 IStatusBar* statusBar) | |
845 { | |
342 | 846 if (button == MouseButton_Left) |
847 { | |
848 size_t bitmap; | |
849 if (stack_.LookupBitmap(bitmap, x, y)) | |
850 { | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
851 printf("CLICK on bitmap %ld\n", bitmap); |
343 | 852 return new MoveBitmapTracker(stack_, bitmap, x, y, |
853 (modifiers & KeyboardModifiers_Shift)); | |
342 | 854 } |
855 else | |
856 { | |
857 printf("CLICK outside\n"); | |
858 return NULL; | |
859 } | |
860 } | |
861 else | |
862 { | |
863 return NULL; | |
864 } | |
341 | 865 } |
866 | |
867 virtual void MouseOver(CairoContext& context, | |
868 WorldSceneWidget& widget, | |
869 const ViewportGeometry& view, | |
870 double x, | |
871 double y, | |
872 IStatusBar* statusBar) | |
873 { | |
874 } | |
875 | |
876 virtual void MouseWheel(WorldSceneWidget& widget, | |
877 MouseWheelDirection direction, | |
878 KeyboardModifiers modifiers, | |
879 IStatusBar* statusBar) | |
880 { | |
881 } | |
882 | |
883 virtual void KeyPressed(WorldSceneWidget& widget, | |
884 KeyboardKeys key, | |
885 char keyChar, | |
886 KeyboardModifiers modifiers, | |
887 IStatusBar* statusBar) | |
888 { | |
342 | 889 if (keyChar == 's') |
890 widget.FitContent(); | |
341 | 891 } |
892 }; | |
893 | |
894 | |
338 | 895 |
896 class BitmapStackWidget : | |
897 public WorldSceneWidget, | |
898 public IObservable, | |
899 public IObserver | |
900 { | |
901 private: | |
341 | 902 BitmapStack& stack_; |
903 BitmapStackInteractor myInteractor_; | |
337 | 904 |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
905 protected: |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
906 virtual Extent2D GetSceneExtent() |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
907 { |
339 | 908 return stack_.GetSceneExtent(); |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
909 } |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
910 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
911 virtual bool RenderScene(CairoContext& context, |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
912 const ViewportGeometry& view) |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
913 { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
914 // "Render()" has been replaced |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
915 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
916 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
917 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
918 public: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
919 BitmapStackWidget(MessageBroker& broker, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
920 BitmapStack& stack, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
921 const std::string& name) : |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
922 WorldSceneWidget(name), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
923 IObservable(broker), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
924 IObserver(broker), |
342 | 925 stack_(stack), |
926 myInteractor_(stack_) | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
927 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
928 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
929 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); |
341 | 930 |
931 SetInteractor(myInteractor_); | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
932 } |
339 | 933 |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
934 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
935 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
936 printf("Geometry has changed\n"); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
937 FitContent(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
938 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
939 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
940 void OnContentChanged(const BitmapStack::ContentChangedMessage& message) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
941 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
942 printf("Content has changed\n"); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
943 NotifyContentChanged(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
944 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
945 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
946 virtual bool Render(Orthanc::ImageAccessor& target) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
947 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
948 Orthanc::Image buffer(Orthanc::PixelFormat_Float32, target.GetWidth(), |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
949 target.GetHeight(), false); |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
950 stack_.Render(buffer, GetView()); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
951 |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
952 // As in GrayscaleFrameRenderer => TODO MERGE? |
339 | 953 |
954 float windowCenter, windowWidth; | |
343 | 955 if (!stack_.GetWindowing(windowCenter, windowWidth)) |
956 { | |
957 windowCenter = 128; | |
958 windowWidth = 256; | |
959 } | |
339 | 960 |
961 float x0 = windowCenter - windowWidth / 2.0f; | |
962 float x1 = windowCenter + windowWidth / 2.0f; | |
963 | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
964 if (windowWidth >= 0.001f) // Avoid division by zero at (*) |
339 | 965 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
966 const unsigned int width = target.GetWidth(); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
967 const unsigned int height = target.GetHeight(); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
968 |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
969 for (unsigned int y = 0; y < height; y++) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
970 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
971 const float* p = reinterpret_cast<const float*>(buffer.GetConstRow(y)); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
972 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); |
339 | 973 |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
974 for (unsigned int x = 0; x < width; x++, p++, q += 4) |
339 | 975 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
976 uint8_t v = 0; |
339 | 977 if (*p >= x1) |
978 { | |
979 v = 255; | |
980 } | |
981 else if (*p <= x0) | |
982 { | |
983 v = 0; | |
984 } | |
985 else | |
986 { | |
987 // https://en.wikipedia.org/wiki/Linear_interpolation | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
988 v = static_cast<uint8_t>(255.0f * (*p - x0) / (x1 - x0)); // (*) |
339 | 989 } |
990 | |
991 // TODO MONOCHROME1 | |
992 /*if (invert_) | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
993 { |
339 | 994 v = 255 - v; |
995 }*/ | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
996 |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
997 q[0] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
998 q[1] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
999 q[2] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1000 q[3] = 255; |
339 | 1001 } |
1002 } | |
1003 } | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1004 else |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1005 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1006 Orthanc::ImageProcessing::Set(target, 0, 0, 0, 255); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1007 } |
339 | 1008 |
337 | 1009 return true; |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1010 } |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1011 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1012 }; |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1013 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1014 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1015 namespace Samples |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1016 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1017 class SingleFrameEditorApplication : |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1018 public SampleSingleCanvasApplicationBase, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1019 public IObserver |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1020 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1021 enum Tools |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1022 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1023 Tools_Crop, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1024 Tools_Windowing, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1025 Tools_Zoom, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1026 Tools_Pan |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1027 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1028 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1029 enum Actions |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1030 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1031 Actions_Invert, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1032 Actions_RotateLeft, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1033 Actions_RotateRight |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1034 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1035 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1036 private: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1037 class Interactor : public IWorldSceneInteractor |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1038 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1039 private: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1040 SingleFrameEditorApplication& application_; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1041 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1042 public: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1043 Interactor(SingleFrameEditorApplication& application) : |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1044 application_(application) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1045 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1046 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1047 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1048 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1049 const ViewportGeometry& view, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1050 MouseButton button, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1051 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1052 double x, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1053 double y, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1054 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1055 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1056 switch (application_.currentTool_) { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1057 case Tools_Zoom: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1058 printf("ZOOM\n"); |
329
b10dfdb96866
removing WorldSceneWidget::IWorldObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
1059 |
b10dfdb96866
removing WorldSceneWidget::IWorldObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
1060 case Tools_Crop: |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1061 case Tools_Windowing: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1062 case Tools_Pan: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1063 // TODO return the right mouse tracker |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1064 return NULL; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1065 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1066 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1067 return NULL; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1068 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1069 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1070 virtual void MouseOver(CairoContext& context, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1071 WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1072 const ViewportGeometry& view, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1073 double x, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1074 double y, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1075 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1076 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1077 if (statusBar != NULL) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1078 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1079 char buf[64]; |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1080 sprintf(buf, "X = %.02f Y = %.02f (in cm)", x / 10.0, y / 10.0); |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1081 statusBar->SetMessage(buf); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1082 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1083 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1084 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1085 virtual void MouseWheel(WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1086 MouseWheelDirection direction, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1087 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1088 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1089 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1090 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1091 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1092 virtual void KeyPressed(WorldSceneWidget& widget, |
327 | 1093 KeyboardKeys key, |
1094 char keyChar, | |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1095 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1096 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1097 { |
327 | 1098 switch (keyChar) |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1099 { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1100 case 's': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1101 widget.FitContent(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1102 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1103 case 'p': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1104 application_.currentTool_ = Tools_Pan; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1105 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1106 case 'z': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1107 application_.currentTool_ = Tools_Zoom; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1108 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1109 case 'c': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1110 application_.currentTool_ = Tools_Crop; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1111 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1112 case 'w': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1113 application_.currentTool_ = Tools_Windowing; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1114 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1115 case 'i': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1116 application_.Invert(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1117 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1118 case 'r': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1119 if (modifiers == KeyboardModifiers_None) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1120 application_.Rotate(90); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1121 else |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1122 application_.Rotate(-90); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1123 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1124 case 'e': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1125 application_.Export(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1126 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1127 default: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1128 break; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1129 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1130 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1131 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1132 |
334
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1133 std::auto_ptr<Interactor> mainWidgetInteractor_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1134 std::auto_ptr<OrthancApiClient> orthancApiClient_; |
338 | 1135 std::auto_ptr<BitmapStack> stack_; |
334
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1136 Tools currentTool_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1137 const OrthancFrameLayerSource* source_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1138 unsigned int slice_; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1139 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1140 public: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1141 SingleFrameEditorApplication(MessageBroker& broker) : |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1142 IObserver(broker), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1143 currentTool_(Tools_Zoom), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1144 source_(NULL), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1145 slice_(0) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1146 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1147 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1148 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1149 virtual void DeclareStartupOptions(boost::program_options::options_description& options) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1150 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1151 boost::program_options::options_description generic("Sample options"); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1152 generic.add_options() |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1153 ("instance", boost::program_options::value<std::string>(), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1154 "Orthanc ID of the instance") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1155 ("frame", boost::program_options::value<unsigned int>()->default_value(0), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1156 "Number of the frame, for multi-frame DICOM instances") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1157 ; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1158 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1159 options.add(generic); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1160 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1161 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1162 virtual void Initialize(StoneApplicationContext* context, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1163 IStatusBar& statusBar, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1164 const boost::program_options::variables_map& parameters) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1165 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1166 using namespace OrthancStone; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1167 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1168 context_ = context; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1169 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1170 statusBar.SetMessage("Use the key \"s\" to reinitialize the layout, \"p\" to pan, \"z\" to zoom, \"c\" to crop, \"i\" to invert, \"w\" to change windowing, \"r\" to rotate cw, \"shift+r\" to rotate ccw"); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1171 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1172 if (parameters.count("instance") != 1) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1173 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1174 LOG(ERROR) << "The instance ID is missing"; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1175 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1176 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1177 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1178 std::string instance = parameters["instance"].as<std::string>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1179 int frame = parameters["frame"].as<unsigned int>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1180 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1181 orthancApiClient_.reset(new OrthancApiClient(IObserver::broker_, context_->GetWebService())); |
337 | 1182 |
343 | 1183 Orthanc::FontRegistry fonts; |
1184 fonts.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); | |
1185 | |
338 | 1186 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_)); |
1187 stack_->LoadFrame(instance, frame, false); | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1188 stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", frame, false); |
343 | 1189 stack_->LoadText(fonts.GetFont(0), "Hello\nworld\nBonjour, Alain", 0, -50); |
337 | 1190 |
338 | 1191 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1192 mainWidget_->SetTransmitMouseOver(true); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1193 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1194 mainWidgetInteractor_.reset(new Interactor(*this)); |
341 | 1195 //mainWidget_->SetInteractor(*mainWidgetInteractor_); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1196 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1197 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1198 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1199 void Invert() |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1200 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1201 // TODO |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1202 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1203 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1204 void Rotate(int degrees) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1205 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1206 // TODO |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1207 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1208 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1209 void Export() |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1210 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1211 // TODO: export dicom file to a temporary file |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1212 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1213 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1214 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1215 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1216 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1217 } |