VC++图片类型的识别(附源码)
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++图片类型的识别(附源码)相关的知识,希望对你有一定的参考价值。
我们平时常用的图片类型有jpg、bmp、png和gif等,一般情况下我们会根据图片的后缀名去判断图片的类型,其实这样做是不科学的,文件的后缀名是可以随意修改的,但文件的内容始终是不变的,不会因为后缀名的修改,就变成修改后的文件类型了。
有时我们的代码中是需要识别图片的类型的。比如对于.bmp位图文件,可能bmp格式的图片大小比较大,我们需要把这个图片通过网络发出去,为了减轻网络的发送压力,我们需要将图片转成jpg或png图片后再将图片发送出去。因为jpg或png格式的图片有着较高的压缩率,可以有效地较少图片文件的大小,这样就减轻了图片再网络传输的压力。
那如何通过代码去鉴别文件的真实图片类型呢?其实很简单,可以通过fread等函数读出文件内容最开始的若干个字节来判断,每种图片的都有对应的类型标识。
1、bmp图片
bmp图片文件的前2个字节存放bmp类型标识,识别代码如下:
BOOL 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;
2、jpg图片
jpg图片文件的前2个字节存放jpg类型标识,识别代码如下:
BOOL 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;
3、png图片
png图片文件的前8个字节存放png类型标识,识别代码如下:
BOOL 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;
4、gif图片
gif图片文件的前6个字节存放gif类型标识,识别代码如下:
BOOL 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;
5、tiff图片
tiff图片文件的前4个字节存放tiff类型标识,识别代码如下:
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;
上述代码是通过C函数fopen、fread去读取文件中的内容的,也可以使用Windows API函数CreateFile、ReadFile等去读取的,比如:
BOOL 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;
以上是关于VC++图片类型的识别(附源码)的主要内容,如果未能解决你的问题,请参考以下文章
VC++如何将rc资源中的图片加载到MFC的CImage对象中(附源码)