牛骨文教育服务平台(让学习变的简单)

没有躲过的坑--获取一张图片的width和height

有时候问题总是被想的过于复杂!

简单说就是读取一张图片,然后得到这个图片的width和height。

首先,用到的库没有Image这个控件,所以不能从控件获得图片的高和宽。

于是GOOGLE了一个算法,稍作修改,对于不同的类型有不同的计算方法,上代码吧:

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
    string fname = "D:暴走.png";
    ifstream ffin(fname, std::ios::binary);

    if (!ffin) {
        cout << "Can not open this file." << endl;
        return 0;
    }
    int image_type = 0;
    char c = fname.at(fname.length() - 1);
    char c2 = fname.at(fname.length() - 3);

    if ((c == "f") && (c2 == "g")) {  // file extension name is gif 
        image_type = 1;
    }
    else if ((c == "g") && (c2 == "j")) { // file extension name is jpg
        image_type = 2;
    }
    else if ((c == "g") && (c2 == "p")) { // file extension name is png
        image_type = 3;
    }
    else if ((c == "p") && (c2 == "b")) { // file extension name is bmp
        image_type = 4;
    }

    char s1[2] = { 0 };
    char s2[2] = { 0 };
    long m_Width = 0;
    long m_Height = 0;
    switch (image_type)
    {
    case 1:  // gif  
        ffin.seekg(6);
        ffin.read(s1, 2);
        ffin.read(s2, 2);
        m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
        m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
        break;
    case 2:  // jpg
        ffin.seekg(164);
        ffin.read(s1, 2);
        ffin.read(s2, 2);
        m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
        m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
        break;
    case 3:   // png
        ffin.seekg(17);
        ffin.read(s1, 2);
        ffin.seekg(2, std::ios::cur);
        ffin.read(s2, 2);
        m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
        m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
        break;
    case 4:   // bmp    
        ffin.seekg(18);
        ffin.read(s1, 2);
        ffin.seekg(2, std::ios::cur);
        ffin.read(s2, 2);
        m_Width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
        m_Height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
        break;
    default:
        cout << "NO" << endl;
        break;
    }
    ffin.close();
    cout << "width:" << m_Width  << endl;
    cout << "height:" << m_Height << endl;
}

上述代码的优点就是,不用读取整个图片的大小,效率是很高的。

但是,有一个很大的坑,就是无法计算出小于24kb的图片,这不是坑爹的吗?

咨询了一下其他平台的做法,用了一个叫ImageMagic的库,用于图片的处理很强大。配置了好久,但是还是会报错。也许跟vs编译器的版本有关吧。况且为了一个小小的功能就引入一个库,未免有点小题大做了。

蓦然回首,CImage类正等着呢!

原来忘记了最基本的windows GDI了。

好吧,别忘了,引入头文件:

#include<iostream>
#include<atlimage.h>
int main()
{
    CImage m;
    std::wstring imgPath = _T("d:222.png");
    m.Load(imgPath.c_str());
    std::cout << m.GetWidth() << std::endl;

    return 0;
}

没有躲过的坑儿–我们忽略那些微小而基本的功能!