一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C/C++ - C++中圖片類型的識(shí)別與轉(zhuǎn)換詳解方法

C++中圖片類型的識(shí)別與轉(zhuǎn)換詳解方法

2022-02-23 13:56link-初揚(yáng) C/C++

本文簡(jiǎn)單的介紹一下C++語(yǔ)言中如何識(shí)別圖片文件的類型,以及各圖片類型之間的轉(zhuǎn)換方法,并提供相關(guān)的源碼供大家參考,感興趣的朋友快來(lái)看看吧

1、圖片類型的識(shí)別

一般情況下,不同類型的圖片文件都會(huì)有其對(duì)應(yīng)的后綴名,比如.jpg、.bmp、.jpg等。但僅僅通過后綴名,是沒法判別文件是不是圖片以及圖片文件真實(shí)類型,必須通過文件內(nèi)容的起始標(biāo)記字段才能判斷出來(lái)。

C++中圖片類型的識(shí)別與轉(zhuǎn)換詳解方法

每種圖片文件的類型標(biāo)識(shí)字段存儲(chǔ)于文件內(nèi)容開始的幾個(gè)字節(jié),讀出這幾個(gè)字節(jié)就能判斷出圖片類型了。下面給出常見的圖片類型的判斷代碼。

以下代碼都是調(diào)用_tfopen(支持Unicode)打開文件,調(diào)用fread讀出文件中的類型標(biāo)記數(shù)據(jù)。注意,打開文件時(shí)必須設(shè)置 b - 二進(jìn)制參數(shù),如果不設(shè)置,調(diào)用fread時(shí)可能讀不出指定字節(jié)數(shù)的內(nèi)容!

1.1、bmp圖片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
BOOL32 IsBmpFile( LPCTSTR lpStrFilePath )
{
    FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
    if ( pFile == NULL )
    {
        return FALSE;
    }
 
    char szData[2] = {0};
    int nReadNum = fread( szData, sizeof(char), 2, pFile );
    if ( nReadNum < 2 )
    {
        fclose( pFile );
        return FALSE;
    }
 
    fclose( pFile );
 
    // bmp: 0x42, 0x4d
    unsigned char szBmpFlag = { 0x42, 0x4d };
    if ( !memcmp( szBmpFlag, szData, 2 ) )
    {      
        return TRUE;
    }  
 
    return FALSE;
}

1.2、jpg圖片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
BOOL32 IsJpgFile( LPCTSTR lpStrFilePath )
{
    FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
    if ( pFile == NULL )
    {
        return FALSE;
    }
 
    char szData[2] = {0};
    int nReadNum = fread( szData, sizeof(char), 2, pFile );
    if ( nReadNum < 2 )
    {
        fclose( pFile );
        return FALSE;
    }
 
    fclose( pFile );
    
    // jpg: 0xFF, 0xD8
    unsigned char szJpgFlag[] = { 0xFF, 0xD8 };
    if ( !memcmp( szJpgFlag, szData, 2 ) )
    {      
        return TRUE;
    }  
 
    return FALSE;
}

