【VC开源代码栏目提醒】:网学会员VC开源代码为您提供DibSection.cpp参考,解决您在DibSection.cpp学习中工作中的难题,参考学习。
//
// DIB Section
//
// Copyright (c) 2000 Chihiro.SAKAMOTO (HyperWorks)
//
#include "StdAfx.h"
#include "DibSection.h"
#ifdef USEPNG
#include "PngFile.h"
#endif
//
//
//
CDibSection::CDibSection()
: hBitmap(0), Bits(0)
{
}
CDibSection::CDibSection(const CDibSection &dib)
: hBitmap(0), Bits(0)
{
if (Create(dib.Width(), dib.Height(), dib.Depth()))
Copy(dib);
}
//
//
//
CDibSection::~CDibSection()
{
Destroy();
}
//
//
//
BOOL CDibSection::Create(int width, int height, int depth)
{
Destroy();
bytes_per_line = ScanBytes(width, depth);
bytes_per_pixel = PixelBytes(depth);
Header.Info.biSize = sizeof(BITMAPINFOHEADER);
Header.Info.biWidth = width;
Header.Info.biHeight = height;
Header.Info.biBitCount = depth;
Header.Info.biPlanes = 1;
Header.Info.biXPelsPerMeter = 0;
Header.Info.biYPelsPerMeter = 0;
Header.Info.biClrUsed = 0;
Header.Info.biClrImportant = 0;
Header.Info.biCompression = depth == 24? BI_RGB: BI_BITFIELDS;
Header.Info.biSizeImage = bytes_per_line * height;
switch (depth) {
case 16:
Header.BitField[0] = 0x7c00;
Header.BitField[1] = 0x03e0;
Header.BitField[2] = 0x001f;
break;
case 32:
Header.BitField[0] = 0xff0000;
Header.BitField[1] = 0x00ff00;
Header.BitField[2] = 0x0000ff;
break;
default:
Header.BitField[0] = 0;
Header.BitField[1] = 0;
Header.BitField[2] = 0;
break;
}
HDC dc = ::GetDC(0);
hBitmap = CreateDIBSection(dc, (BITMAPINFO *)&Header, DIB_RGB_COLORS, &Bits, NULL, 0);
::ReleaseDC(0, dc);
return hBitmap != 0;
}
//
//
void CDibSection::Destroy()
{
if (hBitmap) {
GdiFlush();
::DeleteObject(hBitmap);
hBitmap = 0;
}
}
//
//
BOOL CDibSection::LoadBmp(const char *path)
{
Destroy();
hBitmap = (HBITMAP)::LoadImage(::GetModuleHandle(0), path, IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_LOADFROMFILE);
if (!hBitmap)
return FALSE;
DIBSECTION dib;
if (::GetObject(hBitmap, sizeof(DIBSECTION), &dib) != sizeof(DIBSECTION)) {
::DeleteObject(hBitmap);
hBitmap = 0;
return FALSE;
}
Header.Info = dib.dsBmih;
for (int i=0; i<3; i++)
Header.BitField[i] = dib.dsBitfields[i];
bytes_per_pixel = PixelBytes(dib.dsBmih.biBitCount);
bytes_per_line = ScanBytes(dib.dsBmih.biWidth, dib.dsBmih.biBitCount);
Bits = dib.dsBm.bmBits;
return TRUE;
}
//
//
BOOL CDibSection::SaveBmp(const char *path)
{
TRY {
CFile file(path, CFile::modeCreate | CFile::modeWrite);
int length = bytes_per_line * Height();
BITMAPFILEHEADER header;
memset(&header, 0, sizeof(header));
header.bfType = (WORD)('M' << 8) | 'B';
header.bfSize = sizeof(header) + Header.Info.biSize + length;
header.bfOffBits = sizeof(header) + Header.Info.biSize;
file.Write(&header, sizeof(header));
file.Write(&Header.Info, Header.Info.biSize);
if (Header.Info.biCompression == BI_BITFIELDS)
file.Write(Header.BitField, sizeof(Header.BitField));
file.Write(Bits, length);
file.Close();
}
CATCH(CFileException, e) {
return FALSE;
}
END_CATCH
return TRUE;
}
#ifdef USEPNG
// stdio wrapper
//
//
//
class CStdio {
public:
CStdio(const char *path, const char *mode="rb");
~CStdio();
int Read(void *buf, int len);
int Write(void *buf, int len);
FILE *fp;
} ;
//
//
inline CStdio::CStdio(const char *path, const char *mode)
{
fp = fopen(path, mode);
if (fp == 0)
throw exception("can't open");
}
//
//
inline CStdio::~CStdio()
{
fclose(fp);
}
//
//
inline int CStdio::Read(void *buf, int len)
{
return fread(buf, 1, len, fp);
}
//
//
inline int CStdio::Write(void *buf, int len)
{
return fwrite(buf, 1, len, fp);
}
//
// Row data
//
class row_data {
public:
row_data(const CDibSection *image);
~row_data();
operator png_bytepp();
private:
png_bytepp row;
} ;
//
//
inline row_data::row_data(const CDibSection *image)
{
row = new png_byte *[image->Height()];
for (png_uint_32 y=0; y<image->Height(); y++)
row[y] = (png_byte *)image->GetBits(0, y);
}
//
//
inline row_data::~row_data()
{
delete[] row;
}
//
//
inline row_data::operator png_bytepp()
{
return row;
}
//
//
BOOL CDibSection::LoadPng(const char *path, bool alpha_include)
{
try {
CStdio file(path);
png_byte buf[8];
if (file.Read(buf, 8) != 8 || !png_check_sig(buf, 8))
return FALSE;
cpng_read png;
png.init_io(file.fp);
png.set_sig_bytes(8);
png.read_info();
png_uint_32 width, height;
int depth, color_type;
png.get_IHDR(&width, &height, &depth, &color_type);
if (alpha_include) {
if ((color_type & PNG_COLOR_MASK_ALPHA) == 0)
return false;
}
else {
if (color_type & PNG_COLOR_MASK_ALPHA)
png.set_strip_alpha();
}
if (color_type == PNG_COLOR_TYPE_PALETTE)
png.set_expand();
if (color_type == PNG_COLOR_TYPE_GRAY && depth < 8)
png.set_expand();
if (png.get_valid(PNG_INFO_tRNS))
png.set_expand();
if (depth > 8)
png.set_strip_16();
if (color_type == PNG_COLOR_TYPE_GRAY)
png.set_gray_to_rgb();
png.read_update_info();
png.get_IHDR(&width, &height, &depth, &color_type);
if (color_type != PNG_COLOR_TYPE_RGB)
return FALSE;
if (!Create(width, height, alpha_include? 32: 24))
return FALSE;
row_data row(this);
png.set_bgr();
png.read_image(row);
png.read_end();
}
catch (...) {
return FALSE;
}
return TRUE;
}
//
//
BOOL CDibSection::SavePng(const char *path)
{
try {
CStdio file(path, "wb");
cpng_write png;
png.init_io(file.fp);
// png.set_compression_level();
// png.set_filter(PNG_FILTER_TYPE_BASE, PNG_ALL_FILTERS);
png.set_filter(PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB);
png.set_IHDR(Width(), Height(), 8, PNG_COLOR_TYPE_RGB);
png.write_info();
row_data row(this);
png.set_bgr();
png.write_image(row);
png.write_end();
}
catch (...) {
return FALSE;
}
return TRUE;
}
#endif
//
//
void CDibSection::Copy(const CDibSection &dib)
{
BitBlt(CDibDC(*this), 0, 0, dib.Width(), dib.Height(), CDibDC(dib), 0, 0, SRCCOPY);
}
void CDibSection::Copy(const CDibSection &dib, CPoint to, CSize size, CPoint from)
{
BitBlt(CDibDC(*this), to.x, to.y, size.cx, size.cy, CDibDC(dib), from.x, from.y, SRCCOPY);
}
//
//
void CDibSection::Mix(const CDibSection &dib, CPoint to, CSize size, CPoint from, COLORREF tc)
{
if (Depth() == dib.Depth()) {
switch (Depth()) {
case 16:
{
BYTE r = GetRValue(tc);
BYTE g = GetGValue(tc);
BYTE b = GetBValue(tc);
WORD color = (r << 7) & 0x7c00 | (g << 2) & 0x03e0 | (b >> 3) & 0x001f;
for (int y = 0; y < size.cy; y++) {
WORD *p = (WORD *)GetBits(to.x, to.y + y);
const WORD *q = (const WORD *)dib.GetBits(from.x, from.y + y);
for (int x = 0; x < size.cx; x++) {
if (*q != color)
*p = *q
上一篇:
frmAnalysis.frm
下一篇:
高等数学课程复习资料