📄 mfcappview.cpp
字号:
////////////////////////////////////////////////////////////////////////////
// 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
//
// 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.
//
// 24-bit to 8-bit color quantization code modified from Dennis Lee's
// DL1Quant. His source is available at ...
//
// MfcAppView.cpp : implementation of the CMfcAppView class
//
#include "stdafx.h"
#include "MfcApp.h"
#include <math.h>
#include "MfcAppDoc.h"
#include "MfcAppView.h"
#include "JpegFile.h"
#include "BMPDlg.h"
#include "BMPFile.h"
#include "QuantDlg.h"
#include "dl1quant.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// 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_SAVECOLORMAPPEDBMP, OnFileSavecolormappedbmp)
ON_COMMAND(ID_FILE_SAVEGRAYAS, OnFileSavegrayas)
ON_COMMAND(ID_FILE_GETDIMENSIONSJPG, OnFileGetdimensionsjpg)
//}}AFX_MSG_MAP
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();
}
/////////////////////////////////////////////////////////////////////////////
// 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|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(".BMP"))
LoadBMP(fileName);
AfxGetApp()->DoWaitCursor(-1);
}
// force a redraw
Invalidate(TRUE);
}
void CMfcAppView::OnFileSaveAs()
{
CString fileName;
CString filt="JPG File (*.JPG)|*.JPG|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);
AfxGetApp()->DoWaitCursor(-1);
}
}
void CMfcAppView::OnFileSavecolormappedbmp()
{
if (m_buf==NULL) {
AfxMessageBox("No Image!");
return;
}
////////////////////////////////////////////////////////////////////////
// get the filename
CString fileName;
CString filt="BMP (*.BMP)|*.BMP|All files (*.*)|*.*||";
// OPENFILENAME - so i can get to its Help page easily
CFileDialog fileDlg(FALSE,"*.BMP","*.BMP",NULL,filt,this);
fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST;
fileDlg.m_ofn.lpstrTitle="File to save as";
if (fileDlg.DoModal()!=IDOK)
return;
fileName=fileDlg.GetPathName();
////////////////////////////////////////////////////////////////////////
// fetch bits per pixel
CBMPDlg theDlg;
if (theDlg.DoModal()!=IDOK)
return;
int bitsperpixel = theDlg.m_bits;
AfxGetApp()->DoWaitCursor(1);
////////////////////////////////////////////////////////////////////////
// prepare for color-mapping
// our palette
RGBQUAD colormap[256];
// num colors
int colors = (int)pow(2,bitsperpixel);
BYTE *colorMappedBuffer = NULL;
// if we can use the color quantizer, we will
if (bitsperpixel==8) {
CQuantDlg theDlg;
if (theDlg.DoModal()!=IDOK) {
return;
}
// color or grayscale?
if (theDlg.m_color) {
// color !
// allocate a buffer to colormap to
colorMappedBuffer = (BYTE *) new BYTE[m_width* m_height];
if (colorMappedBuffer==NULL) {
AfxMessageBox("Memory Error in OnSaveColormappedbmp!");
return;
}
BYTE tmpPal[3][256];
// colormap it
// generates an 8-bit color-mapped image into colorMappedBuffer
if (!dl1quant(m_buf,
colorMappedBuffer, // buffers
m_width,
m_height,
theDlg.m_quantColors,
TRUE,
tmpPal)) { // palette
AfxMessageBox("Quantization error");
delete [] colorMappedBuffer;
return;
}
// copy our palette
for (UINT col=0;col<256;col++) {
if (col>theDlg.m_quantColors) {
colormap[col].rgbRed=0;
colormap[col].rgbBlue=0;
colormap[col].rgbGreen=0;
} else {
colormap[col].rgbRed=tmpPal[0][col];
colormap[col].rgbGreen=tmpPal[1][col];
colormap[col].rgbBlue=tmpPal[2][col];
}
}
} else {
// gray :(
// convert to 8-bit colormapped grayscale
colorMappedBuffer = MakeColormappedGrayscale(m_buf, // RGB
(UINT)m_width, // pixels
(UINT)m_height,
(UINT)m_width * 3, // bytes
(UINT)colors, // colors
colormap); // palette
}
} else { // bitsperpixel!=8
// based on bitsperpixel, create a colormapped image
colorMappedBuffer = MakeColormappedGrayscale(m_buf,
(UINT)m_width,
(UINT)m_height,
(UINT)m_width * 3,
(UINT)colors,
colormap);
}
////////////////////////////////////////////////////////////////////////
// finally, save the thing
if (colorMappedBuffer!=NULL) {
// write the BMP using our colormapped image (one byte per pixel, packed),
// number of bits, number of total colors and a colormap
// pixel values must be in the range [0...colors-1]
BMPFile theBmpFile;
theBmpFile.SaveBMP(fileName, // path
colorMappedBuffer, // image
m_width, // pixels
m_height,
bitsperpixel, // 1,4,8
colors, // num colors
colormap); // palette
if (theBmpFile.m_errorText!="OK") {
AfxMessageBox(theBmpFile.m_errorText, MB_ICONSTOP);
}else {
// load what we just saved
LoadBMP(fileName);
Invalidate(TRUE);
}
// toss our buffer...
delete [] colorMappedBuffer;
} else {
AfxMessageBox("Failed to allocate space for RGB buffer");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -