Mercurial > hg > orthanc-stone
annotate Framework/Radiography/RadiographyScene.cpp @ 628:84af39146e76 am-dev
CodeGeneration: support default values
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Wed, 08 May 2019 16:32:57 +0200 |
parents | 848170ca4351 |
children | 7a7e36c52d62 |
rev | line source |
---|---|
408 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
439 | 5 * Copyright (C) 2017-2019 Osimis S.A., Belgium |
408 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "RadiographyScene.h" | |
23 | |
430 | 24 #include "RadiographyAlphaLayer.h" |
25 #include "RadiographyDicomLayer.h" | |
26 #include "RadiographyTextLayer.h" | |
475
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
27 #include "RadiographyMaskLayer.h" |
408 | 28 #include "../Toolbox/DicomFrameConverter.h" |
29 | |
30 #include <Core/Images/Image.h> | |
31 #include <Core/Images/ImageProcessing.h> | |
32 #include <Core/Images/PamReader.h> | |
33 #include <Core/Images/PamWriter.h> | |
34 #include <Core/Images/PngWriter.h> | |
35 #include <Core/OrthancException.h> | |
36 #include <Core/Toolbox.h> | |
37 #include <Plugins/Samples/Common/DicomDatasetReader.h> | |
38 #include <Plugins/Samples/Common/FullOrthancDataset.h> | |
39 | |
412 | 40 #include <boost/math/special_functions/round.hpp> |
41 | |
408 | 42 |
43 namespace OrthancStone | |
44 { | |
45 RadiographyScene::LayerAccessor::LayerAccessor(RadiographyScene& scene, | |
46 size_t index) : | |
47 scene_(scene), | |
48 index_(index) | |
49 { | |
50 Layers::iterator layer = scene.layers_.find(index); | |
51 if (layer == scene.layers_.end()) | |
52 { | |
53 layer_ = NULL; | |
54 } | |
55 else | |
56 { | |
57 assert(layer->second != NULL); | |
58 layer_ = layer->second; | |
59 } | |
60 } | |
61 | |
426 | 62 |
408 | 63 RadiographyScene::LayerAccessor::LayerAccessor(RadiographyScene& scene, |
64 double x, | |
65 double y) : | |
66 scene_(scene), | |
67 index_(0) // Dummy initialization | |
68 { | |
69 if (scene.LookupLayer(index_, x, y)) | |
70 { | |
71 Layers::iterator layer = scene.layers_.find(index_); | |
426 | 72 |
408 | 73 if (layer == scene.layers_.end()) |
74 { | |
75 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
76 } | |
77 else | |
78 { | |
79 assert(layer->second != NULL); | |
80 layer_ = layer->second; | |
81 } | |
82 } | |
83 else | |
84 { | |
85 layer_ = NULL; | |
86 } | |
87 } | |
88 | |
89 | |
90 RadiographyScene& RadiographyScene::LayerAccessor::GetScene() const | |
91 { | |
92 if (IsValid()) | |
93 { | |
94 return scene_; | |
95 } | |
96 else | |
97 { | |
98 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
99 } | |
100 } | |
101 | |
102 | |
103 size_t RadiographyScene::LayerAccessor::GetIndex() const | |
104 { | |
105 if (IsValid()) | |
106 { | |
107 return index_; | |
108 } | |
109 else | |
110 { | |
111 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
112 } | |
113 } | |
114 | |
115 | |
410
6decc0ba9da5
rename RadiographyScene::Layer as RadiographyLayer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
409
diff
changeset
|
116 RadiographyLayer& RadiographyScene::LayerAccessor::GetLayer() const |
408 | 117 { |
118 if (IsValid()) | |
119 { | |
120 return *layer_; | |
121 } | |
122 else | |
123 { | |
124 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
125 } | |
426 | 126 } |
408 | 127 |
410
6decc0ba9da5
rename RadiographyScene::Layer as RadiographyLayer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
409
diff
changeset
|
128 RadiographyLayer& RadiographyScene::RegisterLayer(RadiographyLayer* layer) |
408 | 129 { |
130 if (layer == NULL) | |
131 { | |
132 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
133 } | |
134 | |
410
6decc0ba9da5
rename RadiographyScene::Layer as RadiographyLayer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
409
diff
changeset
|
135 std::auto_ptr<RadiographyLayer> raii(layer); |
426 | 136 |
428
751fb354149e
ability to change the scene of the RadiographyWidget
am@osimis.io
parents:
426
diff
changeset
|
137 LOG(INFO) << "Registering layer: " << countLayers_; |
751fb354149e
ability to change the scene of the RadiographyWidget
am@osimis.io
parents:
426
diff
changeset
|
138 |
408 | 139 size_t index = countLayers_++; |
140 raii->SetIndex(index); | |
141 layers_[index] = raii.release(); | |
142 | |
430 | 143 EmitMessage(GeometryChangedMessage(*this, *layer)); |
144 EmitMessage(ContentChangedMessage(*this, *layer)); | |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
145 layer->RegisterObserverCallback(new Callable<RadiographyScene, RadiographyLayer::LayerEditedMessage>(*this, &RadiographyScene::OnLayerEdited)); |
408 | 146 |
147 return *layer; | |
148 } | |
426 | 149 |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
150 void RadiographyScene::OnLayerEdited(const RadiographyLayer::LayerEditedMessage& message) |
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
151 { |
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
152 EmitMessage(RadiographyScene::LayerEditedMessage(*this, message.GetOrigin())); |
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
153 } |
408 | 154 |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
155 RadiographyScene::RadiographyScene(MessageBroker& broker) : |
408 | 156 IObserver(broker), |
157 IObservable(broker), | |
158 countLayers_(0), | |
159 hasWindowing_(false), | |
160 windowingCenter_(0), // Dummy initialization | |
161 windowingWidth_(0) // Dummy initialization | |
162 { | |
163 } | |
164 | |
165 | |
166 RadiographyScene::~RadiographyScene() | |
167 { | |
168 for (Layers::iterator it = layers_.begin(); it != layers_.end(); it++) | |
169 { | |
170 assert(it->second != NULL); | |
171 delete it->second; | |
172 } | |
173 } | |
174 | |
432
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
175 PhotometricDisplayMode RadiographyScene::GetPreferredPhotomotricDisplayMode() const |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
176 { |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
177 // return the mode of the first layer who "cares" about its display mode (normaly, the one and only layer that is a DicomLayer) |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
178 for (Layers::const_iterator it = layers_.begin(); it != layers_.end(); it++) |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
179 { |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
180 if (it->second->GetPreferredPhotomotricDisplayMode() != PhotometricDisplayMode_Default) |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
181 { |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
182 return it->second->GetPreferredPhotomotricDisplayMode(); |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
183 } |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
184 } |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
185 |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
186 return PhotometricDisplayMode_Default; |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
187 } |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
188 |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
189 |
430 | 190 void RadiographyScene::GetLayersIndexes(std::vector<size_t>& output) const |
191 { | |
192 for (Layers::const_iterator it = layers_.begin(); it != layers_.end(); it++) | |
193 { | |
194 output.push_back(it->first); | |
195 } | |
196 } | |
197 | |
425 | 198 void RadiographyScene::RemoveLayer(size_t layerIndex) |
199 { | |
428
751fb354149e
ability to change the scene of the RadiographyWidget
am@osimis.io
parents:
426
diff
changeset
|
200 LOG(INFO) << "Removing layer: " << layerIndex; |
751fb354149e
ability to change the scene of the RadiographyWidget
am@osimis.io
parents:
426
diff
changeset
|
201 |
425 | 202 if (layerIndex > countLayers_) |
203 { | |
204 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
205 } | |
206 delete layers_[layerIndex]; | |
207 layers_.erase(layerIndex); | |
208 countLayers_--; | |
428
751fb354149e
ability to change the scene of the RadiographyWidget
am@osimis.io
parents:
426
diff
changeset
|
209 LOG(INFO) << "Removing layer, there are now : " << countLayers_ << " layers"; |
425 | 210 } |
211 | |
430 | 212 const RadiographyLayer& RadiographyScene::GetLayer(size_t layerIndex) const |
425 | 213 { |
214 if (layerIndex > countLayers_) | |
215 { | |
216 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
217 } | |
430 | 218 |
219 return *(layers_.at(layerIndex)); | |
425 | 220 } |
408 | 221 |
222 bool RadiographyScene::GetWindowing(float& center, | |
223 float& width) const | |
224 { | |
225 if (hasWindowing_) | |
226 { | |
227 center = windowingCenter_; | |
228 width = windowingWidth_; | |
229 return true; | |
230 } | |
231 else | |
232 { | |
233 return false; | |
234 } | |
235 } | |
236 | |
237 | |
238 void RadiographyScene::GetWindowingWithDefault(float& center, | |
239 float& width) const | |
240 { | |
241 if (!GetWindowing(center, width)) | |
242 { | |
243 center = 128; | |
244 width = 256; | |
245 } | |
246 } | |
247 | |
248 | |
249 void RadiographyScene::SetWindowing(float center, | |
250 float width) | |
251 { | |
252 hasWindowing_ = true; | |
253 windowingCenter_ = center; | |
254 windowingWidth_ = width; | |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
255 |
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
256 EmitMessage(RadiographyScene::WindowingChangedMessage(*this)); |
408 | 257 } |
258 | |
259 | |
410
6decc0ba9da5
rename RadiographyScene::Layer as RadiographyLayer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
409
diff
changeset
|
260 RadiographyLayer& RadiographyScene::LoadText(const Orthanc::Font& font, |
430 | 261 const std::string& utf8, |
262 RadiographyLayer::Geometry* geometry) | |
408 | 263 { |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
264 std::auto_ptr<RadiographyTextLayer> alpha(new RadiographyTextLayer(IObservable::GetBroker(), *this)); |
408 | 265 alpha->LoadText(font, utf8); |
430 | 266 if (geometry != NULL) |
267 { | |
268 alpha->SetGeometry(*geometry); | |
269 } | |
408 | 270 |
271 return RegisterLayer(alpha.release()); | |
272 } | |
273 | |
426 | 274 |
410
6decc0ba9da5
rename RadiographyScene::Layer as RadiographyLayer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
409
diff
changeset
|
275 RadiographyLayer& RadiographyScene::LoadTestBlock(unsigned int width, |
430 | 276 unsigned int height, |
277 RadiographyLayer::Geometry* geometry) | |
408 | 278 { |
279 std::auto_ptr<Orthanc::Image> block(new Orthanc::Image(Orthanc::PixelFormat_Grayscale8, width, height, false)); | |
280 | |
281 for (unsigned int padding = 0; | |
282 (width > 2 * padding) && (height > 2 * padding); | |
283 padding++) | |
284 { | |
285 uint8_t color; | |
286 if (255 > 10 * padding) | |
287 { | |
288 color = 255 - 10 * padding; | |
289 } | |
290 else | |
291 { | |
292 color = 0; | |
293 } | |
294 | |
295 Orthanc::ImageAccessor region; | |
296 block->GetRegion(region, padding, padding, width - 2 * padding, height - 2 * padding); | |
297 Orthanc::ImageProcessing::Set(region, color); | |
298 } | |
299 | |
430 | 300 return LoadAlphaBitmap(block.release(), geometry); |
301 } | |
302 | |
488 | 303 RadiographyLayer& RadiographyScene::LoadMask(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners, |
475
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
304 const RadiographyDicomLayer& dicomLayer, |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
305 float foreground, |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
306 RadiographyLayer::Geometry* geometry) |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
307 { |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
308 std::auto_ptr<RadiographyMaskLayer> mask(new RadiographyMaskLayer(IObservable::GetBroker(), *this, dicomLayer, foreground)); |
475
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
309 mask->SetCorners(corners); |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
310 if (geometry != NULL) |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
311 { |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
312 mask->SetGeometry(*geometry); |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
313 } |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
314 |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
315 return RegisterLayer(mask.release()); |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
316 } |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
317 |
3c28542229a3
added a mask layer in the RadiographyWidget (to be cleaned)
am@osimis.io
parents:
440
diff
changeset
|
318 |
430 | 319 RadiographyLayer& RadiographyScene::LoadAlphaBitmap(Orthanc::ImageAccessor* bitmap, RadiographyLayer::Geometry *geometry) |
320 { | |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
321 std::auto_ptr<RadiographyAlphaLayer> alpha(new RadiographyAlphaLayer(IObservable::GetBroker(), *this)); |
430 | 322 alpha->SetAlpha(bitmap); |
323 if (geometry != NULL) | |
324 { | |
325 alpha->SetGeometry(*geometry); | |
326 } | |
408 | 327 |
328 return RegisterLayer(alpha.release()); | |
329 } | |
330 | |
553
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
331 RadiographyLayer& RadiographyScene::LoadDicomImage(Orthanc::ImageAccessor* dicomImage, // takes ownership |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
332 const std::string& instance, |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
333 unsigned int frame, |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
334 DicomFrameConverter* converter, // takes ownership |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
335 PhotometricDisplayMode preferredPhotometricDisplayMode, |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
336 RadiographyLayer::Geometry* geometry) |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
337 { |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
338 RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer(IObservable::GetBroker(), *this))); |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
339 |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
340 layer.SetInstance(instance, frame); |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
341 |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
342 if (geometry != NULL) |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
343 { |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
344 layer.SetGeometry(*geometry); |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
345 } |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
346 |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
347 layer.SetDicomFrameConverter(converter); |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
348 layer.SetSourceImage(dicomImage); |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
349 layer.SetPreferredPhotomotricDisplayMode(preferredPhotometricDisplayMode); |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
350 |
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
351 return layer; |
587 | 352 } |
553
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
353 |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
354 RadiographyLayer& RadiographyScene::LoadDicomFrame(OrthancApiClient& orthanc, |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
355 const std::string& instance, |
410
6decc0ba9da5
rename RadiographyScene::Layer as RadiographyLayer
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
409
diff
changeset
|
356 unsigned int frame, |
430 | 357 bool httpCompression, |
358 RadiographyLayer::Geometry* geometry) | |
408 | 359 { |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
360 RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer(IObservable::GetBroker(), *this))); |
430 | 361 layer.SetInstance(instance, frame); |
362 | |
363 if (geometry != NULL) | |
364 { | |
365 layer.SetGeometry(*geometry); | |
366 } | |
408 | 367 |
368 { | |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
369 IWebService::HttpHeaders headers; |
408 | 370 std::string uri = "/instances/" + instance + "/tags"; |
426 | 371 |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
372 orthanc.GetBinaryAsync( |
426 | 373 uri, headers, |
374 new Callable<RadiographyScene, OrthancApiClient::BinaryResponseReadyMessage> | |
375 (*this, &RadiographyScene::OnTagsReceived), NULL, | |
376 new Orthanc::SingleValueObject<size_t>(layer.GetIndex())); | |
408 | 377 } |
378 | |
379 { | |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
380 IWebService::HttpHeaders headers; |
408 | 381 headers["Accept"] = "image/x-portable-arbitrarymap"; |
382 | |
383 if (httpCompression) | |
384 { | |
385 headers["Accept-Encoding"] = "gzip"; | |
386 } | |
426 | 387 |
408 | 388 std::string uri = ("/instances/" + instance + "/frames/" + |
389 boost::lexical_cast<std::string>(frame) + "/image-uint16"); | |
426 | 390 |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
391 orthanc.GetBinaryAsync( |
426 | 392 uri, headers, |
393 new Callable<RadiographyScene, OrthancApiClient::BinaryResponseReadyMessage> | |
394 (*this, &RadiographyScene::OnFrameReceived), NULL, | |
395 new Orthanc::SingleValueObject<size_t>(layer.GetIndex())); | |
408 | 396 } |
397 | |
398 return layer; | |
399 } | |
400 | |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
401 |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
402 RadiographyLayer& RadiographyScene::LoadDicomWebFrame(IWebService& web) |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
403 { |
503
77e0eb83ff63
layers are now Observable and emitting LayerEdited messages
amazy
parents:
488
diff
changeset
|
404 RadiographyLayer& layer = RegisterLayer(new RadiographyDicomLayer(IObservable::GetBroker(), *this)); |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
405 |
426 | 406 |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
407 return layer; |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
408 } |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
409 |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
410 |
426 | 411 |
408 | 412 void RadiographyScene::OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) |
413 { | |
414 size_t index = dynamic_cast<const Orthanc::SingleValueObject<size_t>&> | |
426 | 415 (message.GetPayload()).GetValue(); |
408 | 416 |
417 LOG(INFO) << "JSON received: " << message.GetUri().c_str() | |
418 << " (" << message.GetAnswerSize() << " bytes) for layer " << index; | |
426 | 419 |
408 | 420 Layers::iterator layer = layers_.find(index); |
421 if (layer != layers_.end()) | |
422 { | |
423 assert(layer->second != NULL); | |
426 | 424 |
408 | 425 OrthancPlugins::FullOrthancDataset dicom(message.GetAnswer(), message.GetAnswerSize()); |
430 | 426 dynamic_cast<RadiographyDicomLayer*>(layer->second)->SetDicomTags(dicom); |
408 | 427 |
428 float c, w; | |
429 if (!hasWindowing_ && | |
430 layer->second->GetDefaultWindowing(c, w)) | |
431 { | |
432 hasWindowing_ = true; | |
433 windowingCenter_ = c; | |
434 windowingWidth_ = w; | |
435 } | |
436 | |
430 | 437 EmitMessage(GeometryChangedMessage(*this, *(layer->second))); |
408 | 438 } |
439 } | |
426 | 440 |
408 | 441 |
442 void RadiographyScene::OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
443 { | |
444 size_t index = dynamic_cast<const Orthanc::SingleValueObject<size_t>&>(message.GetPayload()).GetValue(); | |
426 | 445 |
408 | 446 LOG(INFO) << "DICOM frame received: " << message.GetUri().c_str() |
447 << " (" << message.GetAnswerSize() << " bytes) for layer " << index; | |
426 | 448 |
408 | 449 Layers::iterator layer = layers_.find(index); |
450 if (layer != layers_.end()) | |
451 { | |
452 assert(layer->second != NULL); | |
453 | |
454 std::string content; | |
455 if (message.GetAnswerSize() > 0) | |
456 { | |
457 content.assign(reinterpret_cast<const char*>(message.GetAnswer()), message.GetAnswerSize()); | |
458 } | |
426 | 459 |
408 | 460 std::auto_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader); |
461 reader->ReadFromMemory(content); | |
430 | 462 dynamic_cast<RadiographyDicomLayer*>(layer->second)->SetSourceImage(reader.release()); |
408 | 463 |
430 | 464 EmitMessage(ContentChangedMessage(*this, *(layer->second))); |
408 | 465 } |
466 } | |
467 | |
468 | |
469 Extent2D RadiographyScene::GetSceneExtent() const | |
470 { | |
471 Extent2D extent; | |
472 | |
473 for (Layers::const_iterator it = layers_.begin(); | |
474 it != layers_.end(); ++it) | |
475 { | |
476 assert(it->second != NULL); | |
477 extent.Union(it->second->GetExtent()); | |
478 } | |
479 | |
480 return extent; | |
481 } | |
426 | 482 |
408 | 483 |
484 void RadiographyScene::Render(Orthanc::ImageAccessor& buffer, | |
409 | 485 const AffineTransform2D& viewTransform, |
408 | 486 ImageInterpolation interpolation) const |
487 { | |
488 // Render layers in the background-to-foreground order | |
489 for (size_t index = 0; index < countLayers_; index++) | |
490 { | |
491 Layers::const_iterator it = layers_.find(index); | |
492 if (it != layers_.end()) | |
493 { | |
494 assert(it->second != NULL); | |
495 it->second->Render(buffer, viewTransform, interpolation); | |
496 } | |
497 } | |
498 } | |
499 | |
500 | |
501 bool RadiographyScene::LookupLayer(size_t& index /* out */, | |
502 double x, | |
503 double y) const | |
504 { | |
505 // Render layers in the foreground-to-background order | |
506 for (size_t i = countLayers_; i > 0; i--) | |
507 { | |
508 index = i - 1; | |
509 Layers::const_iterator it = layers_.find(index); | |
510 if (it != layers_.end()) | |
511 { | |
512 assert(it->second != NULL); | |
513 if (it->second->Contains(x, y)) | |
514 { | |
515 return true; | |
516 } | |
517 } | |
518 } | |
519 | |
520 return false; | |
521 } | |
522 | |
426 | 523 |
408 | 524 void RadiographyScene::DrawBorder(CairoContext& context, |
525 unsigned int layer, | |
526 double zoom) | |
527 { | |
528 Layers::const_iterator found = layers_.find(layer); | |
426 | 529 |
408 | 530 if (found != layers_.end()) |
531 { | |
532 context.SetSourceColor(255, 0, 0); | |
533 found->second->DrawBorders(context, zoom); | |
534 } | |
535 } | |
536 | |
537 | |
538 void RadiographyScene::GetRange(float& minValue, | |
539 float& maxValue) const | |
540 { | |
541 bool first = true; | |
426 | 542 |
408 | 543 for (Layers::const_iterator it = layers_.begin(); |
544 it != layers_.end(); it++) | |
545 { | |
546 assert(it->second != NULL); | |
547 | |
548 float a, b; | |
549 if (it->second->GetRange(a, b)) | |
550 { | |
551 if (first) | |
552 { | |
553 minValue = a; | |
554 maxValue = b; | |
555 first = false; | |
556 } | |
557 else | |
558 { | |
559 minValue = std::min(a, minValue); | |
560 maxValue = std::max(b, maxValue); | |
561 } | |
562 } | |
563 } | |
564 | |
565 if (first) | |
566 { | |
567 minValue = 0; | |
568 maxValue = 0; | |
569 } | |
570 } | |
571 | |
481
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
572 Orthanc::Image* RadiographyScene::ExportToImage(double pixelSpacingX, |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
573 double pixelSpacingY, |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
574 ImageInterpolation interpolation, |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
575 bool invert, |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
576 int64_t maxValue /* for inversion */) |
426 | 577 { |
408 | 578 if (pixelSpacingX <= 0 || |
579 pixelSpacingY <= 0) | |
580 { | |
581 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
582 } | |
426 | 583 |
408 | 584 Extent2D extent = GetSceneExtent(); |
585 | |
507 | 586 int w = static_cast<int>(std::ceil(extent.GetWidth() / pixelSpacingX)); |
587 int h = static_cast<int>(std::ceil(extent.GetHeight() / pixelSpacingY)); | |
408 | 588 |
589 if (w < 0 || h < 0) | |
590 { | |
591 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
592 } | |
593 | |
594 Orthanc::Image layers(Orthanc::PixelFormat_Float32, | |
595 static_cast<unsigned int>(w), | |
596 static_cast<unsigned int>(h), false); | |
597 | |
409 | 598 AffineTransform2D view = AffineTransform2D::Combine( |
426 | 599 AffineTransform2D::CreateScaling(1.0 / pixelSpacingX, 1.0 / pixelSpacingY), |
600 AffineTransform2D::CreateOffset(-extent.GetX1(), -extent.GetY1())); | |
601 | |
432
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
602 // wipe background before rendering |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
603 Orthanc::ImageProcessing::Set(layers, 0); |
4eb96c6b4e96
improved handling of MONOCHROME1, background and invertion
am@osimis.io
parents:
431
diff
changeset
|
604 |
408 | 605 Render(layers, view, interpolation); |
606 | |
481
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
607 std::auto_ptr<Orthanc::Image> rendered(new Orthanc::Image(Orthanc::PixelFormat_Grayscale16, |
553
92305ee35b1c
web-worker consequences: give access to lower level data
Alain Mazy <alain@mazy.be>
parents:
541
diff
changeset
|
608 layers.GetWidth(), layers.GetHeight(), false)); |
481
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
609 |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
610 Orthanc::ImageProcessing::Convert(*rendered, layers); |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
611 if (invert) |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
612 Orthanc::ImageProcessing::Invert(*rendered, maxValue); |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
613 |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
614 return rendered.release(); |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
615 } |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
616 |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
617 |
587 | 618 Orthanc::Image* RadiographyScene::ExportToCreateDicomRequestAndImage(Json::Value& createDicomRequestContent, |
619 const Json::Value& dicomTags, | |
620 const std::string& parentOrthancId, | |
621 double pixelSpacingX, | |
622 double pixelSpacingY, | |
623 bool invert, | |
624 ImageInterpolation interpolation) | |
481
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
625 { |
541 | 626 LOG(INFO) << "Exporting RadiographyScene to DICOM"; |
627 | |
481
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
628 std::auto_ptr<Orthanc::Image> rendered(ExportToImage(pixelSpacingX, pixelSpacingY, interpolation)); // note: we don't invert the image in the pixels data because we'll set the PhotometricDisplayMode correctly in the DICOM tags |
408 | 629 |
483 | 630 createDicomRequestContent["Tags"] = dicomTags; |
408 | 631 |
436
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
632 PhotometricDisplayMode photometricMode = GetPreferredPhotomotricDisplayMode(); |
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
633 if ((invert && photometricMode != PhotometricDisplayMode_Monochrome2) || |
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
634 (!invert && photometricMode == PhotometricDisplayMode_Monochrome1)) |
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
635 { |
483 | 636 createDicomRequestContent["Tags"]["PhotometricInterpretation"] = "MONOCHROME1"; |
436
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
637 } |
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
638 else |
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
639 { |
483 | 640 createDicomRequestContent["Tags"]["PhotometricInterpretation"] = "MONOCHROME2"; |
436
04711a2e12cd
fix crop + export photometric interpretation correctly
am@osimis.io
parents:
432
diff
changeset
|
641 } |
408 | 642 |
643 // WARNING: The order of PixelSpacing is Y/X. We use "%0.8f" to | |
644 // avoid floating-point numbers to grow over 16 characters, | |
645 // which would be invalid according to DICOM standard | |
646 // ("dciodvfy" would complain). | |
647 char buf[32]; | |
648 sprintf(buf, "%0.8f\\%0.8f", pixelSpacingY, pixelSpacingX); | |
426 | 649 |
483 | 650 createDicomRequestContent["Tags"]["PixelSpacing"] = buf; |
408 | 651 |
652 float center, width; | |
653 if (GetWindowing(center, width)) | |
654 { | |
483 | 655 createDicomRequestContent["Tags"]["WindowCenter"] = |
426 | 656 boost::lexical_cast<std::string>(boost::math::iround(center)); |
408 | 657 |
483 | 658 createDicomRequestContent["Tags"]["WindowWidth"] = |
426 | 659 boost::lexical_cast<std::string>(boost::math::iround(width)); |
408 | 660 } |
661 | |
587 | 662 if (!parentOrthancId.empty()) |
663 { | |
664 createDicomRequestContent["Parent"] = parentOrthancId; | |
665 } | |
666 | |
667 return rendered.release(); | |
668 } | |
669 | |
670 | |
671 void RadiographyScene::ExportToCreateDicomRequest(Json::Value& createDicomRequestContent, | |
672 const Json::Value& dicomTags, | |
673 const std::string& parentOrthancId, | |
674 double pixelSpacingX, | |
675 double pixelSpacingY, | |
676 bool invert, | |
677 ImageInterpolation interpolation, | |
678 bool usePam) | |
679 { | |
680 LOG(INFO) << "Exporting RadiographyScene to DICOM"; | |
681 VLOG(1) << "Exporting RadiographyScene to: export to image"; | |
682 | |
683 std::auto_ptr<Orthanc::Image> rendered(ExportToCreateDicomRequestAndImage(createDicomRequestContent, dicomTags, parentOrthancId, pixelSpacingX, pixelSpacingY, invert, interpolation)); | |
684 | |
685 // convert the image into base64 for inclusing in the createDicomRequest | |
686 std::string base64; | |
687 | |
688 { | |
689 std::string content; | |
690 | |
691 if (usePam) | |
692 { | |
693 VLOG(1) << "Exporting RadiographyScene: convert to PAM"; | |
694 Orthanc::PamWriter writer; | |
695 writer.WriteToMemory(content, *rendered); | |
696 } | |
697 else | |
698 { | |
699 Orthanc::PngWriter writer; | |
700 writer.WriteToMemory(content, *rendered); | |
701 } | |
702 | |
703 VLOG(1) << "Exporting RadiographyScene: encoding to base64"; | |
704 Orthanc::Toolbox::EncodeBase64(base64, content); | |
705 } | |
426 | 706 |
408 | 707 // This is Data URI scheme: https://en.wikipedia.org/wiki/Data_URI_scheme |
426 | 708 createDicomRequestContent["Content"] = ("data:" + |
709 std::string(usePam ? Orthanc::MIME_PAM : Orthanc::MIME_PNG) + | |
710 ";base64," + base64); | |
481
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
711 |
541 | 712 VLOG(1) << "Exporting RadiographyScene: create-dicom request is ready"; |
484
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
713 } |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
714 |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
715 |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
716 void RadiographyScene::ExportDicom(OrthancApiClient& orthanc, |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
717 const Json::Value& dicomTags, |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
718 const std::string& parentOrthancId, |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
719 double pixelSpacingX, |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
720 double pixelSpacingY, |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
721 bool invert, |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
722 ImageInterpolation interpolation, |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
723 bool usePam) |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
724 { |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
725 Json::Value createDicomRequestContent; |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
726 |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
727 ExportToCreateDicomRequest(createDicomRequestContent, dicomTags, parentOrthancId, pixelSpacingX, pixelSpacingY, invert, interpolation, usePam); |
7bf001b9d244
re-added ExportToCreateDicomRequest
Alain Mazy <alain@mazy.be>
parents:
483
diff
changeset
|
728 |
481
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
729 orthanc.PostJsonAsyncExpectJson( |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
730 "/tools/create-dicom", createDicomRequestContent, |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
731 new Callable<RadiographyScene, OrthancApiClient::JsonResponseReadyMessage> |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
732 (*this, &RadiographyScene::OnDicomExported), |
159a465e27bd
reworked RadiographyScene export to export to an Orthanc::Image too
am@osimis.io
parents:
475
diff
changeset
|
733 NULL, NULL); |
483 | 734 |
735 } | |
736 | |
737 | |
738 // Export using PAM is faster than using PNG, but requires Orthanc | |
739 // core >= 1.4.3 | |
740 void RadiographyScene::ExportDicom(OrthancApiClient& orthanc, | |
741 const Orthanc::DicomMap& dicom, | |
742 const std::string& parentOrthancId, | |
743 double pixelSpacingX, | |
744 double pixelSpacingY, | |
745 bool invert, | |
746 ImageInterpolation interpolation, | |
747 bool usePam) | |
748 { | |
749 std::set<Orthanc::DicomTag> tags; | |
750 dicom.GetTags(tags); | |
751 | |
752 Json::Value jsonTags = Json::objectValue; | |
753 | |
754 for (std::set<Orthanc::DicomTag>::const_iterator | |
755 tag = tags.begin(); tag != tags.end(); ++tag) | |
756 { | |
757 const Orthanc::DicomValue& value = dicom.GetValue(*tag); | |
758 if (!value.IsNull() && | |
759 !value.IsBinary()) | |
760 { | |
761 jsonTags[tag->Format()] = value.GetContent(); | |
762 } | |
763 } | |
764 | |
765 ExportDicom(orthanc, jsonTags, parentOrthancId, pixelSpacingX, pixelSpacingY, invert, interpolation, usePam); | |
408 | 766 } |
767 | |
768 void RadiographyScene::OnDicomExported(const OrthancApiClient::JsonResponseReadyMessage& message) | |
769 { | |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
770 LOG(INFO) << "DICOM export was successful: " |
408 | 771 << message.GetJson().toStyledString(); |
772 } | |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
773 |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
774 |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
775 void RadiographyScene::OnDicomWebReceived(const IWebService::HttpRequestSuccessMessage& message) |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
776 { |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
777 LOG(INFO) << "DICOMweb WADO-RS received: " << message.GetAnswerSize() << " bytes"; |
418 | 778 |
779 const IWebService::HttpHeaders& h = message.GetAnswerHttpHeaders(); | |
780 for (IWebService::HttpHeaders::const_iterator | |
426 | 781 it = h.begin(); it != h.end(); ++it) |
418 | 782 { |
783 printf("[%s] = [%s]\n", it->first.c_str(), it->second.c_str()); | |
784 } | |
417
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
785 } |
aee3d7941c9b
preparing to load images using DICOMweb
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
412
diff
changeset
|
786 |
408 | 787 } |