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

 

你可能感兴趣的:(ImageMagick)