1.3、jpg圖片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
BOOL32 IsPngFile( LPCTSTR lpStrFilePath )
{
    FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
    if ( pFile == NULL )
    {
        return FALSE;
    }
 
    char szData[8] = {0};
    int nReadNum = fread( szData, sizeof(char), 8, pFile );
    if ( nReadNum < 8 )
    {
        fclose( pFile );
        return FALSE;
    }
 
    fclose( pFile );
 
    // png: 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
    unsigned char szPngFlag[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
    if ( !memcmp( szPngFlag, szData, 8 ) )
    {      
        return TRUE;
    }  
 
    return FALSE;
}

1.4、gif圖片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
BOOL32 IsGifFile( LPCTSTR lpStrFilePath )
{
    FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
    if ( pFile == NULL )
    {
        return FALSE;
    }
 
    char szData[6+1] = {0};
    int nReadNum = fread( szData, sizeof(char), 6, pFile );
    if ( nReadNum < 6 )
    {
        fclose( pFile );
        return FALSE;
    }
 
    fclose(pFile);
 
    // 使用字符串判斷更直觀
    if ( strcmp( szData, "GIF89a" ) == 0 || strcmp( szData, "GIF87a" ) == 0 )
    {
        return TRUE;
    }
 
    return FALSE;
}

1.5、tiff圖片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
BOOL32 IsTiffFile( LPCTSTR lpStrFilePath )
{
    FILE* pFile = _tfopen( lpStrFilePath, _T("rb") );
    if ( pFile == NULL )
    {
        return FALSE;
    }
 
    char szData[4] = {0};
    int nReadNum = fread( szData, sizeof(char), 4, pFile );
    if ( nReadNum < 4 )
    {
        fclose( pFile );
        return FALSE;
    }
 
    fclose( pFile );
 
    // jpg: 0x49, 0x49, 0x2A, 0x00
    unsigned char szTiffFlag[] = { 0x49, 0x49, 0x2A, 0x00 };
    if ( !memcmp( szTiffFlag, szData, 2 ) )
    {      
        return TRUE;
    }  
 
    return FALSE;
}

1.6、使用CreateFile和ReadFile API函數(shù)讀取內(nèi)容

上面是使用fopen和fread讀取文件中的內(nèi)容的,下面給出調(diào)用CreateFile和ReadFile API函數(shù)實(shí)現(xiàn)的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
BOOL32 IsJpgFile( LPCTSTR lpStrFilePath )
{
        HANDLE hFile = ::CreateFile(lpStrFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
        {
                return FALSE;
        }
 
        unsigned char szData[4] = { 0 };
 
        DWORD dwReadNum;
        if (!::ReadFile((HANDLE)hFile, szData, 4, &dwReadNum, NULL))
        {
                CloseHandle(hFile);
                return FALSE;
        }
 
        if ( dwReadNum< 4 )
        {
                CloseHandle(hFile);
                return FALSE;
        }       
 
        CloseHandle(hFile);
 
        unsigned char szJpgFlag[] = { 0xFF, 0xD8 };
 
        // 0xFF,0xD8
        if ( !memcmp( szJpgFlag, szData, 2 ) )
        {               
                return TRUE;
        }      
 
 
        return FALSE;
}

2、圖片之間的相互轉(zhuǎn)換

有時(shí)我們需要進(jìn)行不同圖片類型之間的相互轉(zhuǎn)換,比如將占用較大存儲(chǔ)空間的bmp圖片轉(zhuǎn)換成jpg或者jpg圖片??梢赃x擇使用GDI+類實(shí)現(xiàn)不同圖片類型之間的轉(zhuǎn)換。在使用GDI+之前,要先初始化GDI+庫(kù):

?
1
2
3
4
ULONG_PTR m_gdiplusToken;
    
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup( &m_gdiplusToken, &gdiplusStartupInput, NULL );

在退出程序時(shí),要關(guān)閉GDI+庫(kù):

?
1
Gdiplus::GdiplusShutdown( m_gdiplusToken );

實(shí)現(xiàn)圖片類型之間相互轉(zhuǎn)換的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 根據(jù)目標(biāo)文件的后綴確定要轉(zhuǎn)換成的目標(biāo)文件類型
BOOL32 SaveImgFileToAnotherType( const CString& strSrcFile, const CString& strDstFile )
{
    // 使用CImage實(shí)現(xiàn)不同格式圖片文件的轉(zhuǎn)換
    if ( strDstFile.IsEmpty() )
    {
        return FALSE;
    }
 
    CImage img;
    HRESULT hResult = img.Load( strSrcFile ); // 加載源圖片文件
    if ( hResult != S_OK )
    {
        return FALSE;
    }
 
    GUID guidFileType = Gdiplus::ImageFormatPNG; // 默認(rèn)保存為png圖片
    CString strExt;
    s32 nIndex = strDstFile.ReverseFind( _T('.') );
    if ( nIndex != -1 )
    {
        strExt = strDstFile.Right( strDstFile.GetLength() - nIndex - 1 );
        if ( strExt == _T("png") )
        {
            guidFileType = Gdiplus::ImageFormatPNG;
        }
        else if ( strExt == _T("jpg"))
        {
            guidFileType = Gdiplus::ImageFormatJPEG;
        }
        else if ( strExt == _T("bmp") )
        {
            guidFileType = Gdiplus::ImageFormatBMP;
        }
        else if ( strExt == _T("gif") )
        {
            guidFileType = Gdiplus::ImageFormatGIF;
        }
        else
        {
            guidFileType = Gdiplus::ImageFormatPNG;
        }
    }
 
    hResult = img.Save( strDstFile, guidFileType ); // 保存為目標(biāo)文件
    if ( hResult != S_OK )
    {
        return FALSE;
    }
 
    return TRUE;
}

以上就是C++中圖片類型的識(shí)別與轉(zhuǎn)換詳解方法的詳細(xì)內(nèi)容,更多關(guān)于C++ 圖片類型轉(zhuǎn)換的資料請(qǐng)關(guān)注服務(wù)器之家其它相關(guān)文章!

原文鏈接:https://blog.csdn.net/chenlycly/article/details/121130312

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 视频国产91 | 色视频国产 | 操爽| 日韩中文字幕视频在线观看 | 日本黄色大片免费观看 | 国产一区二区三区四区波多野结衣 | 色哟哟在线视频 | 久久视频精品3线视频在线观看 | 午夜深情在线观看免费 | 天海翼最新作品 | 国产欧美精品专区一区二区 | 911亚洲精品国内自产 | 无人区1免费完整观看 | 精品高潮呻吟99AV无码 | 久久精品中文字幕 | 日韩精品免费一区二区 | 午夜福利08550 | 5x视频在线观看 | 91制片厂制作果冻传媒八夷 | 亚洲冬月枫中文字幕在线看 | 日日爽日日操 | 亚洲日韩男人网在线 | 美女免费观看一区二区三区 | 王雨纯 羞羞 | 国产亚洲精品美女 | 97se狠狠狠狠狼亚洲综合网 | 国产成人精视频在线观看免费 | 男女污网站 | 丰满艳妇亲伦视频 | 免费国产成人α片 | 亚洲99久久无色码中文字幕 | bl超h 高h 污肉快穿np | 青青草国产免费国产是公开 | 男人疯狂擦进女人下面 | 国产成人亚洲精品91专区高清 | 99视频全部免费 | 日韩手机在线观看 | 潘金莲西门庆一级淫片aaaaaa | 欧美日韩中文字幕一区二区高清 | 国产欧美日韩精品一区二区三区 | 国产在线视频欧美亚综合 |