win32image.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 748 行 · 第 1/2 页
CPP
748 行
//Win32Image.cpp
/*
Copyright 2000-2004 The VCF Project.
Please see License.txt in the top level directory
where you installed the VCF.
*/
#include "vcf/GraphicsKit/GraphicsKit.h"
#include "vcf/GraphicsKit/GraphicsKitPrivate.h"
using namespace VCF;
Win32Image::Win32Image()
{
flipBits_ = false;
ownDC_ = true;
init();
}
Win32Image::Win32Image( const unsigned long& width, const unsigned long& height ):
AbstractImage(false)
{
flipBits_ = false;
ownDC_ = true;
init();
setSize( width, height );
}
Win32Image::Win32Image( const String& fileName ):
AbstractImage(false)
{
flipBits_ = true;
ownDC_ = true;
init();
loadFromFile( fileName );
}
Win32Image::Win32Image( GraphicsContext* context, Rect* rect ):
AbstractImage(false)
{
flipBits_ = false;
ownDC_ = false; //leave it this way to begin with and then
//switch to false for the duration after the intial
//bitmap has been created
if ( (NULL != context) && (NULL != rect) ){
Win32Context* ctx = reinterpret_cast<Win32Context*>(context->getPeer() );
if ( NULL != ctx ){
//set up the bitmap data
IMTRAITS::setChannelType( flags_, IMTRAITS::getTraitsChannelType() );
IMTRAITS::setChannelSize( flags_, IMTRAITS::getTraitsChannelSize() );
IMTRAITS::setImageType( flags_, IMTRAITS::getTraitsImageType() );
IMTRAITS::setPixelLayoutOrder( flags_, Image::ploBGRA );
//hBitmap_ = NULL;
palette_ = NULL;
HDC contextDC = (HDC)ctx->getContextID();
//the deletion of the context_ should delete the
//dc_ handle
context_ = context;
HDC tmpDC = CreateCompatibleDC( contextDC );
HDC origDC = contextDC;
contextDC = tmpDC;
setSize( rect->getWidth(), rect->getHeight() );
contextDC = origDC;
int r = BitBlt( tmpDC, 0, 0, getWidth(), getHeight(), contextDC, (int)rect->left_, (int)rect->top_, SRCCOPY );
::SelectObject( tmpDC, hbmp_.oldBMP() );
DeleteDC( tmpDC );
hbmp_.attach( contextDC );
//hOldBitmap_ = (HBITMAP)::SelectObject( dc_, (HBITMAP)hbmp );
//ownDC_ = false;
}
else {
//throw exception !!!
throw InvalidPointerException( MAKE_ERROR_MSG_2("Incorrect peer class (isn't a Win32Context) for passed GraphicsContext instance" ) );
}
}
else {
//throw exception !!!
throw InvalidPointerException( MAKE_ERROR_MSG_2("Graphics Context passed in to Win32Image is NULL" ) );
}
}
Win32Image::Win32Image( HBITMAP bitmap )
:AbstractImage(false)
{
flipBits_ = true;
ownDC_ = true;
init();
if ( NULL == bitmap ) {
throw InvalidPointerException(MAKE_ERROR_MSG_2("NULL HBITMAP passed into Win32Image constructor"));
}
loadFromBMPHandle( bitmap );
}
Win32Image::Win32Image( HICON icon )
:AbstractImage(false)
{
flipBits_ = true;
ownDC_ = true;
init();
ICONINFO info = {0};
if ( GetIconInfo( icon, &info ) ) {
BITMAP bmp;
if ( GetObject( info.hbmColor, sizeof(BITMAP), &bmp ) ) {
setSize( bmp.bmWidth, bmp.bmHeight );
if ( !DrawIcon( hbmp_.dc(), 0, 0, icon ) ) {
StringUtils::traceWithArgs( Format("DrawIcon failed, err: %d\n") % GetLastError() );
}
}
}
}
Win32Image::~Win32Image()
{
//if ( NULL != hBitmap_ ){
// SelectObject( dc_, hOldBitmap_ );
// int err = DeleteObject( hBitmap_ );
//}
//the base class AbstractImage will take care of
//deleting hte GraphicsContext. If we don't
//own the DC then set the context_ to null
//to prevent from deleting it
if ( ownDC_ ) {
//DeleteDC( dc_ );
}
else {
hbmp_.detach();
context_ = NULL;
}
imageBits_->pixels_ = NULL;
}
void Win32Image::init()
{
//NOTE: init() is not called if ownDC_ is true - the constructor takes care of this
IMTRAITS::setChannelType( flags_, IMTRAITS::getTraitsChannelType() );
IMTRAITS::setChannelSize( flags_, IMTRAITS::getTraitsChannelSize() );
IMTRAITS::setImageType( flags_, IMTRAITS::getTraitsImageType() );
IMTRAITS::setPixelLayoutOrder( flags_, Image::ploBGRA );
//hBitmap_ = NULL;
palette_ = NULL;
//dc_ = ::CreateCompatibleDC( NULL );
//the deletion of the context_ should delete the
//dc_ handle
context_ = new GraphicsContext( (OSHandleID)hbmp_.dc() );
}
void Win32Image::setSize( const unsigned long & width, const unsigned long & height )
{
if ( (!ownDC_) && (hbmp_ != NULL) ) {
throw RuntimeException( MAKE_ERROR_MSG_2("Cannot set size for non modifiable image") );
}
AbstractImage::setSize( width, height );
createBMP();
}
void Win32Image::createBMP()
{
if ( (!ownDC_) && (hbmp_ != NULL) ) {
throw RuntimeException( MAKE_ERROR_MSG_2("Cannot set size for non modifiable image") );
}
dataBuffer_ = NULL;
//hBitmap_ = NULL;
memset( &bmpInfo_, 0, sizeof (BITMAPINFOHEADER) );
bmpInfo_.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmpInfo_.bmiHeader.biWidth = getWidth();
if ( true == flipBits_ ) {
bmpInfo_.bmiHeader.biHeight = -getHeight(); // Win32 DIB are upside down - do this to filp it over
}
else {
//this needs to be fixed
//I put this back for now JEC-12-10-2001
bmpInfo_.bmiHeader.biHeight = -getHeight(); // this is WRONG, cause there are times when we don't
// want it this way, but it will have to do for now :(
}
bmpInfo_.bmiHeader.biPlanes = 1;
bmpInfo_.bmiHeader.biBitCount = 32;
bmpInfo_.bmiHeader.biCompression = BI_RGB;
bmpInfo_.bmiHeader.biSizeImage = abs(bmpInfo_.bmiHeader.biHeight) * bmpInfo_.bmiHeader.biWidth * 4;
imageBits_->pixels_ = NULL;
hbmp_.setSize( getWidth(), getHeight() );
//hBitmap_ = CreateDIBSection ( dc_, &bmpInfo_, DIB_RGB_COLORS, (void **)&imageBits_->pixels_, NULL, NULL );
if ( (hbmp_ != NULL) ) {
dataBuffer_ = (unsigned char*)hbmp_.data();
imageBits_->pixels_ = (SysPixelType*)hbmp_.data();
SysPixelType* pix = imageBits_->pixels_;
int sz = bmpInfo_.bmiHeader.biWidth * abs(bmpInfo_.bmiHeader.biHeight);
do {
sz --;
pix[sz].a = 255;
} while( sz > 0 );
//hOldBitmap_ = (HBITMAP)::SelectObject( dc_, hBitmap_ );
//::DeleteObject( oldObj );//clear out the old object
}
}
HBITMAP Win32Image::getBitmap()
{
return hbmp_;
}
HDC Win32Image::getDC()
{
return hbmp_.dc();
}
void Win32Image::loadFromFile( const String& fileName )
{
flipBits_ = true;
HBITMAP hBMP = NULL;
if ( System::isUnicodeEnabled() ) {
hBMP = (HBITMAP)LoadImageW( NULL, fileName.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
}
else {
hBMP = (HBITMAP)LoadImageA( NULL, fileName.ansi_c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
}
if ( NULL == hBMP ) {
throw ImageLoaderException(MAKE_ERROR_MSG_2("Image file unreadable - this may be due to an incorrect file name"));
}
loadFromBMPHandle( hBMP );
}
void Win32Image::loadFromBMPHandle( HBITMAP bitmap )
{
flipBits_ = true;
//hBitmap_ = bitmap;
BITMAP bmp = {0};
GetObject( bitmap, sizeof(bmp), &bmp );
setSize( bmp.bmWidth, bmp.bmHeight );
HDC tmpBMPDC = CreateCompatibleDC( NULL );
HBITMAP oldBitmap = (HBITMAP)::SelectObject( tmpBMPDC, bitmap );
BitBlt( hbmp_.dc(), 0, 0, bmp.bmWidth, bmp.bmHeight, tmpBMPDC, 0, 0, SRCCOPY );
::SelectObject( tmpBMPDC, oldBitmap );
DeleteDC( tmpBMPDC );
DeleteObject( bitmap );
SysPixelType* pix = imageBits_->pixels_;
int sz = bmpInfo_.bmiHeader.biWidth * abs(bmpInfo_.bmiHeader.biHeight);
do {
sz --;
pix[sz].a = 255;
} while( sz > 0 );
}
void Win32Image::internal_saveToFile( const String& fileName )
{
/**
NOTE!!!!
It's important that this get's written out with "wb", not
just "w" here.
*/
#ifdef VCF_CW
FILE* f = fopen( fileName.ansi_c_str(), "wb" );
#else
FILE* f = _wfopen( fileName.c_str(), L"wb" );
#endif
// write the file header
const int bitsPerPix = 24;
//store width for 24bit image NOT 32
DWORD width = ((((bitsPerPix * getWidth()) + 31) / 32) * 4);
DWORD size = getHeight() * width;
BITMAPINFOHEADER bih = {0};
bih.biHeight = getHeight();
bih.biWidth = getWidth();
bih.biClrImportant = 0;
bih.biClrUsed = 0;
bih.biPlanes = 1;
bih.biSizeImage = size;
bih.biBitCount = bitsPerPix;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biCompression = BI_RGB;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
BITMAPFILEHEADER bitmapfileheader;
bitmapfileheader.bfType = 0x4D42;
bitmapfileheader.bfSize = sizeof(BITMAPFILEHEADER) + size;
bitmapfileheader.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + bih.biSize;
//sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
//0 * sizeof(RGBQUAD);
bitmapfileheader.bfReserved1 = 0;
bitmapfileheader.bfReserved2 = 0;
fwrite( &bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, f );
// write the info header
fwrite( &bih, bih.biSize, 1, f );
// write the palette here, but we'll do nothing since we don't support palettes
DWORD height = getHeight();
SysPixelType* bits = getImageBits()->pixels_;
unsigned char* row = new unsigned char[width];
unsigned long imgWidth = getWidth();
// write the bitmap data
unsigned char* tmpRow = row;
for ( int y=height-1;y>=0;y-- ) {
tmpRow = row;
for (unsigned long x=0;x<imgWidth;x++ ) {
SysPixelType& pix = bits[y*imgWidth + x];
*tmpRow = pix.b;
tmpRow++;
*tmpRow = pix.g;
tmpRow++;
*tmpRow = pix.r;
tmpRow++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?