欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2021年11月15日 10:31:39   作者:link-初揚(yáng)  
本文簡單的介紹一下C++語言中如何識別圖片文件的類型,以及各圖片類型之間的轉(zhuǎn)換方法,并提供相關(guān)的源碼供大家參考,感興趣的朋友快來看看吧

1、圖片類型的識別

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

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

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

1.1、bmp圖片

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圖片

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圖片

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圖片

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圖片

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)的代碼:

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)換

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

ULONG_PTR m_gdiplusToken;
	
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup( &m_gdiplusToken, &gdiplusStartupInput, NULL );

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

Gdiplus::GdiplusShutdown( m_gdiplusToken );

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

// 根據(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++中圖片類型的識別與轉(zhuǎn)換詳解方法的詳細(xì)內(nèi)容,更多關(guān)于C++ 圖片類型轉(zhuǎn)換的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論