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

C++中圖片類型的識別與轉換詳解方法

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

1、圖片類型的識別

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

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

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

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ù)讀取內容

上面是使用fopen和fread讀取文件中的內容的,下面給出調用CreateFile和ReadFile API函數(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、圖片之間的相互轉換

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

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

在退出程序時,要關閉GDI+庫:

Gdiplus::GdiplusShutdown( m_gdiplusToken );

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

// 根據(jù)目標文件的后綴確定要轉換成的目標文件類型
BOOL32 SaveImgFileToAnotherType( const CString& strSrcFile, const CString& strDstFile )
{
	// 使用CImage實現(xiàn)不同格式圖片文件的轉換
	if ( strDstFile.IsEmpty() )
	{
		return FALSE;
	}
 
	CImage img;
	HRESULT hResult = img.Load( strSrcFile ); // 加載源圖片文件
	if ( hResult != S_OK )
	{
		return FALSE;
	}
 
	GUID guidFileType = Gdiplus::ImageFormatPNG; // 默認保存為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 ); // 保存為目標文件
	if ( hResult != S_OK )
	{
		return FALSE;
	}
 
	return TRUE;
}

以上就是C++中圖片類型的識別與轉換詳解方法的詳細內容,更多關于C++ 圖片類型轉換的資料請關注腳本之家其它相關文章!

相關文章

最新評論