• 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 "wandMagickWand.h"
      6 #include "magickMagickCore.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
    Error_Type is %d
    ",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!
    ");
     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!
    ");
     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
    ",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
    ",IMageDepth);
    116 
    117 
    118     //得到图像宽度和高度
    119     int Height;
    120 
    121     Height = (int)MagickGetImageHeight(magick_wand);
    122 
    123     printf("The Current Image Height is %d
    ",Height);
    124 
    125     int Width;
    126 
    127     Width = (int)MagickGetImageWidth(magick_wand);
    128 
    129     printf("The Current Image Width is %d
    ",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
    ",MagickGetImageChannelDepth(magick_wand,RedChannel));
    145     printf("GreenChannelDepth is %d
    ",MagickGetImageChannelDepth(magick_wand,GreenChannel));
    146     printf("BlueChannelDepth is %d
    ",MagickGetImageChannelDepth(magick_wand,BlueChannel));
    147     printf("GrayChannelDepth is %d
    ",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
    ",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
    ",IMageDepth);
    248 
    249 
    250     //得到图像宽度和高度
    251     int Height;
    252 
    253     Height = (int)MagickGetImageHeight(magick_wand);
    254 
    255     printf("The Current Image Height is %d
    ",Height);
    256 
    257     int Width;
    258 
    259     Width = (int)MagickGetImageWidth(magick_wand);
    260 
    261     printf("The Current Image Width is %d
    ",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
    ",MagickGetImageChannelDepth(magick_wand,RedChannel));
    277     printf("GreenChannelDepth is %d
    ",MagickGetImageChannelDepth(magick_wand,GreenChannel));
    278     printf("BlueChannelDepth is %d
    ",MagickGetImageChannelDepth(magick_wand,BlueChannel));
    279     printf("GrayChannelDepth is %d
    ",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
    ",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

  • 相关阅读:
    HTML <iframe> 标签
    HTML <tr> 标签
    HTML <img> 标签的 border 属性
    jQuery ajax ajax() 方法
    CSS padding 属性
    SQL Server CONVERT() 函数
    CSS overflow 属性
    HTML <input> 标签
    Java动态代理一——动态类Proxy的使用
    Java拆箱装箱小结
  • 原文地址:https://www.cnblogs.com/foohack/p/3459865.html
Copyright © 2020-2023  润新知