📄 dibipl.cpp
字号:
//-----------------------------------------------------------------------------
// (c) 2002 by Basler Vision Technologies
// Section: Vision Components
// Project: BCAM
// $Header: DibIpl.cpp, 2, 16.09.2002 10:28:24, Nebelung, H.$
//-----------------------------------------------------------------------------
/**
\file DibIpl.cpp
\brief implementation of the CDibIplIpl class.
*/
#include "stdafx.h"
#include "DibIpl.h"
#include "stdafx.h"
#include <assert.h>
#include <ipl.h>
#include <bvcexception.h>
#include "dibsectn.h"
using Bvc::Exception;
//! Default constructor
CDibIpl::CDibIpl() :
m_hBitmap(NULL),
m_Orientation(BottomUp),
m_PaletteType(Color),
m_RefCount(0)
{
m_pIplImage = NULL;
}
//! Destroy all BMP related resources
void CDibIpl::Destroy()
{
// Destroy the referenced DIB section
if(m_hBitmap)
{
if(!::DeleteObject(m_hBitmap))
throw BvcException(::GetLastError(), "CDibIpl::Destroy");
m_hBitmap = NULL;
}
// Destroy the IPL image header
if(m_pIplImage)
{
iplDeallocate( m_pIplImage, IPL_IMAGE_HEADER );
m_pIplImage = NULL;
}
}
//! Increments the reference counter of this object
long CDibIpl::AddRef()
{
return ::InterlockedIncrement(&m_RefCount);
}
//! Decrements the reference counter of this object. Destroys the object if the reference counter becomes 0.
void CDibIpl::Release()
{
::InterlockedDecrement(&m_RefCount);
if(0 == m_RefCount)
delete this;
}
//! Create a CDibIpl object
CDibIpl* CDibIpl::Create( CSize Size, unsigned int BitsPerPixel, Orientation_t Orientation, PaletteType_t PaletteType )
{
CDibIpl *pDib = new CDibIpl();
pDib->m_Orientation = Orientation;
pDib->m_PaletteType = PaletteType;
pDib->m_hBitmap = DSCreateDIBSection( Size.cx, Orientation == BottomUp ? Size.cy : -Size.cy, BitsPerPixel, PaletteType == Monochrome );
if(!pDib->m_hBitmap)
throw BvcException(E_FAIL, "CDibIpl::Create");
pDib->AddRef();
pDib->Refresh();
return pDib;
}
//! Loads the bitmap from a BMP file
CDibIpl* CDibIpl::LoadBMP( CString FileName )
{
CDibIpl *pDib = new CDibIpl();
if(!DSLoadDIBSectionFromBMPFile( (LPCTSTR) FileName, &pDib->m_hBitmap, NULL ))
throw BvcException(E_FAIL, "CDibIpl::LoadBMP");
// BMP files are always bottom up
pDib->m_Orientation = BottomUp;
// Check if the image is Mono8
pDib->m_PaletteType = Color;
LPBITMAPINFO pBitmapInfo = DSGetBITMAPINFOForDIBSection( pDib->m_hBitmap );
if(pBitmapInfo->bmiHeader.biBitCount == 8)
{
for(int i=0; i<256; ++i)
{
if( pBitmapInfo->bmiColors[i].rgbRed != i
|| pBitmapInfo->bmiColors[i].rgbGreen != i
|| pBitmapInfo->bmiColors[i].rgbBlue != i )
break;
}
pDib->m_PaletteType = Monochrome;
}
free(pBitmapInfo);
pDib->AddRef();
pDib->Refresh();
return pDib;
}
//! Virtual destructor
CDibIpl::~CDibIpl()
{
Destroy();
}
//! checks if twobitmaps share the same properties
bool CDibIpl::IsEqualType(CDibIpl& Dib)
{
BITMAP ThisBitmap;
BITMAP Bitmap;
GetBitmap(&ThisBitmap);
Dib.GetBitmap(&Bitmap);
return( Bitmap.bmType == ThisBitmap.bmType
&& Bitmap.bmWidth == ThisBitmap.bmWidth
&& Bitmap.bmHeight == ThisBitmap.bmHeight
&& Bitmap.bmWidthBytes == ThisBitmap.bmWidthBytes
&& Bitmap.bmPlanes == ThisBitmap.bmPlanes
&& Bitmap.bmBitsPixel == ThisBitmap.bmBitsPixel
&& Dib.m_Orientation == m_Orientation );
}
//! Stores the bitmap to a BMP file
void CDibIpl::StoreBMP( CString FileName )
{
if( m_Orientation == TopDown )
{
// BMP file have to be stores bottom up so we have to topple it
HBITMAP hBitmap = GetToppledCopy();
DSStoreDIBSectionInBMPFile( (LPCTSTR) FileName, hBitmap);
::DeleteObject(hBitmap);
}
else
{
DSStoreDIBSectionInBMPFile( (LPCTSTR) FileName, m_hBitmap);
}
}
//! Gets a HBITMAP handle (no ownership is granted!)
HBITMAP CDibIpl::GetBitmapHandle()
{
return m_hBitmap;
}
//! Returns a pointer to the pixel data
void* CDibIpl::GetPixels()
{
BITMAP Bitmap;
if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
throw BvcException(::GetLastError(), "CDibIpl::GetPixels");
return Bitmap.bmBits;
}
//! Returns the bitmap's size 1
void CDibIpl::GetSize(CSize *pSize)
{
assert(pSize);
if(!m_hBitmap)
{
pSize->cx = 0;
pSize->cy = 0;
}
else
{
BITMAP Bitmap;
if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
throw BvcException(::GetLastError(), "CDibIpl::GetSize");
pSize->cx = Bitmap.bmWidth;
pSize->cy = Bitmap.bmHeight;
}
}
//! Returns the bitmap's size 2
CSize CDibIpl::GetSize()
{
CSize Size;
GetSize(&Size);
return Size;
}
//! Returns the total size of a line in bytes
unsigned long CDibIpl::GetWidthBytes()
{
BITMAP Bitmap;
if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
throw BvcException(::GetLastError(), "CDibIpl::GetSize");
return Bitmap.bmWidthBytes;
}
//! Returns the total size of the image in bytes
unsigned long CDibIpl::GetTotalPixelBytes()
{
BITMAP Bitmap;
if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
throw BvcException(::GetLastError(), "CDibIpl::GetSize");
return Bitmap.bmWidthBytes * Bitmap.bmHeight;
}
//! Returns the bitmap's bits per pixel
unsigned short CDibIpl::GetBitsPerPixel()
{
BITMAP Bitmap;
if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
throw BvcException(::GetLastError(), "CDibIpl::GetBitsPerPixel");
return Bitmap.bmBitsPixel;
}
//! Returns the bitmaps orientation (BottomUp or TopDown)
CDibIpl::Orientation_t CDibIpl::GetOrientation()
{
return m_Orientation;
}
//! Returns the bitmaps palette type (e.g., color or monochrome )
CDibIpl::PaletteType_t CDibIpl::GetPaletteType()
{
return m_PaletteType;
}
//! Returns the bitmaps BITMAPINFORHEADER
void CDibIpl::GetBitmapInfoHeader(BITMAPINFOHEADER *pBitmapInfoHeader)
{
DIBSECTION DibSection;
if(!::GetObject(m_hBitmap, sizeof(DIBSECTION), &DibSection))
throw BvcException(::GetLastError(), "CDibIpl::GetBitmapInfoHeader");
::CopyMemory(pBitmapInfoHeader, &(DibSection.dsBmih), sizeof(BITMAPINFOHEADER));
}
//! Returns a bitmaps BITMAPINFO which has to be freed by the user
void CDibIpl::GetBitmapInfo(BITMAPINFO **ppBitmapInfo, unsigned long *pBitmapInfoBytes)
{
*ppBitmapInfo = DSGetBITMAPINFOForDIBSection( m_hBitmap );
*pBitmapInfoBytes = sizeof(BITMAPINFOHEADER) + DSColorTableSize( *ppBitmapInfo );
}
//! Returns the bitmaps BITMAP
void CDibIpl::GetBitmap(BITMAP *pBitmap)
{
if(!::GetObject(m_hBitmap, sizeof(BITMAP), pBitmap))
throw BvcException(::GetLastError(), "CDibIpl::GetBitmap");
}
//! Topples the bitmap
void CDibIpl::Topple()
{
if (m_hBitmap == NULL)
throw BvcException(E_FAIL, "CDibIpl::Topple - No bitmap present");
HBITMAP hBitmap = GetToppledCopy();
Destroy();
m_hBitmap = hBitmap;
m_Orientation = m_Orientation == BottomUp ? TopDown : BottomUp;
Refresh();
}
//! Clones the Bitmap
CDibIpl* CDibIpl::Clone(
bool Topple //!< If true the clone will be toppled with resprect to the original bitmap
)
{
if (m_hBitmap == NULL)
throw BvcException(E_FAIL, "CDibIpl::Clone - No bitmap present");
HBITMAP pBitmap = NULL;
if(Topple)
{
pBitmap = GetToppledCopy();
}
else
{
pBitmap = GetCopy();
}
CDibIpl *pDib = new CDibIpl();
pDib->m_hBitmap = pBitmap;
pDib->m_Orientation = Topple ? (m_Orientation == BottomUp ? TopDown : BottomUp) : m_Orientation;
pDib->m_PaletteType = m_PaletteType;
pDib->AddRef();
pDib->Refresh();
return pDib;
}
//! Copies the image to the clipboard
void CDibIpl::CopyToClipboard()
{
if ( GetOrientation() == CDibIpl::TopDown )
{
CDibIpl* pDib = Clone(true);
if (pDib == NULL)
throw BvcException(E_FAIL, "CDibIpl::CopyToClipboard");
pDib->CopyToClipboard();
delete pDib;
}
else
{
HGLOBAL hGlobal = NULL;
try
{
if (m_hBitmap == NULL)
throw BvcException(E_FAIL, "CDibIpl::CopyToClipboard - No bitmap present");
// Get BITMAPINFO Header
LPBITMAPINFO pBitmapInfo;
pBitmapInfo = DSGetBITMAPINFOForDIBSection( m_hBitmap );
if(!pBitmapInfo)
throw BvcException(::GetLastError(), "CDibIpl::CopyToClipboard");
// Create a suitable global memory buffer and lock it
DWORD TotalDIBBytes = DSTotalBytesSize( pBitmapInfo );
hGlobal = GlobalAlloc(GHND | GMEM_SHARE, TotalDIBBytes );
if(!hGlobal)
throw BvcException(::GetLastError(), "CDibIpl::CopyToClipboard");
// Lock the global Buffer
char* pBuffer = (char*) GlobalLock(hGlobal);
if ( pBuffer == NULL )
throw BvcException(::GetLastError(), "CDibIpl::CopyToClipboard");
// Copy the information header and the color table to the global Buffer
DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER) + DSColorTableSize( pBitmapInfo );
CopyMemory(pBuffer, &pBitmapInfo->bmiHeader, dwHeaderSize);
// Copy the image data to the global buffer
LPBYTE pBits = DSGetPointerToDIBSectionImageBits( m_hBitmap );
DWORD dwSize = DSImageBitsSize( pBitmapInfo );
CopyMemory(((PBYTE) pBuffer) + dwHeaderSize, pBits, dwSize);
// Clean up
free(pBitmapInfo);
GlobalUnlock(hGlobal);
// set the buffer to the clipboard
if(!::OpenClipboard(NULL))
throw BvcException(::GetLastError(), "CDibIpl::CopyToClipboard");
if(!::EmptyClipboard())
throw BvcException(::GetLastError(), "CDibIpl::CopyToClipboard");
if(!::SetClipboardData(CF_DIB, hGlobal))
throw BvcException(::GetLastError(), "CDibIpl::CopyToClipboard");
if(!::CloseClipboard())
throw BvcException(::GetLastError(), "CDibIpl::CopyToClipboard");
}
catch(BvcException e)
{
if(hGlobal)
::GlobalFree(hGlobal);
throw e;
}
}
}
//! Returns a DIB section which is a copy of the referenced bitmap
HBITMAP CDibIpl::GetCopy()
{
if (m_hBitmap == NULL)
throw BvcException(E_FAIL, "CDibIpl::GetCopy - No bitmap present");
LPBITMAPINFO pBitmap = DSGetBITMAPINFOForDIBSection(m_hBitmap);
if (! pBitmap) throw BvcException( E_FAIL, "CDibIpl::GetCopy - No bitmap info present" );
pBitmap->bmiHeader.biHeight = m_Orientation == TopDown ? -pBitmap->bmiHeader.biHeight : pBitmap->bmiHeader.biHeight;
LPBYTE pSrc = DSGetPointerToDIBSectionImageBits(m_hBitmap);
if (!pSrc) throw BvcException( ::GetLastError(), "CDibIpl::GetCopy" );
LPBYTE pDst = NULL;
HBITMAP hBitmap = ::CreateDIBSection( NULL, pBitmap, DIB_RGB_COLORS, (void**)&pDst, NULL, 0 );
free(pBitmap);
if(hBitmap == NULL || pDst == NULL)
throw BvcException(::GetLastError(), "CDibIpl::GetCopy");
return hBitmap;
}
//! Returns a DIB section which is a toppled copy of the referenced bitmap
HBITMAP CDibIpl::GetToppledCopy()
{
if (m_hBitmap == NULL)
throw BvcException(E_FAIL, "CDibIpl::GetToppledCopy - No bitmap present");
LPBITMAPINFO pBitmap = DSGetBITMAPINFOForDIBSection(m_hBitmap);
if (!pBitmap) throw BvcException(::GetLastError(), "CDibIpl::GetToppledCopy");
LPBYTE pSrc = DSGetPointerToDIBSectionImageBits(m_hBitmap);
if (!pSrc) throw BvcException(::GetLastError(), "CDibIpl::GetToppledCopy");
// Create a version of the image which is top down if the original image was bottom up
// and vice versa.
// BEWARE : For some strange reason the newly created image will have a biHeight > 0
// even if we created it with biHeight < 0. Nevertheless the bitmap object somehow
// remembers the fact that it is top-down because if it's drawn it appears correct
pBitmap->bmiHeader.biHeight = -pBitmap->bmiHeader.biHeight;
LPBYTE pDst = NULL;
HBITMAP hBitmap = ::CreateDIBSection( NULL, pBitmap, DIB_RGB_COLORS, (void**)&pDst, NULL, 0 );
if(hBitmap == NULL || pDst == NULL)
throw BvcException(::GetLastError(), "CDibIpl::GetToppledCopy");
DWORD rowlength = GetWidthBytes();
for( int i = 0, m = abs(pBitmap->bmiHeader.biHeight) - 1; i < abs(pBitmap->bmiHeader.biHeight); i++, m-- )
{
memcpy(pDst + m * rowlength, pSrc + i * rowlength, rowlength);
}
return hBitmap;
}
//! This function is called whenever the bitmap is re-created
void CDibIpl::Refresh()
{
// TODO : Create a matching palette (but honestly : who is using
// palettised graphic cards any more? :-)
// Create a IPL header describing the BMP. No additional memory is allocated
if( m_hBitmap )
{
BITMAP Bitmap;
GetBitmap(&Bitmap);
int nChannels = Bitmap.bmBitsPixel == 1 ? 1 : Bitmap.bmBitsPixel/8;
int depth = Bitmap.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
int origin = m_Orientation == BottomUp ? IPL_ORIGIN_BL : IPL_ORIGIN_TL;
m_pIplImage = iplCreateImageHeader(
nChannels, // number of channels
0, // # of alpha channel, 0-absent
depth, // bit depth of channel
"RGB", // color model
"BGR", // channel sequence
IPL_DATA_ORDER_PIXEL,// data ordering : by pixels or by channels
origin, // bitmap origin : _TL = top left, _BL = bottom left
IPL_ALIGN_DWORD,// scan lines alignment
Bitmap.bmWidth, // width in pixels
Bitmap.bmHeight,// height and
0, // ROI, 0 - entire image
0, // MASK ROI, 0 - entire image
0, // image ID - reserved
0); // tile info.
m_pIplImage->imageData = m_pIplImage->imageDataOrigin = (char*)(Bitmap.bmBits);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -