32 #ifndef MAGICKDRAIN_H_
33 #define MAGICKDRAIN_H_
39 #ifdef DRAIN_MAGICK_yes
61 #ifdef DRAIN_MAGICK_yes
65 static void convert(
const ImageT<T> &drainImage, Magick::ImageT &magickImage);
70 static void convert(Magick::ImageT &magickImage,
ImageT<T> &drainImage);
78 #ifdef DRAIN_MAGICK_yes
82 void MagickDrain::convert(
const ImageT<T> &drainImage, Magick::ImageT &magickImage) {
84 Magick::ImageType type = Magick::TrueColorMatteType;
86 int imageChannels = drainImage.getImageChannelCount();
87 int alphaChannels = drainImage.getAlphaChannelCount();
89 if (alphaChannels > 1){
90 std::cerr <<
"Warning: multiple alpha channel image, using 1st only \n";
91 std::cerr <<
" Image geometry:" << drainImage.getGeometry() <<
'\n';
95 const ImageT<T> *red = NULL, *green = NULL, *blue = NULL, *alpha = NULL;
107 switch (imageChannels){
109 if (alphaChannels == 0){
110 std::cerr <<
"Error: zero channel image!\n";
113 type = Magick::GrayscaleType;
114 red =& drainImage.getChannel(0);
115 green =& drainImage.getChannel(0);
116 blue =& drainImage.getChannel(0);
120 type = Magick::GrayscaleType;
121 red =& drainImage.getChannel(0);
122 green =& drainImage.getChannel(0);
123 blue =& drainImage.getChannel(0);
124 if (alphaChannels > 0) {
125 type = Magick::GrayscaleMatteType;
126 alpha =& drainImage.getAlphaChannel();
130 if (!alphaChannels) {
131 type = Magick::GrayscaleMatteType;
132 std::cerr <<
"Notice: 2 channel image, storing 2nd as alpha channel \n";
133 red =& drainImage.getChannel(0);
134 green =& drainImage.getChannel(0);
135 blue =& drainImage.getChannel(0);
136 alpha =& drainImage.getChannel(1);
139 std::cerr <<
"Notice: (2+alpha ) channel image, creating 'RGAA' image instead of 'RGBA'.\n";
140 type = Magick::TrueColorMatteType;
141 red =& drainImage.getChannel(0);
142 green =& drainImage.getChannel(1);
143 blue =& drainImage.getAlphaChannel();
144 alpha =& drainImage.getAlphaChannel();
148 type = Magick::TrueColorType;
149 red =& drainImage.getChannel(0);
150 green =& drainImage.getChannel(1);
151 blue =& drainImage.getChannel(2);
153 type = Magick::TrueColorMatteType;
154 alpha =& drainImage.getAlphaChannel();
158 type = Magick::TrueColorMatteType;
159 red =& drainImage.getChannel(0);
160 green =& drainImage.getChannel(1);
161 blue =& drainImage.getChannel(2);
164 std::cerr <<
"Warning: (" << imageChannels <<
"+alpha) channel image, using (3+alpha). \n";
165 alpha =& drainImage.getAlphaChannel();
167 else if (imageChannels == 4){
168 std::cerr <<
"Notice: 4 channel image, storing 4th as alpha channel \n";
169 alpha =& drainImage.getChannel(3);
175 const int width = drainImage.getGeometry().getWidth();
176 const int height = drainImage.getGeometry().getHeight();
183 magickImage.classType(Magick::DirectClass);
184 magickImage.size(Magick::Geometry(width,height));
187 magickImage.modifyImage();
188 magickImage.type(type);
191 Magick::PixelPacket *pixel_cache = magickImage.getPixels(0,0,width,height);
199 const unsigned int drainMax = std::numeric_limits<unsigned char>::max();
200 const int shiftBits = magickImage.depth() - 8;
206 for (j=0; j<height; j++){
207 rowAddress = j*width;
209 for (i=0; i<width; i++){
210 address = i + rowAddress;
211 pixel_cache[address].red = (red->at(i,j) << shiftBits);
212 pixel_cache[address].green = (green->at(i,j) << shiftBits);
213 pixel_cache[address].blue = (blue->at(i,j) << shiftBits);
217 pixel_cache[address].opacity = ((drainMax-alpha->at(i,j)) << shiftBits);
223 magickImage.syncPixels();
225 catch (Magick::Error& e) {
227 std::cerr <<
"a Magick++ error occurred: " << e.what() << std::endl;
230 std::cerr <<
"MagickDrain: an unhandled error has occurred; exiting application." << std::endl;
238 std::stringstream sstr;
239 std::map<std::string,Data>::const_iterator it;
241 sstr << it->first <<
'=' << it->second <<
'\n';
243 magickImage.comment(sstr.toStr());
251 #ifdef DRAIN_MAGICK_yes
255 void MagickDrain::convert(Magick::ImageT &magickImage, ImageT<T> &drainImage) {
257 const int w = magickImage.columns();
258 const int h = magickImage.rows();
264 switch (magickImage.type()){
265 case Magick::GrayscaleType:
266 drainImage.setGeometry(w,h,1);
267 magickImage.write(0,0,w,h,
"I",Magick::CharPixel,&drainImage.at(0,0));
269 case Magick::GrayscaleMatteType:
270 drainImage.setGeometry(w,h,1,1);
271 magickImage.write(0,0,w,h,
"I",Magick::CharPixel,&drainImage.at(0,0,0));
272 magickImage.write(0,0,w,h,
"A",Magick::CharPixel,&drainImage.at(0,0,1));
275 case Magick::PaletteType:
276 case Magick::TrueColorType:
277 drainImage.setGeometry(w,h,3);
278 magickImage.write(0,0,w,h,
"R",Magick::CharPixel,&drainImage.at(0,0,0));
279 magickImage.write(0,0,w,h,
"G",Magick::CharPixel,&drainImage.at(0,0,1));
280 magickImage.write(0,0,w,h,
"B",Magick::CharPixel,&drainImage.at(0,0,2));
282 case Magick::PaletteMatteType:
283 case Magick::TrueColorMatteType:
284 drainImage.setGeometry(w,h,3,1);
285 magickImage.write(0,0,w,h,
"R",Magick::CharPixel,&drainImage.at(0,0,0));
286 magickImage.write(0,0,w,h,
"G",Magick::CharPixel,&drainImage.at(0,0,1));
287 magickImage.write(0,0,w,h,
"B",Magick::CharPixel,&drainImage.at(0,0,2));
288 magickImage.write(0,0,w,h,
"A",Magick::CharPixel,&drainImage.at(0,0,3));
293 std::stringstream sstr;
294 sstr <<
"operator<<(image,magickImage) : Magick type " << magickImage.type() <<
" not handled.";
295 throw std::runtime_error(sstr.toStr());
299 if (drainImage.getAlphaChannelCount()>0){
305 std::stringstream sstr(magickImage.comment());
306 drainImage.properties.reader.read(sstr);
308 if (drain::Debug > 5){
309 std::cerr <<
"read magickImage.type = " << magickImage.type() <<
'\n';
310 std::cerr <<
"comment='" << magickImage.comment() <<
"'\n";
311 std::cerr <<
"::::::::::::::::::::\n";
312 std::cerr << drainImage.properties;
FlexVariableMap properties
Container for user-defined KEY=VALUE metadata.
Definition: ImageFrame.h:369
A template class for images with static storage type.
Definition: ImageT.h:67
Definition: MagickDrain.h:56
Definition: DataSelector.cpp:1277