⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picoperate.cpp

📁 本程序是用VC++6.0开发的BMP转JPEG格式的图片压缩源程序
💻 CPP
字号:


#include "stdafx.h"
#include "PicOperate.h"



#include "CompressEncode.h"





///////////////////////////////////////////////////////////////////////////////
//构造函数
PictureOperate::PictureOperate()
{

	
	m_pDib = NULL;

	
}
//析构函数
PictureOperate::~PictureOperate()
{


	if( m_pDib != NULL )
		delete [] m_pDib;

}

//加载位图
BOOL PictureOperate::Load( const char *pszFilename )
{

	CFile cf;

	// Attempt to open the Dib file for reading.
	if( !cf.Open( pszFilename, CFile::modeRead ) )
		return( FALSE );

	// Get the size of the file and store
	// in a local variable. Subtract the
	// size of the BITMAPFILEHEADER structure
	// since we won't keep that in memory.
	DWORD dwDibSize;
	dwDibSize =
		cf.GetLength() - sizeof( BITMAPFILEHEADER );

	// Attempt to allocate the Dib memory.
	unsigned char *pDib;
	pDib = new unsigned char [dwDibSize];
	if( pDib == NULL )
		return( FALSE );

	BITMAPFILEHEADER BFH;

	// Read in the Dib header and data.
	try{

		// Did we read in the entire BITMAPFILEHEADER?
		if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
			!= sizeof( BITMAPFILEHEADER ) ||

			// Is the type 'MB'?
			BFH.bfType != 'MB' ||

			// Did we read in the remaining data?
			cf.Read( pDib, dwDibSize ) != dwDibSize ){

			// Delete the memory if we had any
			// errors and return FALSE.
			delete [] pDib;
			return( FALSE );
			}
		}

	// If we catch an exception, delete the
	// exception, the temporary Dib memory,
	// and return FALSE.
	catch( CFileException *e ){
		e->Delete();
		delete [] pDib;
		return( FALSE );
		}
	
	// If we got to this point, the Dib has been
	// loaded. If a Dib was already loaded into
	// this class, we must now delete it.
	if( m_pDib != NULL )
		delete m_pDib;

	// Store the local Dib data pointer and
	// Dib size variables in the class member
	// variables.
	m_pDib = pDib;
	m_dwDibSize = dwDibSize;

	// Pointer our BITMAPINFOHEADER and RGBQUAD
	// variables to the correct place in the Dib data.
	m_pBIH = (BITMAPINFOHEADER *) m_pDib;
	m_pPalette =
		(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];

	//	get image width and height
	m_width = m_pBIH->biWidth;
	m_height = m_pBIH->biHeight;

	// Calculate the number of palette entries.
	m_nPaletteEntries = 1 << m_pBIH->biBitCount;
	if( m_pBIH->biBitCount > 8 )
		m_nPaletteEntries = 0;
	else if( m_pBIH->biClrUsed != 0 )
		m_nPaletteEntries = m_pBIH->biClrUsed;

	// Point m_pDibBits to the actual Dib bits data.
	m_pDibBits =
		&m_pDib[sizeof(BITMAPINFOHEADER)+
			m_nPaletteEntries*sizeof(RGBQUAD)];

	// If we have a valid palette, delete it.
	if( m_Palette.GetSafeHandle() != NULL )
		m_Palette.DeleteObject();

	// If there are palette entries, we'll need
	// to create a LOGPALETTE then create the
	// CPalette palette.
	if( m_nPaletteEntries != 0 ){

		// Allocate the LOGPALETTE structure.
		LOGPALETTE *pLogPal = (LOGPALETTE *) new char
				[sizeof(LOGPALETTE)+
				m_nPaletteEntries*sizeof(PALETTEENTRY)];

		if( pLogPal != NULL ){

			// Set the LOGPALETTE to version 0x300
			// and store the number of palette
			// entries.
			pLogPal->palVersion = 0x300;
			pLogPal->palNumEntries = m_nPaletteEntries;

			// Store the RGB values into each
			// PALETTEENTRY element.
			for( int i=0; i<m_nPaletteEntries; i++ ){
				pLogPal->palPalEntry[i].peRed =
					m_pPalette[i].rgbRed;
				pLogPal->palPalEntry[i].peGreen =
					m_pPalette[i].rgbGreen;
				pLogPal->palPalEntry[i].peBlue =
					m_pPalette[i].rgbBlue;
				}

			// Create the CPalette object and
			// delete the LOGPALETTE memory.
			m_Palette.CreatePalette( pLogPal );
			delete [] pLogPal;
			}
		}
	
	return( TRUE );

}



///////////////////////////////////////////////////////////////////////////////
//对位图进行基于DCT的压缩编码,并且保存为JPG文件
void PictureOperate::picCompressEncode(CString filename, BOOL color, int quality)
{

	//压缩后的字节数
	int nOutputBytes = 0;

	unsigned char *pJpg;
	pJpg = new unsigned char [m_dwDibSize];
	
	LARGE_INTEGER iLarge;
	QueryPerformanceFrequency( &iLarge );	
	double dbFreq = (double) iLarge.QuadPart;
	
	//获得起始时间
	QueryPerformanceCounter( &iLarge ); 
	double dbBegin = (double) iLarge.QuadPart;

	/////////////////////////////////////////////////////

	
	//quality为压缩质量
	CompressEncode encoder( quality );

	encoder.CompressImage( m_pDibBits, pJpg, 
		m_pBIH->biWidth, m_pBIH->biHeight, nOutputBytes );

	//////////////////////////////////////////////////////

	//获得压缩结束后时间
	QueryPerformanceCounter( &iLarge ); 
	double dbEnd = (double) iLarge.QuadPart;

	int nms = (int) (( dbEnd - dbBegin ) * 1000.0 / dbFreq );	
		
	float ratio = (float) m_dwDibSize / nOutputBytes;
	CString str;
	//输出压缩后信息
	str.Format( "压缩后字节数 = %d, 压缩比 = %f, 耗时 = %d ", 
					nOutputBytes, ratio, nms );
	AfxMessageBox( str );
	
	//保存JPG文件
	CFile cf;
	if( !cf.Open( filename, CFile::modeCreate | CFile::modeWrite ) )
	{
		AfxMessageBox("Can not create jpg file!");
		return;
	}

	cf.Write( pJpg, nOutputBytes );

	delete []pJpg;
}
///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -