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对象中(附源码)

VC++几种加载图片方法的讨论(附源码)

VC++屏幕捕获并保存成图片(附源码)

VC++使用GDI+实现HBITMAP与图片文件之间的相互转换(附源码)

用Python做了个图片识别系统(附源码)

用Python做了个不良图片识别系统(附源码)