图像解析库使用范例

范例包括libgif,libpng和libjpeg,图像类型判断如下,其中fData是图像数据的首地址

    //png
    if (!png_sig_cmp((png_byte*)fData, (png_size_t)0, 4))
    {
        return EN_IMG_TYIE_PNG;
    }
    // gif
    if (memcmp(GIF_STAMP,   fData, GIF_STAMP_LEN) == 0 ||
            memcmp(GIF87_STAMP, fData, GIF_STAMP_LEN) == 0 ||
            memcmp(GIF89_STAMP, fData, GIF_STAMP_LEN) == 0)
    {
        return EN_IMG_TYIE_GIF;
    }

    // jpg
    char gHeader[] = { 0xFF, 0xD8, 0xFF };
    if (memcmp(fData, gHeader, 3) == 0)
    {
        return EN_IMG_TYIE_JPG;
    }
    // bmp
    char kBmpMagic[] = { 'B', 'M' };
    if (memcmp(fData, kBmpMagic, 2) == 0)
    {
        return EN_IMG_TYIE_BMP;
    }
    return EN_IMG_TYPE_NONE;


解析png代码如下:fData是png图像数据,fSize是数据长度,width和height是输出参数,存放图像的宽和高,返回RGBA格式的图像数据

unsigned char* BwImageDecode::DecodeMemoryPNG(unsigned char* fData, long fSize, int& width, int& height)
{
    png_structp png_ptr;
    png_infop info_ptr;
    int bit_depth, color_type;
    png_bytep *row_pointers = NULL;
    unsigned char* image_data;
    int rowbytes;

    /* Create a png read struct */
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
    {
        return NULL;
    }

   /* Create a png info struct */
    info_ptr = png_create_info_struct (png_ptr);
    if (!info_ptr)
    {
        png_destroy_read_struct (&png_ptr, NULL, NULL);
        return NULL;
    }

    /* Initialize the setjmp for returning properly after a libpng error occured */
    if (setjmp (png_jmpbuf (png_ptr)))
    {
        png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

        if (row_pointers)
            free (row_pointers);

        return NULL;
    }

    ImageSource imgsource;
    imgsource.data = fData;
    imgsource.size = fSize;
    imgsource.offset = 0;
    png_set_read_fn(png_ptr, &imgsource, memReadFuncPng);

    /* Read png info */
    png_read_info (png_ptr, info_ptr);

    /* Get some usefull information from header */
    bit_depth = png_get_bit_depth (png_ptr, info_ptr);
    color_type = png_get_color_type (png_ptr, info_ptr);

    /* Convert index color images to RGB images */
    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb (png_ptr);

    /* Convert RGB images to RGBA images */
    if (color_type == PNG_COLOR_TYPE_RGB)
        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);

    /* Convert 1-2-4 bits grayscale images to 8 bits grayscale. */
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_gray_1_2_4_to_8 (png_ptr);

    if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_tRNS_to_alpha (png_ptr);

    if (bit_depth == 16)
        png_set_strip_16 (png_ptr);
    else if (bit_depth < 8)
        png_set_packing (png_ptr);

    /* Update info structure to apply transformations */
    png_read_update_info (png_ptr, info_ptr);

    /* Retrieve updated information */
    png_get_IHDR (png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, &bit_depth, &color_type, NULL, NULL, NULL);

    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
    if ((image_data =(unsigned char *) malloc(height * rowbytes)) == NULL)
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return NULL;
    }

    /* Setup a pointer array.  Each one points at the begening of a row. */
    if ((row_pointers =(png_bytepp) malloc(height * sizeof(png_bytep))) == NULL)
    {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        free(image_data);
        return NULL;
    }
    for (int i = 0; i < height; i++)
        row_pointers[height - 1 - i] = image_data + i*rowbytes;

    /* Read pixel data using row pointers */
    png_read_image (png_ptr, row_pointers);

    /* Finish decompression and release memory */
    png_read_end (png_ptr, NULL);
    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

    /* We don't need row pointers anymore */
    free (row_pointers);

    return image_data;
}

解析jpg代码如下:fData是jpg图像数据,fSize是数据长度,width和height是输出参数,存放图像的宽和高,返回RGBA格式的图像数据

unsigned char* BwImageDecode::DecodeMemoryJPG(unsigned char* fData, long fSize, int& width, int& height)
{

    unsigned char* image_data;
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    unsigned char* buffer;
    int row_stride;
    int out_color_components = 4;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);

    //从内存读取
    jpeg_stdio_buffer_src(&cinfo, fData, fSize);

    jpeg_read_header(&cinfo, TRUE);
//    cinfo.out_color_components = 3;
//    cinfo.out_color_space = JCS_RGB;

    jpeg_start_decompress(&cinfo);
    width = cinfo.output_width;
    height = cinfo.output_height;

    row_stride = cinfo.output_width * cinfo.output_components;
    buffer = (unsigned char*)malloc(row_stride);
    image_data = (unsigned char*)malloc(cinfo.output_width * cinfo.output_height * out_color_components);

    while (cinfo.output_scanline < cinfo.output_height)
    {
        unsigned char * p = image_data + (cinfo.output_width * out_color_components * cinfo.output_scanline);
        jpeg_read_scanlines(&cinfo, &buffer, 1);
        for(int i=0; i < width; i++)
        {
            p[4*i  ] = buffer[3*i];
            p[4*i+1] = buffer[3*i+1];
            p[4*i+2] = buffer[3*i+2];
            p[4*i+3] = 0xff;
        }
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    free(buffer);

    return image_data;
}


