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