📄 bmpview.cpp
字号:
// BMPView.cpp : implementation of the CBMPView class
//
#include "stdafx.h"
#include "BMP.h"
#include "BMPDoc.h"
#include "BMPView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBMPView
IMPLEMENT_DYNCREATE(CBMPView, CView)
BEGIN_MESSAGE_MAP(CBMPView, CView)
//{{AFX_MSG_MAP(CBMPView)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CBMPView construction/destruction
CBMPView::CBMPView()
{
// TODO: add construction code here
}
CBMPView::~CBMPView()
{
}
BOOL CBMPView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CBMPView drawing
void CBMPView::OnDraw(CDC* pDC)
{
CBMPDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(filename=="")
{
return;
}
FILE *fp=fopen(filename,"r");
BITMAPFILEHEADER fileheader;
BITMAPINFO info;
fread(&fileheader,sizeof(fileheader),1,fp);
if(fileheader.bfType!=0x4D42)
{
pDC->TextOut(100,200,"无位图文件 请选择位图文件");
fclose(fp);
return ;
}
fread(&info.bmiHeader, sizeof(BITMAPINFOHEADER), 1, fp);
long width=info.bmiHeader.biWidth;
long height=info.bmiHeader.biHeight;
UCHAR *buffer=new UCHAR[info.bmiHeader.biSizeImage];
fseek(fp,fileheader.bfOffBits,0);
fread(buffer,info.bmiHeader.biSizeImage,1,fp);
// 单色图的解析
if(info.bmiHeader.biBitCount==1)
{
int n=0;
int color[500][500];
if(height>0)
{
//height>0 表示图片颠倒
for(int i=0; i<height; i++)
for(int j=0; j<width; j=j+8)
{
int k=7;
while(k>=0)
{
color[i][k+j]=buffer[n]%2;
buffer[n]=buffer[n]/2;
k--;
}
n++;
}
for(i=0; i<height; i++)
for(int j=0; j<width; j++)
{
if(color[i][j] == 0)
pDC->SetPixel(j,height-i,RGB(0,0,0));
if(color[i][j] == 1)
pDC->SetPixel(j,height-i,RGB(255,255,255));
}
}
else
{
for(int i=0; i<0-height; i++)
for(int j=0; j<width; j=j+8)
{
int k=7;
while(k>=0)
{
color[i][k+j]=buffer[n]%2;
buffer[n]=buffer[n]/2;
k--;
}
n++;
}
for(i=0; i<0-height; i++)
for(int j=0; j<width; j++)
{
if(color[i][j] == 0)
pDC->SetPixel(j,i,RGB(0,0,0));
if(color[i][j] == 1)
pDC->SetPixel(j,i,RGB(255,255,255));
}
}
}
// 16色图的解析
if(info.bmiHeader.biBitCount==4)
{
int pitch;
if(width%8==0)
pitch=width;
else
pitch=width+8-width%8;
RGBQUAD quad[16];
fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*16,0);
fread(quad,sizeof(RGBQUAD)*16,1,fp);
if(height>0)
{
//height>0 表示图片颠倒
for(int i=0; i<height; i++)
for(int j=0; j<width; j++)
{
int index;
if(j%2==0)
index = buffer[(i*pitch+j)/2]/16;
if(j%2==1)
index = buffer[(i*pitch+j)/2]%16;
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,height-i,RGB(r,g,b));
}
}
else
{
for(int i=0; i<0-height; i++)
for(int j=0; j<width; j++)
{
int index;
if(j%2==0)
index = buffer[(i*pitch+j)/2]/16;
if(j%2==1)
index = buffer[(i*pitch+j)/2]%16;
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,i,RGB(r,g,b));
}
}
}
// 32色图的解析
if(info.bmiHeader.biBitCount==8)
{
int pitch;
if(width%4==0)
{
pitch=width;
}
else
{
pitch=width+4-width%4;
}
RGBQUAD quad[256];
fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*256,0);
fread(quad,sizeof(RGBQUAD)*256,1,fp);
if(height>0)
{
//height>0 表示图片颠倒
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
int index=buffer[i*pitch+j];
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,height-i,RGB(r,g,b));
}
}
}
else
{
for(int i=0;i<0-height;i++)
{
for(int j=0;j<width;j++)
{
int index=buffer[i*pitch+j];
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,i,RGB(r,g,b));
}
}
}
}
// 256色图解析
if(info.bmiHeader.biBitCount==16)
{
int pitch=width+width%2;
if(height>0)
{
//height>0 表示图片颠倒
if(info.bmiHeader.biCompression==BI_RGB)
{
//该模式只有555
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
// 555 格式
UCHAR b=buffer[(i*pitch+j)*2]&0x1F;
UCHAR g=(((buffer[(i*pitch+j)*2+1]<<6)&0xFF)>>3)+(buffer[(i*pitch+j)*2]>>5);
UCHAR r=(buffer[(i*pitch+j)*2+1]<<1)>>3;
pDC->SetPixel(j,height-i,RGB((r*0xFF)/0x1F,(g*0xFF)/0x1F,(b*0xFF)/0x1F));
}
}
}
if(info.bmiHeader.biCompression==BI_BITFIELDS)
{
//该模式在bitmapinfoheader之后存在RGB掩码 每个掩码1 DWORD
fseek(fp,fileheader.bfOffBits-sizeof(DWORD )*3,0);
DWORD rMask;
fread(&rMask,sizeof(DWORD ),1,fp);
if(rMask==0x7C00)
{
// 5 5 5 格式
MessageBeep(0);
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*pitch+j)*2]&0x1F;
UCHAR g=(((buffer[(i*pitch+j)*2+1]<<6)&0xFF)>>3)+(buffer[(i*pitch+j)*2]>>5);
UCHAR r=(buffer[(i*pitch+j)*2+1]<<1)>>3;
pDC->SetPixel(j,height-i,RGB((r*0xFF)/0x1F,(g*0xFF)/0x1F,(b*0xFF)/0x1F));
}
}
}
if(rMask==0xF800)
{
//5 6 5 格式
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*pitch+j)*2]&0x1F;
UCHAR g=(((buffer[(i*pitch+j)*2+1]<<5)&0xFF)>>2)+(buffer[(i*pitch+j)*2]>>5);
UCHAR r=buffer[(i*pitch+j)*2+1]>>3;
pDC->SetPixel(j,height-i,RGB(r*0xFF/0x1F,g*0xFF/0x3F,b*0xFF/0x1F));
}
}
}
}
}
else
{
if(info.bmiHeader.biCompression==BI_RGB)
{
//该模式只有555
for(int i=0;i<0-height;i++){
for(int j=0;j<width;j++){
//5 5 5 格式
UCHAR b=buffer[(i*pitch+j)*2]&0x1F;
UCHAR g=(((buffer[(i*pitch+j)*2+1]<<6)&0xFF)>>3)+(buffer[(i*pitch+j)*2]>>5);
UCHAR r=(buffer[(i*pitch+j)*2+1]<<1)>>3;
pDC->SetPixel(j,i,RGB((r*0xFF)/0x1F,(g*0xFF)/0x1F,(b*0xFF)/0x1F));
}
}
}
if(info.bmiHeader.biCompression==BI_BITFIELDS)
{
//该模式在bitmapinfoheader之后存在RGB掩码 每个掩码1 DWORD
fseek(fp,fileheader.bfOffBits-sizeof(DWORD )*3,0);
DWORD rMask;
fread(&rMask,sizeof(DWORD ),1,fp);
if(rMask==0x7C00)
{
// 5 5 5 格式
MessageBeep(0);
for(int i=0;i<0-height;i++)
{
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*pitch+j)*2]&0x1F;
UCHAR g=(((buffer[(i*pitch+j)*2+1]<<6)&0xFF)>>3)+(buffer[(i*pitch+j)*2]>>5);
UCHAR r=(buffer[(i*pitch+j)*2+1]<<1)>>3;
pDC->SetPixel(j,i,RGB((r*0xFF)/0x1F,(g*0xFF)/0x1F,(b*0xFF)/0x1F));
}
}
}
if(rMask==0xF800)
{
//565 格式
for(int i=0;i<0-height;i++)
{
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*pitch+j)*2]&0x1F;
UCHAR g=(((buffer[(i*pitch+j)*2+1]<<5)&0xFF)>>2)+(buffer[(i*pitch+j)*2]>>5);
UCHAR r=buffer[(i*pitch+j)*2+1]>>3;
pDC->SetPixel(j,i,RGB(r*0xFF/0x1F,g*0xFF/0x3F,b*0xFF/0x1F));
}
}
}
}
}
}
// 24位图解析
if(info.bmiHeader.biBitCount==24)
{
int pitch=width%4;
// bgr
if(height>0){
//height>0 表示图片颠倒
for(int i=0;i<height;i++)
{
int realPitch=i*pitch;
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*width+j)*3+realPitch];
UCHAR g=buffer[(i*width+j)*3+1+realPitch];
UCHAR r=buffer[(i*width+j)*3+2+realPitch];
pDC->SetPixel(j,height-i,RGB(r,g,b));
}
}
}
else
{
for(int i=0;i<0-height;i++)
{
int realPitch=i*pitch;
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*width+j)*3+realPitch];
UCHAR g=buffer[(i*width+j)*3+1+realPitch];
UCHAR r=buffer[(i*width+j)*3+2+realPitch];
pDC->SetPixel(j,i,RGB(r,g,b));
}
}
}
}
// 32位图进行解析
if(info.bmiHeader.biBitCount==32)
{
// bgra
if(height>0)
{
//height>0 表示图片颠倒
for(int i=0;i<0-height;i++)
{
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*width+j)*4];
UCHAR g=buffer[(i*width+j)*4+1];
UCHAR r=buffer[(i*width+j)*4+2];
pDC->SetPixel(j,height-i,RGB(r,g,b));
}
}
}
else
{
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*width+j)*4];
UCHAR g=buffer[(i*width+j)*4+1];
UCHAR r=buffer[(i*width+j)*4+2];
pDC->SetPixel(j,i,RGB(r,g,b));
}
}
}
}
delete buffer;
fclose(fp);
}
/////////////////////////////////////////////////////////////////////////////
// CBMPView printing
BOOL CBMPView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CBMPView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CBMPView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CBMPView diagnostics
#ifdef _DEBUG
void CBMPView::AssertValid() const
{
CView::AssertValid();
}
void CBMPView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CBMPDoc* CBMPView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBMPDoc)));
return (CBMPDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CBMPView message handlers
void CBMPView::OnFileOpen()
{
// TODO: Add your command handler code here
CString filter;
filter = "BMP文件(*.bmp)|*.bmp||";
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);
if(dlg.DoModal() == IDOK)
{
filename = dlg.GetPathName();
CBMPView::OnInitialUpdate();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -