ImageMagick提取图像原始数据(ImageData/RawData)

我用的是ImageMagickWand的接口,因为这接口比Core接口更上层,所以官方文档推荐用。

 抽取整个图像文件字节数据:

http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20664

 抽取图像像素的字节数据:

http://www.imagemagick.org/discourse-server/viewtopic.php?f=6&t=12135

 

ImageMagick附带的convert工具命令使用:

convert [-option] inputfile outputfile

以下时常用option:

-colorspace

-size

-depth

以下是提取原始数据的命令:

convert -colorspace gray -depth 16 inputfile gray:filename.raw

.raw文件会在convert工具的当前目录下生成,.raw文件就是没有文件头的原始图像像素的字节文件。

 以下时Demo:

  1 // ImageMagick_use_test.cpp : Defines the entry point for the console application.
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "wand\MagickWand.h"
  6 #include "magick\MagickCore.h"
  7 #include "stdio.h"
  8 #include "stdlib.h"
  9 #include "conio.h"
 10 #include "malloc.h"
 11 
 12 #define OUT
 13 
 14 void ThrowWandException(MagickWand* wand) 
 15 { 
 16     char *description; 
 17     
 18     ExceptionType severity; 
 19     char err_msg[125];
 20     
 21     description=MagickGetException(wand,&severity); 
 22     sprintf(err_msg,"%s\nError_Type is %d\n",description,severity); 
 23     //description=(char *) MagickRelinquishMemory(description); 
 24     
 25     printf(err_msg);
 26 }
 27 
 28 char* __stdcall GetGrayPixelFormat_16bit( const char* fileName, int width, int height, OUT char* pDestImage );
 29 
 30 bool __stdcall GetRGBPixelFormat_16bit( const char* fileName, int width, int height, OUT char* pRed, OUT char* pGreen, OUT char* pBlue);
 31 
 32 int _tmain(int argc, _TCHAR* argv[])
 33 {
 34 
 35    char *pDestImage = NULL;
 36    char *pRed =NULL;
 37    char *pGreen = NULL;
 38    char *pBlue = NULL;
 39    //Allocate 1024*5 Buffer in bytes
 40    pDestImage = (char*)malloc(1920*1200*2);
 41    pRed = (char*)malloc(1920*1200*2);
 42    pGreen = (char*)malloc(1920*1200*2);
 43    pBlue = (char*)malloc(1920*1200*2);
 44     
 45    memset(pDestImage,0,1920*1200*2);
 46    memset(pRed, 0, 1920*1200*2);
 47    memset(pGreen, 0, 1920*1200*2);
 48    memset(pBlue, 0, 1920*1200*2);
 49    
 50    pDestImage = GetGrayPixelFormat_16bit( "C:\\Users\\Yajun Dou\\Desktop\\12.jpg", 1920, 1200, pDestImage);
 51 
 52    if(pDestImage == NULL)
 53    {
 54        printf("GetGrayPixelFormat_16bit Failed!\n");
 55    }
 56 
 57    if(GetRGBPixelFormat_16bit("C:\\Users\\Yajun Dou\\Desktop\\12.jpg",1920,1200,pRed,pGreen,pBlue)==false)
 58    {
 59        printf("GetRGBPixelFormat_16bit Failed!\n");
 60    }
 61 
 62    free(pDestImage);
 63    free(pRed);
 64    free(pGreen);
 65    free(pBlue);
 66     
 67 
 68     return 0;
 69 }
 70 
 71 char* __stdcall GetGrayPixelFormat_16bit( const char* fileName, int width, int height, OUT char* pDestImage )
 72 {
 73     MagickBooleanType status;
 74 
 75     MagickWand *magick_wand;
 76 
 77     char* pReturnDestImage = NULL;
 78     char* pReturnDestImageData = NULL;
 79 
 80     
 81     int IMageDepth;
 82     
 83     //Initialize Magick Enviroment
 84 
 85     MagickWandGenesis();
 86     magick_wand=NewMagickWand();
 87     
 88     //Read image
 89     status=MagickReadImage(magick_wand,fileName);
 90     if (status == MagickFalse)
 91         ThrowWandException(magick_wand);
 92 
 93     //得到图像深度
 94     IMageDepth = (int)MagickGetImageDepth(magick_wand);
 95 
 96     printf("The Current Image Depth is %d\n",IMageDepth);
 97 
 98     
 99     //convert image to grayscale 
100     status = MagickSetImageColorspace(magick_wand,GRAYColorspace);
101 
102     if(status == MagickFalse)
103         ThrowWandException(magick_wand);
104 
105     status = MagickTransformImageColorspace(magick_wand,GRAYColorspace);
106 
107     if(status == MagickFalse)
108         ThrowWandException(magick_wand);
109 
110     
111 
112 
113     IMageDepth = (int)MagickGetImageDepth(magick_wand);
114 
115     printf("The Current Image Depth is %d\n",IMageDepth);
116 
117 
118     //得到图像宽度和高度
119     int Height;
120 
121     Height = (int)MagickGetImageHeight(magick_wand);
122 
123     printf("The Current Image Height is %d\n",Height);
124 
125     int Width;
126 
127     Width = (int)MagickGetImageWidth(magick_wand);
128 
129     printf("The Current Image Width is %d\n",Width);
130 
131     //得到像素的通道数
132     int ImageChannels;
133     Image* pImage = NULL;
134 
135     pImage = GetImageFromMagickWand(magick_wand);
136 
137     if(pImage == NULL)
138     {
139         return NULL;
140     }
141 
142     ImageChannels = pImage->channels;
143 
144     /*printf("RedChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,RedChannel));
145     printf("GreenChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,GreenChannel));
146     printf("BlueChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,BlueChannel));
147     printf("GrayChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,GrayChannel));*/
148 
149 
150 
151     if(Width != width || Height != height || IMageDepth != 16 || ImageChannels != 3)
152     {
153 
154         if(MagickResizeImage(magick_wand,width,height,LanczosFilter,1.0) == MagickFalse)
155         {
156             ThrowWandException(magick_wand);
157         }
158 
159         //设置图像深度
160         if(MagickSetImageDepth(magick_wand,16) == MagickFalse)
161         {
162             ThrowWandException(magick_wand);
163         } 
164         //设置灰度通道深度
165         if(MagickSetImageChannelDepth(magick_wand,GrayChannel,16) == MagickFalse)
166         {
167             ThrowWandException(magick_wand);
168         }
169 
170     }
171 
172     
173 
174     // MagickWriteImages(magick_wand,"C:\\Users\\Yajun Dou\\Desktop\\12_trans1.bmp",MagickFalse);
175 
176 
177     IMageDepth = (int)MagickGetImageDepth(magick_wand);
178 
179     printf("The Current Image Depth is %d\n",IMageDepth);
180 
181 
182     
183 
184     
185 
186 
187     
188     int ImageDataLength;
189     int ImageDataSize;
190    /* //MagickGetImageBlob函数得到的是整个图像文件的二进制字节流,并非图像数据
191     pReturnDestImage = (char*)MagickGetImageBlob(magick_wand,(size_t*)&ImageDataLength);*/
192     MagickGetImagePixels(magick_wand,0,0,width,height,"I",ShortPixel,pDestImage);
193    
194    
195     
196 
197     
198     magick_wand=DestroyMagickWand(magick_wand);
199     
200     MagickWandTerminus();
201 
202     return pDestImage;
203 }
204 
205 
206 bool __stdcall GetRGBPixelFormat_16bit( const char* fileName, int width, int height, OUT char* pRed, OUT char* pGreen, OUT char* pBlue)
207 {
208     MagickBooleanType status;
209 
210     MagickWand *magick_wand;
211 
212     
213 
214     //Initialize Magick Enviroment
215 
216     MagickWandGenesis();
217     magick_wand=NewMagickWand();
218 
219     //Read image
220     status=MagickReadImage(magick_wand,fileName);
221     if (status == MagickFalse)
222     {
223         ThrowWandException(magick_wand);
224         return false;
225     }
226 
227     //convert image to RGB three channels
228     status = MagickSetImageColorspace(magick_wand,RGBColorspace);
229 
230     if(status == MagickFalse)
231         ThrowWandException(magick_wand);
232 
233     status = MagickTransformImageColorspace(magick_wand,RGBColorspace);
234 
235     if(status == MagickFalse)
236         ThrowWandException(magick_wand);
237 
238 
239 
240 
241     //得到图像深度
242     int IMageDepth;
243 
244 
245     IMageDepth = (int)MagickGetImageDepth(magick_wand);
246 
247     printf("The Current Image Depth is %d\n",IMageDepth);
248 
249 
250     //得到图像宽度和高度
251     int Height;
252 
253     Height = (int)MagickGetImageHeight(magick_wand);
254 
255     printf("The Current Image Height is %d\n",Height);
256 
257     int Width;
258 
259     Width = (int)MagickGetImageWidth(magick_wand);
260 
261     printf("The Current Image Width is %d\n",Width);
262 
263     //得到像素的通道数
264     int ImageChannels;
265     Image* pImage = NULL;
266 
267     pImage = GetImageFromMagickWand(magick_wand);
268 
269     if(pImage == NULL)
270     {
271         return false;
272     }
273 
274     ImageChannels = pImage->channels;
275 
276     /*printf("RedChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,RedChannel));
277     printf("GreenChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,GreenChannel));
278     printf("BlueChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,BlueChannel));
279     printf("GrayChannelDepth is %d\n",MagickGetImageChannelDepth(magick_wand,GrayChannel));*/
280 
281 
282 
283     if(Width != width || Height != height)
284     {
285 
286         if(MagickResizeImage(magick_wand,width,height,LanczosFilter,1.0) == MagickFalse)
287         {
288             ThrowWandException(magick_wand);
289         }
290 
291         
292 
293     }
294 
295     
296 
297     // MagickWriteImages(magick_wand,"C:\\Users\\Yajun Dou\\Desktop\\12_trans1.bmp",MagickFalse);
298 
299 
300     IMageDepth = (int)MagickGetImageDepth(magick_wand);
301 
302     printf("The Current Image Depth is %d\n",IMageDepth);
303 
304     
305 
306     
307 
308 
309 
310 
311 
312 
313     int ImageDataLength;
314     int ImageDataSize;
315     /* //MagickGetImageBlob函数得到的是整个图像文件的二进制字节流,并非图像数据
316     pReturnDestImage = (char*)MagickGetImageBlob(magick_wand,(size_t*)&ImageDataLength);*/
317     MagickGetImagePixels(magick_wand,0,0,width,height,"R",ShortPixel,pRed);
318     MagickGetImagePixels(magick_wand,0,0,width,height,"G",ShortPixel,pGreen);
319     MagickGetImagePixels(magick_wand,0,0,width,height,"B",ShortPixel,pBlue);
320 
321  
322    
323 
324 
325 
326     magick_wand=DestroyMagickWand(magick_wand);
327 
328     MagickWandTerminus();
329 
330     return true;
331 
332     
333 }
View Code

TIPS:MagickWandGenesis()函数是对于整个进程(全局的初始化),一般要在主线程中调用,如果每个函数都调用MagickWandGenesis(),MagickWandTerminus();必然带来巨大性能开销。以上是Demo,所以没管那么多,如果糅合到项目中,必然不能这么写。ImageMagickGetImagePixels,后面的shortpixel是指提取16bit的图像数据,"R" "G"等是指示通道顺序,所以可以"RGB"连接起来写.最后一个参数是输出数据的字节数组。

 

另外还可以调用MagickExportImagePixels这个接口来得到图像数据。ImageMagickGetImagePixels这个接口貌似是过时的接口,虽然能用。这两个API的参数是一样的。

reference:

http://web.mit.edu/usmanm/MacData/afs/athena/contrib/graphics/share/ImageMagick/www/convert.html

 

posted @ 2013-12-05 16:40  foo__hack  阅读(3086)  评论(0编辑  收藏  举报