VC++图片类型的识别(附源码)

       我们平时常用的图片类型有jpg、bmp、png和gif等,一般情况下我们会根据图片的后缀名去判断图片的类型,其实这样做是不科学的,文件的后缀名是可以随意修改的,但文件的内容始终是不变的,不会因为后缀名的修改,就变成修改后的文件类型了。

VC++图片类型的识别(附源码)_第1张图片

       有时我们的代码中是需要识别图片的类型的。比如对于.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++常用功能代码封装,图片类型,bmp,jpg,png,gif)