Mercurial > hg > orthanc-stone
comparison RenderingPlugin/Sources/Plugin.cpp @ 1884:0c6923982fdd
rendering options from GET args
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 14 Jan 2022 14:14:25 +0100 |
parents | fba6e550e0ee |
children | ddaee6b96501 |
comparison
equal
deleted
inserted
replaced
1883:fba6e550e0ee | 1884:0c6923982fdd |
---|---|
29 | 29 |
30 #include <Images/Image.h> | 30 #include <Images/Image.h> |
31 #include <Images/ImageProcessing.h> | 31 #include <Images/ImageProcessing.h> |
32 #include <Images/NumpyWriter.h> | 32 #include <Images/NumpyWriter.h> |
33 #include <Logging.h> | 33 #include <Logging.h> |
34 #include <SerializationToolbox.h> | |
34 | 35 |
35 #include <boost/math/constants/constants.hpp> | 36 #include <boost/math/constants/constants.hpp> |
36 | 37 |
37 | 38 |
38 static Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format) | 39 static Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format) |
51 case OrthancPluginPixelFormat_SignedGrayscale16: | 52 case OrthancPluginPixelFormat_SignedGrayscale16: |
52 return Orthanc::PixelFormat_SignedGrayscale16; | 53 return Orthanc::PixelFormat_SignedGrayscale16; |
53 | 54 |
54 default: | 55 default: |
55 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 56 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
57 } | |
58 } | |
59 | |
60 | |
61 static bool ParseBoolean(const std::string& key, | |
62 const std::string& value) | |
63 { | |
64 bool result; | |
65 | |
66 if (Orthanc::SerializationToolbox::ParseBoolean(result, value)) | |
67 { | |
68 return result; | |
69 } | |
70 else | |
71 { | |
72 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, | |
73 "Bad value for " + key + ": " + value); | |
74 } | |
75 } | |
76 | |
77 | |
78 static double ParseDouble(const std::string& key, | |
79 const std::string& value) | |
80 { | |
81 double result; | |
82 | |
83 if (Orthanc::SerializationToolbox::ParseDouble(result, value)) | |
84 { | |
85 return result; | |
86 } | |
87 else | |
88 { | |
89 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, | |
90 "Bad value for " + key + ": " + value); | |
56 } | 91 } |
57 } | 92 } |
58 | 93 |
59 | 94 |
60 static void RenderNumpyFrame(OrthancPluginRestOutput* output, | 95 static void RenderNumpyFrame(OrthancPluginRestOutput* output, |
61 const char* url, | 96 const char* url, |
62 const OrthancPluginHttpRequest* request) | 97 const OrthancPluginHttpRequest* request) |
63 { | 98 { |
64 // TODO: Parameters in GET | 99 double angleRadians = 0; |
65 | |
66 OrthancPlugins::MemoryBuffer tags; | |
67 if (!tags.RestApiGet("/instances/" + std::string(request->groups[0]) + "/tags", false)) | |
68 { | |
69 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem); | |
70 } | |
71 | |
72 Json::Value json; | |
73 tags.ToJson(json); | |
74 | |
75 Orthanc::DicomMap m; | |
76 m.FromDicomAsJson(json); | |
77 | |
78 OrthancStone::DicomInstanceParameters parameters(m); | |
79 | |
80 OrthancPlugins::MemoryBuffer dicom; | |
81 dicom.GetDicomInstance(request->groups[0]); | |
82 | |
83 unsigned int frame = boost::lexical_cast<unsigned int>(request->groups[1]); | |
84 | |
85 OrthancPlugins::OrthancImage image; | |
86 image.DecodeDicomImage(dicom.GetData(), dicom.GetSize(), frame); | |
87 | |
88 Orthanc::ImageAccessor source; | |
89 source.AssignReadOnly(Convert(image.GetPixelFormat()), image.GetWidth(), image.GetHeight(), | |
90 image.GetPitch(), image.GetBuffer()); | |
91 | |
92 double angle = 0; | |
93 double scaling = 1; | 100 double scaling = 1; |
94 double offsetX = 0; | 101 double offsetX = 0; |
95 double offsetY = 0; | 102 double offsetY = 0; |
96 bool flipX = false; | 103 bool flipX = false; |
97 bool flipY = false; | 104 bool flipY = false; |
105 bool compress = false; | |
106 | |
107 for (uint32_t i = 0; i < request->getCount; i++) | |
108 { | |
109 std::string key(request->getKeys[i]); | |
110 std::string value(request->getValues[i]); | |
111 | |
112 if (key == "angle") | |
113 { | |
114 double angle = ParseDouble(key, value); | |
115 angleRadians = angle / 180.0 * boost::math::constants::pi<double>(); | |
116 } | |
117 else if (key == "scaling") | |
118 { | |
119 scaling = ParseDouble(key, value); | |
120 } | |
121 else if (key == "offset-x") | |
122 { | |
123 offsetX = ParseDouble(key, value); | |
124 } | |
125 else if (key == "offset-y") | |
126 { | |
127 offsetY = ParseDouble(key, value); | |
128 } | |
129 else if (key == "flip-x") | |
130 { | |
131 flipX = ParseBoolean(key, value); | |
132 } | |
133 else if (key == "flip-y") | |
134 { | |
135 flipY = ParseBoolean(key, value); | |
136 } | |
137 else if (key == "compress") | |
138 { | |
139 compress = ParseBoolean(key, value); | |
140 } | |
141 else | |
142 { | |
143 LOG(WARNING) << "Unsupported option: " << key; | |
144 } | |
145 } | |
146 | |
147 OrthancPlugins::MemoryBuffer tags; | |
148 if (!tags.RestApiGet("/instances/" + std::string(request->groups[0]) + "/tags", false)) | |
149 { | |
150 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem); | |
151 } | |
152 | |
153 Json::Value json; | |
154 tags.ToJson(json); | |
155 | |
156 Orthanc::DicomMap m; | |
157 m.FromDicomAsJson(json); | |
158 | |
159 OrthancStone::DicomInstanceParameters parameters(m); | |
160 | |
161 OrthancPlugins::MemoryBuffer dicom; | |
162 dicom.GetDicomInstance(request->groups[0]); | |
163 | |
164 unsigned int frame = boost::lexical_cast<unsigned int>(request->groups[1]); | |
165 | |
166 OrthancPlugins::OrthancImage image; | |
167 image.DecodeDicomImage(dicom.GetData(), dicom.GetSize(), frame); | |
168 | |
169 Orthanc::ImageAccessor source; | |
170 source.AssignReadOnly(Convert(image.GetPixelFormat()), image.GetWidth(), image.GetHeight(), | |
171 image.GetPitch(), image.GetBuffer()); | |
98 | 172 |
99 OrthancStone::AffineTransform2D t; | 173 OrthancStone::AffineTransform2D t; |
100 t = OrthancStone::AffineTransform2D::Combine( | 174 t = OrthancStone::AffineTransform2D::Combine( |
101 OrthancStone::AffineTransform2D::CreateOffset(static_cast<double>(image.GetWidth()) / 2.0 + offsetX, | 175 OrthancStone::AffineTransform2D::CreateOffset(static_cast<double>(image.GetWidth()) / 2.0 + offsetX, |
102 static_cast<double>(image.GetHeight()) / 2.0 + offsetY), | 176 static_cast<double>(image.GetHeight()) / 2.0 + offsetY), |
103 OrthancStone::AffineTransform2D::CreateScaling(scaling, scaling), | 177 OrthancStone::AffineTransform2D::CreateScaling(scaling, scaling), |
104 OrthancStone::AffineTransform2D::CreateRotation(angle / 180.0 * boost::math::constants::pi<double>()), | 178 OrthancStone::AffineTransform2D::CreateRotation(angleRadians), |
105 OrthancStone::AffineTransform2D::CreateOffset(-static_cast<double>(image.GetWidth()) / 2.0, | 179 OrthancStone::AffineTransform2D::CreateOffset(-static_cast<double>(image.GetWidth()) / 2.0, |
106 -static_cast<double>(image.GetHeight()) / 2.0), | 180 -static_cast<double>(image.GetHeight()) / 2.0), |
107 OrthancStone::AffineTransform2D::CreateFlip(flipX, flipY, image.GetWidth(), image.GetHeight())); | 181 OrthancStone::AffineTransform2D::CreateFlip(flipX, flipY, image.GetWidth(), image.GetHeight())); |
108 | 182 |
109 std::unique_ptr<Orthanc::ImageAccessor> modified; | 183 std::unique_ptr<Orthanc::ImageAccessor> modified; |
126 | 200 |
127 assert(modified.get() != NULL); | 201 assert(modified.get() != NULL); |
128 | 202 |
129 std::string answer; | 203 std::string answer; |
130 Orthanc::NumpyWriter writer; | 204 Orthanc::NumpyWriter writer; |
205 writer.SetCompressed(compress); | |
131 Orthanc::IImageWriter::WriteToMemory(writer, answer, *modified); | 206 Orthanc::IImageWriter::WriteToMemory(writer, answer, *modified); |
132 | 207 |
133 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, | 208 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, |
134 answer.c_str(), answer.size(), "text/plain"); | 209 answer.c_str(), answer.size(), "text/plain"); |
135 } | 210 } |
136 | 211 |
137 | 212 |