3,设备无关位图显示

文章详细描述了一个名为CDib的C++类,用于处理位图文件,包括文件操作(如加载和保存)、尺寸获取、颜色数量计算以及调色板创建。它展示了如何在CMy1_showbitmapView中使用这个类来显示位图并管理调色板。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

建立了一个类Dib

Dib.h
#pragma once
#include “afx.h”
class CDib :public CObject
{
public:
CDib();
~CDib();

char* GetFileName();
BOOL IsValid();
DWORD GetSize();
UINT GetWidth();
UINT GetHeight();
UINT GetNumberOfColors();
RGBQUAD* GetRGB();
BYTE* GetData();
BITMAPINFO* GetInfo();
WORD PaletteSize(LPBYTE lpDIB);
WORD DIBNumColors(LPBYTE lpDIB);
void SaveFile(const CString fileName);
void LoadFile(const char* dibFileName);

private:
RGBQUAD* m_pRGB;
BYTE* m_pData;
UINT m_numberOfColors;
BOOL m_valid;
BITMAPFILEHEADER bitmapFileHeader;
BITMAPINFOHEADER* m_pBitmapInfoHeader;
BITMAPINFO* m_pBitmapInfo;
BYTE* pDib;
DWORD size;
char m_fileName[256];

};
Dib.cpp
#include “stdafx.h”
#include “Dib.h”
#include <windowsx.h>

CDib::CDib()
{
size = 0;
}

CDib::~CDib()
{
GlobalFreePtr(m_pBitmapInfo);
}

char * CDib::GetFileName()
{
return m_fileName;
}

BOOL CDib::IsValid()
{
return m_valid;
}

DWORD CDib::GetSize()
{
if (m_pBitmapInfoHeader->biSizeImage != 0)
{
return m_pBitmapInfoHeader->biSizeImage;
}
DWORD height = (DWORD)GetHeight();
DWORD width = (DWORD)GetWidth();
return height * width;
}

UINT CDib::GetWidth()
{
return (UINT) m_pBitmapInfoHeader->biWidth;
}

UINT CDib::GetHeight()
{
return (UINT) m_pBitmapInfoHeader->biHeight;
}

UINT CDib::GetNumberOfColors()
{
int numberOfColors;
if ((m_pBitmapInfoHeader->biClrUsed == 0 ) && (m_pBitmapInfoHeader->biBitCount < 9))
{
switch (m_pBitmapInfoHeader->biBitCount)
{
case 1:
numberOfColors = 2;
break;

	case 4:
		numberOfColors = 16;
		break;

	case 8:
		numberOfColors = 256;
		break;
	}
}
else
{
	numberOfColors = (int)m_pBitmapInfoHeader->biClrUsed;
}
return numberOfColors;

}

RGBQUAD * CDib::GetRGB()
{
return m_pRGB;
}

BYTE * CDib::GetData()
{
return m_pData;
}

BITMAPINFO * CDib::GetInfo()
{
return m_pBitmapInfo;
}

WORD CDib::PaletteSize(LPBYTE lpDIB)
{
return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
}

WORD CDib::DIBNumColors(LPBYTE lpDIB)
{
WORD wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}

void CDib::SaveFile(const CString fileName)
{
//此函数只能保存经处理后宽度高度均没有改变大小的图像
strcpy(m_fileName, fileName);
CFile dibFile(m_fileName, CFile::modeCreate | CFile::modeWrite);
dibFile.Write((void*)& bitmapFileHeader, sizeof(BITMAPFILEHEADER));
dibFile.Write((void*)pDib, size);
dibFile.Close();
}

void CDib::LoadFile(const char * dibFileName)
{
strcpy(m_fileName, dibFileName);
CFile dibFile(m_fileName, CFile::modeRead);
dibFile.Read((void*)& bitmapFileHeader, sizeof(BITMAPFILEHEADER));
if (bitmapFileHeader.bfType != 0x4d42)
{
m_valid = FALSE;
AfxMessageBox(“This isn’t a bitmap file!”);
return;
}
DWORD fileLength = dibFile.GetLength();
size = fileLength - sizeof(BITMAPFILEHEADER);
pDib = (BYTE*)GlobalAllocPtr(GMEM_MOVEABLE, size);
dibFile.Read((void*)pDib, size);
dibFile.Close();
m_pBitmapInfo = (BITMAPINFO*)pDib;
m_pBitmapInfoHeader = (BITMAPINFOHEADER*)pDib;
m_pRGB = (RGBQUAD*)(pDib + m_pBitmapInfoHeader->biSize);
int m_numberOfColors = GetNumberOfColors();
if (m_pBitmapInfoHeader->biClrUsed == 0)
{
m_pBitmapInfoHeader->biClrUsed = m_numberOfColors;
}
DWORD colorTableSize = m_numberOfColors * sizeof(RGBQUAD);
m_pData = pDib + m_pBitmapInfoHeader->biSize + colorTableSize;
if (m_pRGB == (RGBQUAD*) m_pData)
{
m_pRGB = NULL;
}
m_pBitmapInfoHeader->biSizeImage = GetSize();
m_valid = TRUE;
}

调用

#include “Dib.h”

CPalette* _hPalette = NULL;
CDib _cdib;

//加载位图
CMy1_showbitmapView::CMy1_showbitmapView()
{
// TODO: add construction code here
_cdib.LoadFile (“D:/Test/DataProcess/result.bmp”);

}
//创建调色板

CPalette * CMy1_showbitmapView::CreateBitmapPalette(CDib * pBitMap)
{
struct
{
WORD version;
WORD numberOfEntries;
PALETTEENTRY aEntries[256];
}palette = { 0x300,256 };
LPRGBQUAD pRGBTable = pBitMap->GetRGB();
UINT numberOfColors = pBitMap->GetNumberOfColors();
for (size_t i = 0; i < numberOfColors; i++)
{
palette.aEntries[i].peRed = pRGBTable[i].rgbRed;
palette.aEntries[i].peGreen = pRGBTable[i].rgbGreen;
palette.aEntries[i].peBlue = pRGBTable[i].rgbBlue;
palette.aEntries[i].peFlags = 0;
}

CPalette * hPalette = new CPalette;

hPalette->CreatePalette((LPLOGPALETTE)& palette);
return hPalette;

}

//显示位图

void CMy1_showbitmapView::OnDraw(CDC* pDC)
{
CMy1_showbitmapDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: add draw code for native data here
//this->StretchBitMap(pDC);
//控制缩放比例
int m_scale = 1;
//CDib类指针对象
BYTE* pBitmapData = _cdib.GetData();
LPBITMAPINFO pBitmapInfo = _cdib.GetInfo();
int bitmapHeight = _cdib.GetHeight();
int bitmapWidth = _cdib.GetWidth();
int scaledWidth = (int)(bitmapWidth * m_scale);
int scaledHeight = (int)(bitmapHeight * m_scale);
bool bGetRGB = _cdib.GetRGB();
if (!bGetRGB)
{
	return;
}

CPalette* hPalette = CreateBitmapPalette(&_cdib);
//将已创建的调色板调用到设备上下文中
CPalette* hOldPalette = pDC->SelectPalette(hPalette, true);
//实现调色板
pDC->RealizePalette();
::StretchDIBits(pDC->GetSafeHdc(), 0, 0, scaledWidth, scaledHeight,
	0, 0,
	bitmapWidth, bitmapHeight,
	pBitmapData, pBitmapInfo,
	DIB_RGB_COLORS,
	SRCCOPY);
pDC->SelectPalette(hOldPalette, true);
::DeleteObject(hPalette);

}

运行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值