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

📄 mfcview.cpp

📁 jpeg压缩
💻 CPP
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////
//	mfcappView.cpp : implementation of the CMfcappView class
//
//
//	Note  : GIF code removed 9/23/97 pending Unisys licensing. 
//
//
//	This code copyright 1997 Chris Losinger, unless otherwise noted
//
//	CHRISDL@PAGESZ.NET
//
//	PLEASE!!! Tell me of any bugs you find!!!
//
//	This code contains examples of using my JpegFile class, how to
//	read and write 1,4,8 and 24-bit BMPs and how to read and write
//	GIF87a files.
//
//	I find that this code works well for my purposes. Feel free to 
//	use it in your own code, but I can't assume any responsibility
//	if this code fails to do what you expect.
//
//	If you find any problems with this code, feel free to contact 
//	me for help.
//
//	Note : parts of the GIF specification are copyrighted. I am not 
//	authorized to grant license to use the GIF code (or to even use it
//	myself). If you worry about such things, I suggest you find out
//	how to get permission to use the GIF algorithms in your code. 
//	The GIF algorithms are patented by the Unisys corporation.
//
//	24-bit to 8-bit color quantization code modified from Dennis Lee's
//	DL1Quant. His source is available at ...
//


#include "stdafx.h"
#include "mfcapp.h"

#include "mfcDoc.h"
#include "mfcView.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "JpegFile.h"
#include "GIFFile.h"

#include "BMPDlg.h"
#include "BMPFile.h"

#include "QuantDlg.h"
#include "dl1quant.h"

/////////////////////////////////////////////////////////////////////////////
// CMfcappView

IMPLEMENT_DYNCREATE(CMfcappView, CView)

BEGIN_MESSAGE_MAP(CMfcappView, CView)
	//{{AFX_MSG_MAP(CMfcappView)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
	ON_COMMAND(ID_FILE_SAVEGRAYAS, OnFileSavegrayJPGas)
	ON_COMMAND(ID_FILE_GETDIMENSIONSJPG, OnFileGetdimensionsjpg)
	ON_COMMAND(ID_FILE_SAVECOLORMAPPEDBMP, OnFileSavecolormappedbmp)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMfcappView construction/destruction

CMfcappView::CMfcappView()
{
							// we keep a single global image in memory

	m_buf=NULL;				// where we keep our image data
	m_width=0;				// image dimensions
	m_height=0;
	m_widthDW=0;
}

CMfcappView::~CMfcappView()
{
	// clean up
	if (m_buf!=NULL) {
		delete [] m_buf;
		m_buf=NULL;
	}
}

BOOL CMfcappView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMfcappView drawing

void CMfcappView::OnDraw(CDC* pDC)
{
	CMfcappDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// draw the BMP we have in memory
	DrawBMP();
}


////////////////////////////////////////////////////////////////////////////
//
//	shoot the global image to the screen

