📄 bitmaploaddoc.cpp
字号:
// bitmaploadDoc.cpp : implementation of the CBitmaploadDoc class
//
#include "stdafx.h"
#include "bitmapload.h"
#include "bitmaploadDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBitmaploadDoc
IMPLEMENT_DYNCREATE(CBitmaploadDoc, CDocument)
BEGIN_MESSAGE_MAP(CBitmaploadDoc, CDocument)
//{{AFX_MSG_MAP(CBitmaploadDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBitmaploadDoc construction/destruction
CBitmaploadDoc::CBitmaploadDoc()
{
// TODO: add one-time construction code here
pBitmapPixels = NULL;
bm_width = -1;
bm_height = -1;
}
CBitmaploadDoc::~CBitmaploadDoc()
{
if (pBitmapPixels != NULL)
delete [] pBitmapPixels;
pBitmapPixels = NULL;
bm_width = -1;
bm_height = -1;
}
BOOL CBitmaploadDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
DeleteContents();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CBitmaploadDoc serialization
void CBitmaploadDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CBitmaploadDoc diagnostics
#ifdef _DEBUG
void CBitmaploadDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CBitmaploadDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CBitmaploadDoc commands
void CBitmaploadDoc::DeleteContents()
{
// TODO: Add your specialized code here and/or call the base class
if (pBitmapPixels != NULL)
delete [] pBitmapPixels;
pBitmapPixels = NULL;
bm_width = -1;
bm_height = -1;
CDocument::DeleteContents();
}
BOOL CBitmaploadDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
// if (!CDocument::OnOpenDocument(lpszPathName))
// return FALSE;
// TODO: Add your specialized creation code here
DeleteContents();
LoadBitmap24(lpszPathName);
if (pBitmapPixels == NULL)
TRACE0("It is NULL\n");
UpdateAllViews(NULL);
return TRUE;
}
BOOL CBitmaploadDoc::LoadBitmap24(const char * fn)
{
FILE * fp;
BYTE r, g, b;
BITMAPFILEHEADER bmFileHdr;
BITMAPINFO bmInfo;
int EndByte = 1;
BOOL bDone = FALSE;
WORD * temp;
WORD * t2;
// open file to read
fp = fopen(fn, "rb");
// read BITMAPFILEHEADER
fread((char *)&bmFileHdr, sizeof(BITMAPFILEHEADER), 1, fp);
// you read BITMAPINFOHEADER and RGBQUAD separately or together by
// read them into
// BITMAPINFO structure. When RGBQUAD is not empty (bitmap is 16 colors
// or 256 colors)
// You must read these two structures separately.
fread((char *)&bmInfo, sizeof(BITMAPINFO), 1, fp);
// check the bitmap info. If it is not 24 bit, and uncompressed,
//and the colors used and are important is
// not 0. return FALSE.
if (bmInfo.bmiHeader.biBitCount != 24 ||
bmInfo.bmiHeader.biCompression != 0 ||
(bmInfo.bmiHeader.biClrUsed != 0 && bmInfo.bmiHeader.biClrImportant != 0))
{
fclose(fp);
AfxMessageBox("This does nto appear to be a 24-bit uncompressed bitmap.");
return FALSE;
}
// get the width and height of the bitmap.
bm_width = (WORD)bmInfo.bmiHeader.biWidth;
bm_height = (WORD)bmInfo.bmiHeader.biHeight;
if (bm_width > 800 || bm_height > 600)
{
fclose(fp);
AfxMessageBox("This bitmap is way to big. Bitmap shouldn't be larger than 800X600.");
return FALSE;
}
// set new file pointer position at 54 from the begin of the
//file. (0 to 53 are used to store
// BITMAPFILEINFO, and BITMAPINFOHEADER.
fseek(fp, bmFileHdr.bfOffBits, SEEK_SET);
// start the mathematicall calculation for junk bytes.
if ((bmInfo.bmiHeader.biSizeImage - bm_width * bm_height * 3) == 0)
{
EndByte = 0; // only when there is no junk bytes
}
else
{
// find junk bytes.
EndByte = (bmFileHdr.bfSize - 54 - bm_width * bm_height * 3) / bm_height;
}
// create 2 empty arrays. One to store pixels from the file,
// the other is used to invert the array.
temp = new WORD[bm_width * bm_height];
pBitmapPixels = new WORD[bm_width * bm_height];
int count = bm_width * bm_height - 1;
// read the pixels.
while (!feof(fp))
{
// read scan line
for (int i = 0; i < bm_width; i++)
{
// since the bitmap is inverted stored, color byte Blue is always
// the first
if (!feof(fp))
{
fread((BYTE *)&b, sizeof(BYTE), 1, fp);
}
else
{
// this is true only when the file is totally corrupted.
bDone = TRUE;
break;
}
// Then we read the Green byte.
if (!feof(fp))
{
fread((BYTE *)&g, sizeof(BYTE), 1, fp);
}
else
{
// this is true only when the file is totally corrupted.
bDone = TRUE;
break;
}
// Finally the Red byte.
if (!feof(fp))
{
fread((BYTE *)&r, sizeof(BYTE), 1, fp);
}
else
{
// this is true only when the file is totally corrupted.
bDone = TRUE;
break;
}
// convert 24 bit color (3 bytes for R, G, B) into 16 bit,
//5-6-5 format WORD pixel.
temp[count] =
(WORD)((((WORD)r&0xf8)<<8)|(((WORD)g&0xfc)<<3)|(((WORD)b&0xf8)>>3));
count--; // counter operation for pixel index.
}
// When the for loop is done, one scan line is completed.
// This is where you skip the junk bytes. If you don't do
// that, the end result will be distorted image.
// Not good.
if (!bDone)
{
fseek(fp, EndByte, SEEK_CUR);
}
else
{
break;
}
}
// We do another inversion of the array.
count = 0;
for (int y = 0; y < bm_height; y++)
{
for (int x = bm_width - 1; x > -1; x--)
{
t2 = temp + y * bm_width + x;
pBitmapPixels[count] = *t2;
count++;
}
}
delete [] temp; // when done, the old array is discarded.
fclose(fp); // close file
return TRUE; // return success.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -