在特定的应用场景下,有时候我们只是想获取图片的宽高,

但不想通过解码图片才取得这个信息。

预先知道图片的宽高信息,进而提速图片加载,预处理等相关操作以提升体验。

在stackoverflow有一篇相关讨论。

Get Image size WITHOUT loading image into memory
http://stackoverflow.com/questions/15800704/python-get-image-size-without-loading-image-into-memory/

不加图片到内存,而取得图像的大小。

这个技巧具有一定的实用价值,博主据此进行了相应的编码。

实现了 常用图片格式(png,jpeg,ico,bmp,gif) 不采用第三方解码库,解析得到图像宽高的函数get_image_size_without_decode_image。

bool get_image_size_without_decode_image(const char* file_path, int*width, int*height);

完整代码:

#include <stdio.h>
#include <sys/stat.h> 

unsigned long byteswap_ulong(unsigned long i)
{
    unsigned int j;
    j = (i << );
    j += (i << ) & 0x00FF0000;
    j += (i >> ) & 0x0000FF00;
    j += (i >> );
    return j;
} 

inline int Abs(int x) {
    )) - (x >> );
}

unsigned short byteswap_ushort(unsigned short i)
{
    unsigned short j;
    j = (i << );
    j += (i >> );
    return j;
}

// Get Image size WITHOUT loading image into memory
// ref: http://stackoverflow.com/questions/15800704/python-get-image-size-without-loading-image-into-memory/
// 博客: http://tntmonks.cnblogs.com/
// 邮箱: gaozhihan@vip.qq.com
bool get_image_size_without_decode_image(const char* file_path, int*width, int*height)
{
    bool has_image_size = false;
    *height = -;
    *width = -;
    ;
    FILE * fp = fopen(file_path, "rb");
    if (fp == NULL)
        return has_image_size;
    struct stat st;
    ];
    )
    {
        fclose(fp);
        return has_image_size;
    }
    else
    {
        file_size = st.st_size;
    }
    , , fp) < )
    {
        fclose(fp);
        return has_image_size;
    }
    char* png_signature = "\211PNG\r\n\032\n";
    unsigned ] = { 'I', 'H', 'D', 'R' };
    char* gif87_signature = "GIF87a";
    char* gif89_signature = "GIF89a";
    char* jpeg_signature = "\377\330";
    char* bmp_signature = "BM";
    ) && (memcmp(sigBuf, gif87_signature, strlen(gif87_signature)) ==  || memcmp(sigBuf, gif89_signature, strlen(gif89_signature)) == ))
    {
        // image type: gif
        unsigned );
        *width = size_info[];
        *height = size_info[];
        has_image_size = true;
    }
    ) && (memcmp(sigBuf, png_signature, strlen(png_signature)) ==  && memcmp(sigBuf + , ihdr_signature, strlen(ihdr_signature)) == ))
    {
        // image type:   png
        unsigned );
        *width = byteswap_ulong(size_info[]);
        *height = byteswap_ulong(size_info[]);
        has_image_size = true;
    }
    ) && (memcmp(sigBuf, png_signature, strlen(png_signature)) == ))
    {
        // image type: old png
        unsigned );
        *width = byteswap_ulong(size_info[]);
        *height = byteswap_ulong(size_info[]);
        has_image_size = true;
    }
    ) && (memcmp(sigBuf, jpeg_signature, strlen(jpeg_signature)) == ))
    {
        // image type: jpeg
        fseek(fp, , SEEK_SET);
        ;
        fread(&sigBuf, , , fp);
        fread(&b, , , fp);
        ;
        ;
        while (b && ((unsigned char)b & 0xff) != 0xDA) {
            while (((unsigned char)b & 0xff) != 0xFF)
            {
                fread(&b, , , fp);
            }
            while (((unsigned char)b & 0xff) == 0xFF) {
                fread(&b, , , fp);
            }
            if (((unsigned char)b & 0xff) >= 0xC0 && ((unsigned char)b & 0xff) <= 0xC3)
            {
                fread(&sigBuf, , , fp);
                fread(&sigBuf, , , fp);
                unsigned short* size_info = (unsigned short*)(sigBuf);
                h = byteswap_ushort(size_info[]);
                w = byteswap_ushort(size_info[]);
            }
            else
            {
                unsigned ;
                fread(&chunk_size, , , fp);
                , SEEK_CUR) != )
                    break;
            }
            fread(&b, , , fp);
        }
         && h != -)
        {
            *width = w;
            *height = h;
        }
        has_image_size = true;
    }
    ) && (memcmp(sigBuf, bmp_signature, strlen(bmp_signature)) == ))
    {
        // image type: bmp
        unsigned ));
        )
        {
            unsigned );
            *width = size_info[];
            *height = size_info[];
        }
        )
        {
            unsigned );
            *width = size_info[];
            *height = Abs((size_info[]));
        }
        has_image_size = true;
    }
    )
    {
        // image type: ico
        fseek(fp, , SEEK_SET);
        unsigned ;
        unsigned ;
        fread(&reserved, , , fp);
        fread(&format, , , fp);
         && format == )
        {
            unsigned ;
            fread(&num, , , fp);
            )
            {
                printf("ico 包含多个图片");
            }
            else
            {
                , h = ;
                fread(&w, , , fp);
                fread(&h, , , fp);
                *width = int((unsigned char)w & 0xff);
                *height = int((unsigned char)h & 0xff);
            }
        }
        has_image_size = true;
    }
    if (fp != NULL)
        fclose(fp);
    return has_image_size;
}

调用方法:

const char* file_path = "d:\\test.png";

int h, w;
get_image_size_without_decode_image(file_path , &w, &h);

传入图片的位置,输出对应的宽高,高和宽 为-1时,就是解析失败了。

代码比较简单,不多注释了。

若有其他相关问题或者需求可以邮件联系俺探讨。

邮箱地址是: 
gaozhihan@vip.qq.com

不用第三方解码码取得图片宽高 附完整C++算法实现代码的更多相关文章

  1. 不用第三方解码库取得图片宽高 附完整C++算法实现代码

    在特定的应用场景下,有时候我们只是想获取图片的宽高, 但不想通过解码图片才取得这个信息. 预先知道图片的宽高信息,进而提速图片加载,预处理等相关操作以提升体验. 在stackoverflow有一篇相关 ...

  2. JS快速获取图片宽高的方法

    快速获取图片的宽高其实是为了预先做好排版样式布局做准备,通过快速获取图片宽高的方法比onload方法要节省很多时间,甚至一分钟以上都有可能,并且这种方法适用主流浏览器包括IE低版本浏览器. 我们一步一 ...

  3. 转载:JS快速获取图片宽高的方法

    快速获取图片的宽高其实是为了预先做好排版样式布局做准备,通过快速获取图片宽高的方法比onload方法要节省很多时间,甚至一分钟以上都有可能,并且这种方法适用主流浏览器包括IE低版本浏览器. 我们一步一 ...

  4. JS实现图片宽高的等比缩放

    关于图片宽高的等比缩放,其实需求就是让图片自适应父容器的宽高,并且是等比缩放图片,使图片不变形. 例如,需要实现如下的效果: 要实现上面的效果,需要知道图片的宽高,父容器的宽高,然后计算缩放后的宽高. ...

  5. php 图片上传的公共方法(按图片宽高缩放或原图)

    写的用于图片上传的公共方法类调用方法: $upload_name='pic';$type = 'logo_val';$file_name = 'logo_' . $user_id .create_st ...

  6. css3圆形头像(当图片宽高不相等时)

    1.图片宽高相等,width:300px: height:300px; 把他变成宽高100px的圆形头像 img{width:100px; height:100px; border-radius:50 ...

  7. js不需要知道图片宽高的懒加载方法(经过实际测试,不加宽高仍然是无法正常加载的,设置height:auto,height:100%,仍然显示高度为0)

    js不需要知道图片宽高的懒加载方法 懒加载是如何实现的? - 简书https://www.jianshu.com/p/e86c61468285找到一个不需要知道图片宽高的懒加载方法了(经过实际测试,不 ...

  8. css+background实现 图片宽高自适应,拉伸裁剪不变形

    图片宽高不固定 ,一样实现自适应,拉伸裁剪不变形,适应各大兼容性.  下面咱们在网上找两张宽高不一样的照片:     No.1                                      ...

  9. 写个js动态调整图片宽高 (原创)

    <body style="TEXT-ALIGN: center;"> <div id="testID" style="backgro ...

随机推荐

  1. 设置两个div是总是不能重合,浏览器user agent stylesheet问题

    如图 两个div之间总是有一个空行,设置了margin为0还是没卵用,f12调试发现 多了一个user agent stylesheet样式,经百度是浏览器自带的样式 重新为div内的元素ul设置cs ...

  2. 指针变量的*p,p以及&p的区别

    23/7/2017  决定夯实基础,回顾指针的知识点,该博文转载于CSDN博主百家晓东,小部分修改,外加编译图引证 正文如下: 以下面的情况说明: int a = 5; int* p = &a ...

  3. iOS 中Block以及Blocks的使用,闭包方法调用

    OC: -(void)dataWithUrl:(NSString*)string AndId:(NSInteger)id returnName:(void(^)(NSString*name))back ...

  4. scala写算法-用小根堆解决topK

    topK问题是指从大量数据中获取最大(或最小)的k个数,比如从全校学生中寻找成绩最高的500名学生等等. 本问题可采用小根堆解决.思路是先把源数据中的前k个数放入堆中,然后构建堆,使其保持堆序(可以简 ...

  5. ArcGIS 网络分析[2.1] 最短路径

    最短路径求解 [如果看到此博客还没有网络数据集的,请参考第一章的内容,点击我,看目录] 最短路径,是什么最短?时间最短?距离最短?什么距离?路程距离? 考虑到拥堵问题,限速问题,换乘问题,在现实的最短 ...

  6. 《跟我学IDEA》五、快捷键(编码利器)

    上一篇博文,我们学习了idea的一些模版配置,但是只有模版是不行的,一款编辑器如何能为我们灵活的使用,快捷键的功劳不用多说大家也明白.今天我们就来学习快捷键的配置以及一些常用的快捷键的介绍,为让家能更 ...

  7. SQL语句 我喜欢上海

    select * from [user] wherer name like '上海%'

  8. 正则表达式与grep

    一.回溯引用 1.将页面中合法的标题找出来,使用回溯引用匹配 (需要使用 -E 或 -P 来扩展grep语法支持) 2.查找连续出现的单词 二.前后查找 (grep 只能使用 -P 选项) 1. 向前 ...

  9. Python中range()和len()

  10. Ascall 码特殊字符——去除从windows上传文件的^M

    在windows上编辑过的文件如果传到unix上,在每个文件的末尾都会有一个换行控制符^M,这个字符一般处于隐藏状态,除非cat -A才能看到,如果不去掉这个符号,很多脚本不能正常运行,很多文件不能正 ...