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