• 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

  • 相关阅读:
    如何在Ubuntu Server 18.04上安装Microsoft的Procmon
    如何在Ubuntu 20.04上安装Wine 5.0
    如何在Kali Linux 2020中启用SSH服务
    如何在Ubuntu 20.04 LTS Focal Fossa上安装Apache Groovy
    如何使用命令在Ubuntu 20.04 Linux上安装Vmware Tools
    在Ubuntu 20.04 LTS Focal Fossa上安装Zabbix Agent
    hdu 2089 不要62
    hdu 2093 成绩排名
    hdu 2104 hide handkerchief
    leetcode147对链表进行插入排序
  • 原文地址:https://www.cnblogs.com/foohack/p/3459865.html
Copyright © 2020-2023  润新知