解析gif代码如下:fData是gif图像数据,fSize是数据长度,width和height是输出参数,存放图像的宽和高,index是第几帧,返回RGBA格式的图像数据
static int memReadFuncGif(GifFileType* GifFile, GifByteType* buf, int count)
{
    char* ptr = (char*)(GifFile->UserData);
    memcpy(buf, ptr, count);
    GifFile->UserData = ptr + count;
    return count;
}
unsigned char* BwImageDecode::DecodeMemoryGIF(unsigned char* fData, long fSize, int& width, int& height, int index)
{
    GifFileType *GifFile;

    if ((GifFile = DGifOpen(fData, memReadFuncGif)) == NULL)
    {
       return 0;
    }

    if (DGifSlurp(GifFile) == 0)
    {
       return 0;
    }

    unsigned char *image_data = 0, *src = 0, *dst = 0;
    ColorMapObject *ColorMap;
    SavedImage *saveImg;
    GifRowType *ScreenBuffer;
    GifColorType *ColorMapEntry;
    int loc = 0;

    if (index >= GifFile->ImageCount)
    {
        return 0;
    }
//    index = index % GifFile->ImageCount;

    ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap);
    saveImg = &(GifFile->SavedImages[index]);
    ScreenBuffer = &(saveImg->RasterBits);

    if ((image_data = (unsigned char *) malloc(GifFile->SWidth * 4 * GifFile->SHeight)) == NULL)
    {
        DGifCloseFile(GifFile);
        return 0;
    }
    src = saveImg->RasterBits;
    dst = image_data;

    for (int i = 0; i < GifFile->SHeight; i++)
    {
        loc = GifFile->SWidth * i;
        for (int j = 0; j < GifFile->SWidth; j++)
        {
            ColorMapEntry = &(ColorMap->Colors[*(src + loc + j)]);
            *dst++ = ColorMapEntry->Red;
            *dst++ = ColorMapEntry->Green;
            *dst++ = ColorMapEntry->Blue;
            *dst++ = 255;
        }
    }

    width = GifFile->SWidth;
    height = GifFile->SHeight;

//    {
//        m_ImageCount = GifFile->ImageCount;
//        m_ImageWidth = GifFile->SWidth;
//        m_ImageHeight = GifFile->SHeight;
//        m_GifFile = GifFile;
//        m_ImageData = image_data;
//    }

    DGifCloseFile(GifFile);
    return image_data;
}
void* BwImageDecode::DecodeMemoryGIFImage(unsigned char* fData, long fSize, int& width, int& height)
{
    GifFileType *GifFile;

    if ((GifFile = DGifOpen(fData, memReadFuncGif)) == NULL)
    {
       return 0;
    }

    if (DGifSlurp(GifFile) == 0)
    {
       return 0;
    }

    width = GifFile->SWidth;
    height = GifFile->SHeight;
    return GifFile;
}
unsigned char* BwImageDecode::getGifImage(void* gifFile, int index)
{
    if (gifFile == 0) return 0;

    GifFileType *GifFile = (GifFileType *)gifFile;

    unsigned char *image_data = 0, *src = 0, *dst = 0;
    ColorMapObject *ColorMap;
    SavedImage *saveImg;
    GifRowType *ScreenBuffer;
    GifColorType *ColorMapEntry;
    int loc = 0;

    if (index >= GifFile->ImageCount)
    {
        return 0;
    }
    index = index % GifFile->ImageCount;

    ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap);
    saveImg = &(GifFile->SavedImages[index]);
    ScreenBuffer = &(saveImg->RasterBits);

    if ((image_data = (unsigned char *) malloc(GifFile->SWidth * 4 * GifFile->SHeight)) == NULL)
    {
        DGifCloseFile(GifFile);
        return 0;
    }
    src = saveImg->RasterBits;
    dst = image_data;

    for (int i = 0; i < GifFile->SHeight; i++)
    {
        loc = GifFile->SWidth * i;
        for (int j = 0; j < GifFile->SWidth; j++)
        {
            ColorMapEntry = &(ColorMap->Colors[*(src + loc + j)]);
            *dst++ = ColorMapEntry->Red;
            *dst++ = ColorMapEntry->Green;
            *dst++ = ColorMapEntry->Blue;
            *dst++ = 255;
        }
    }

//    LOGE("getGifImage  --  %d",image_data);
    return image_data;
}
char *BwImageDecode::getGIFDuration(void* gifFile)
{
    if (gifFile == 0) return 0;

    GifFileType *GifFile = (GifFileType *)gifFile;

    char * duration = (char*)malloc(GifFile->ImageCount);//new char[GifFile->ImageCount];

    for (int i = 0; i < GifFile->ImageCount; i++)
    {
        duration[i] = savedimage_duration(&GifFile->SavedImages[i]);
    }
    return duration;
}
int BwImageDecode::savedimage_duration(const SavedImage* image)
{
    for (int j = 0; j < image->ExtensionBlockCount; j++)
    {
        if (image->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE)
        {
            int size = image->ExtensionBlocks[j].ByteCount;
            const uint8_t* b = (const uint8_t*)image->ExtensionBlocks[j].Bytes;
            return ((b[2] << 8) | b[1]) * 10;
        }
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值