void CMfcappView::DrawBMP()
{
	// if we don't have an image, get out of here
	if (m_buf==NULL) return;

	CDC *theDC = GetDC();

	if (theDC!=NULL) {

		CRect clientRect;
		GetClientRect(clientRect);

		// Center It
		UINT left = (clientRect.Width() - m_width) / 2;
		UINT top = (clientRect.Height() - m_height) / 2;

		// a 24-bit DIB is DWORD-aligned, vertically flipped and 
		// has Red and Blue bytes swapped. we already did the 
		// RGB->BGR and the flip when we read the images, now do
		// the DWORD-align

		BYTE *tmp;
		// DWORD-align for display
		tmp = JpegFile::MakeDwordAlignedBuf(m_buf,
										 m_width,
										 m_height,
										 &m_widthDW);

		// set up a DIB 
		BITMAPINFOHEADER bmiHeader;
		bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmiHeader.biWidth = m_width;
		bmiHeader.biHeight = m_height;
		bmiHeader.biPlanes = 1;
		bmiHeader.biBitCount = 24;
		bmiHeader.biCompression = BI_RGB;
		bmiHeader.biSizeImage = 0;
		bmiHeader.biXPelsPerMeter = 0;
		bmiHeader.biYPelsPerMeter = 0;
		bmiHeader.biClrUsed = 0;
		bmiHeader.biClrImportant = 0;


		// now blast it to the CDC passed in.
		// lines returns the number of lines actually displayed
		int lines = StretchDIBits(theDC->m_hDC,
									left, top,
									bmiHeader.biWidth,
									bmiHeader.biHeight,
									0,0,
									bmiHeader.biWidth,
									bmiHeader.biHeight,
									tmp,
									(LPBITMAPINFO)&bmiHeader,
									DIB_RGB_COLORS,
									SRCCOPY);

		delete [] tmp;

		CString info;
		info.Format("(%d x %d)", m_width, m_height);
		theDC->SetBkMode(TRANSPARENT);
		theDC->SetTextColor(RGB(0,0,0));
		theDC->TextOut(10,5, info);

		ReleaseDC(theDC);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CMfcappView printing

BOOL CMfcappView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CMfcappView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CMfcappView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CMfcappView diagnostics

#ifdef _DEBUG
void CMfcappView::AssertValid() const
{
	CView::AssertValid();
}

void CMfcappView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMfcappDoc* CMfcappView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMfcappDoc)));
	return (CMfcappDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMfcappView message handlers

void CMfcappView::OnFileOpen() 
{
	CString fileName;
	CString filt="JPG File (*.JPG)|*.JPG|BMP (*.BMP)|*.BMP|GIF (*.GIF)|*.GIF|All files (*.*)|*.*||";
    
    // OPENFILENAME - so i can get to its Help page easily
	CFileDialog fileDlg(TRUE,"*.JPG","*.JPG",NULL,filt,this);

	fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
	fileDlg.m_ofn.lpstrTitle="File to load";

	if (fileDlg.DoModal()==IDOK) {

		AfxGetApp()->DoWaitCursor(1);

		fileName=fileDlg.GetPathName();
		CString ext=fileName.Right(4);

		if (!ext.CompareNoCase(".JPG"))
			LoadJPG(fileName);

		if (!ext.CompareNoCase(".GIF"))
			LoadGIF(fileName);

		if (!ext.CompareNoCase(".BMP"))
			LoadBMP(fileName);
		
		AfxGetApp()->DoWaitCursor(-1);

	}            

	// force a redraw
	Invalidate(TRUE);

}



////////////////////////////////////////////////////////////////////////////
//	Save As dialog handler
//

void CMfcappView::OnFileSaveAs() 
{
	CString fileName;
	CString filt="JPG File (*.JPG)|*.JPG|GIF File (*.GIF)|*.GIF|BMP (*.BMP)|*.BMP|All files (*.*)|*.*||";
    
    // OPENFILENAME - so i can get to its Help page easily
	CFileDialog fileDlg(FALSE,"*.JPG","*.JPG",NULL,filt,this);

	fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
	fileDlg.m_ofn.lpstrTitle="File to save as";

	if (fileDlg.DoModal()==IDOK) {
		
		AfxGetApp()->DoWaitCursor(1);

		fileName=fileDlg.GetPathName();

		CString ext=fileName.Right(4);

		if (!ext.CompareNoCase(".JPG"))
			SaveJPG(fileName,TRUE);

		if (!ext.CompareNoCase(".BMP"))
			SaveBMP24(fileName);

		if (!ext.CompareNoCase(".GIF"))
			SaveGIF(fileName);

		AfxGetApp()->DoWaitCursor(-1);
	}            
}


////////////////////////////////////////////////////////////////////////////
//	read a JPG to our global buffer
//

void CMfcappView::LoadJPG(CString fileName)
{

	// m_buf is the global buffer
	if (m_buf!=NULL) {
		delete [] m_buf;
		m_buf=NULL;
	}

	// read to buffer tmp
	m_buf=JpegFile::JpegFileToRGB(fileName, &m_width, &m_height);

	//////////////////////
	// set up for display

	// do this before DWORD-alignment!!!
	// this works on packed (not DWORD-aligned) buffers
	// swap red and blue for display
	JpegFile::BGRFromRGB(m_buf, m_width, m_height);

	// vertical flip for display
	JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);

}

////////////////////////////////////////////////////////////////////////////
//	read a BMP to our global buffer
//

void CMfcappView::LoadBMP(CString fileName)
{
	if (m_buf!=NULL) {
		delete [] m_buf;
	}

	BMPFile theBmpFile;

	m_buf=theBmpFile.LoadBMP(fileName, &m_width, &m_height);

	if ((m_buf==NULL) || (theBmpFile.m_errorText!="OK")) {
		AfxMessageBox(theBmpFile.m_errorText);
		m_buf==NULL;
		return;
	}

	//////////////////////
	// set up for display

	// do this before DWORD-alignment!!!
	// this works on packed (not DWORD-aligned) buffers
	// swap red and blue for display
	JpegFile::BGRFromRGB(m_buf, m_width, m_height);

	// vertical flip for display
	JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);
}



////////////////////////////////////////////////////////////////////////////
//
//	read a GIF to our global buffer

void CMfcappView::LoadGIF(CString filename)
{

	if (m_buf!=NULL) {
		delete [] m_buf;
		m_buf=NULL;
	}

	GIFFile theGifThing;
	
	// read the GIF to a packed buffer of RGB bytes
	m_buf=theGifThing.GIFReadFileToRGB(filename, 
						&m_width, 
						&m_height);
	
	if (m_buf==NULL) {
		AfxMessageBox(theGifThing.m_GIFErrorText);
		return;
	}

	//////////////////////
	// set up for display

	// do this before DWORD-alignment!!!
	// swap red and blue for display
	JpegFile::BGRFromRGB(m_buf, m_width, m_height);

	// flip for display
	JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);
}


////////////////////////////////////////////////////////////////////////////
//	save functions are generally more complex than reading functions.
//	there are many more decisions to be made for writing than for reading.


////////////////////////////////////////////////////////////////////////////
//	save a JPG

void CMfcappView::SaveJPG(CString fileName, BOOL color)
{
	// note, because i'm lazy, most image data in this app
	// is handled as 24-bit images. this makes the DIB
	// conversion easier. 1,4,8, 15/16 and 32 bit DIBs are
	// significantly more difficult to handle.

	if (m_buf==NULL) {
		AfxMessageBox("No Image!");
		return;
	}

	// we vertical flip for display. undo that.
	JpegFile::VertFlipBuf(m_buf, m_width * 3, m_height);

	// we swap red and blue for display, undo that.
	JpegFile::BGRFromRGB(m_buf, m_width, m_height);


	// save RGB packed buffer to JPG
	BOOL ok=JpegFile::RGBToJpegFile(fileName, 
									m_buf,
									m_width,
									m_height,
									color, 
									75);			// quality value 1-100.
	if (!ok) {
		AfxMessageBox("Write Error");
	} else {
		// load what we just saved
		LoadJPG(fileName);

⌨️ 快捷键说明

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