📄 image.cpp
字号:
/***************************************************************/
/*文件名: image.cpp */
/*文件描述: */
/*相关文件: global.h, global.cpp, image.h */
/*主要函数: */
/*提交日期: 作 者:刘岩、山世光 */
/*编 辑 器: Visual C++ */
/*版权:哈尔滨工业大学智能接口实验室 中科院计算所数字媒体实验室*/
/*版权说明:任何使用必须保留版权信息和历史纪录信息 */
/*修改纪录: */
/*日 期 版本 修改人 修改内容 */
/*03/22/1999 2.0 山世光 --------- */
/*05/22/2000 3.0 山世光 --------- */
/***************************************************************/
#include "stdafx.h"
#include "math.h"
#include "GlobalFunc.h"
#include "image.h"
#include <windowsx.h> // for GlobalAllocPtr
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#define pi 3.1415926
IMPLEMENT_SERIAL(CImage, CObject, 0)
///////////////////////////////////////////////////////////////////
CImage::CImage(): m_bIsDIB(TRUE),m_dwLength(0L),
m_pDib (NULL),m_pData(NULL)
{
m_pPal =new CPalette;
}
///////////////////////////////////////////////////////////////////
CImage::CImage(const CImage& img)//copy constructor
{
m_bIsDIB=img.m_bIsDIB;
m_dwLength=img.m_dwLength;
m_pDib=0;
if(img.m_pDib){
m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
if(!m_pDib)
{
AfxMessageBox("Unable to allocate DIB memory");
return;
}
memcpy(m_pDib,img.m_pDib,m_dwLength);
m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors();
}
m_pPal=new CPalette;
CreateDIBPalette();
}
///////////////////////////////////////////////////////////////////
CImage::CImage(CImage& img, CPoint start, CSize size)
{
int bpp;
int bytepp;
long hdlen;/*size of the DIB header info*/
LPBITMAPINFOHEADER pBMIH;
ASSERT(img.m_pDib);
WORD dww=img.Width();
WORD dwh=img.Height();
if(( (size.cx+start.x)>dww )||( (size.cy+start.y)>dwh )){
AfxMessageBox("Image size is too large!");
return;
}
img.Data();
m_bIsDIB = FALSE;
hdlen = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * img.NumColors();
bpp = img.Bits();
bytepp = bpp / 8;
ASSERT(bpp != 16 && bpp != 32);
DWORD bypeinoneline = ByteNumForOneLine((WORD)size.cx, bpp);//Bytes per line
m_dwLength = hdlen + bypeinoneline * size.cy;
if (!AllocateMemory( )){
return;
}
memcpy(m_pDib, img.m_pDib, hdlen);
pBMIH = BMInfoHdPtr();
pBMIH->biWidth = size.cx;
pBMIH->biHeight = size.cy;
pBMIH->biSizeImage = size.cx * size.cy * bytepp;
m_pData = (BYTE*)(m_pDib + hdlen);
BYTE* p1, *p2;
long t1, t2;
t1 = dww * bytepp;
t2 = size.cx * bytepp;
p1 = ( BYTE* ) ( img.m_pData + (start.y * dww + start.x) * bytepp);
p2 = m_pData;
for(int i=0 ; i<(int)size.cy; i++)
{
memcpy(p2 , p1 , t2);
p1 += t1;
p2 += t2;
}
Dib();
img.Dib();
m_pPal=new CPalette;
CreateDIBPalette();
}
///////////////////////////////////////////////
/*the constructor used to create a DIB of size 'size'
with no initializing image data*/
CImage::CImage(CSize size,int NumColor,int Bits)
{
LPBITMAPINFOHEADER pBMIH;
m_dwLength = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * NumColor;
if (!AllocateMemory()) return;
DWORD dwBytes = Transform((WORD)size.cx);
m_dwLength += dwBytes * size.cy * Bits / 8;
if (!AllocateMemory(TRUE)){
return;
}
pBMIH=BMInfoHdPtr();
pBMIH->biSize = sizeof(BITMAPINFOHEADER);
pBMIH->biWidth = size.cx;
pBMIH->biHeight = size.cy;
pBMIH->biSizeImage = size.cx*size.cy;
pBMIH->biPlanes = 1;
pBMIH->biBitCount = Bits; // 1, 4, 8, or 24
pBMIH->biCompression = BI_RGB;
pBMIH->biXPelsPerMeter = 0;
pBMIH->biYPelsPerMeter = 0;
pBMIH->biClrUsed = 0;
pBMIH->biClrImportant = 0;
m_pData = (BYTE*)(m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * NumColor);
SetDIB();
m_pPal=new CPalette;
CreateGreyPalette();
}
///////////////////////////////////////////////////////////////////
//part copy constructor
CImage& CImage::operator=(const CImage& img)
{
m_bIsDIB=img.m_bIsDIB;
m_dwLength=img.m_dwLength;
if(img.m_pDib){
TRY {
if(m_pDib){
m_pDib = (BYTE*) GlobalReAllocPtr(m_pDib,
m_dwLength, GHND);
}else
{
m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
}
}
CATCH (CMemoryException, e) {
AfxMessageBox("Unable to allocate DIB memory");
return *this;
}
END_CATCH
memcpy(m_pDib,img.m_pDib,m_dwLength);
m_pData = (BYTE*)((BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors());
}else
{
GlobalFree(m_pDib);
m_pDib=0;
}
if(m_pPal) delete m_pPal;
m_pPal=new CPalette;
CreateDIBPalette();
return *this;
}
///////////////////////////////////////////////////////////////////
CImage::CImage(CDC* pDC, int nBt, BOOL bCompr):m_bIsDIB(TRUE)
/* pDC is memory DC ptr and Cbitmap object has been selected into it
nBt is color bits per pixel (default = 0)
bCompr is compression (default = TRUE)
*/
{
// constructs a DIB from the contents of a bitmap
BITMAP bm;
int nPaletteSize,wBits;
LPBITMAPINFOHEADER pBMIH;
LPBITMAPINFO pBMI;
CBitmap* pEmptyBitmap = new CBitmap;
pEmptyBitmap->CreateCompatibleBitmap(pDC, 0, 0);
CBitmap* pBitmap = (CBitmap*) (pDC->SelectObject(pEmptyBitmap));
pBitmap->GetObject(sizeof(bm), &bm);
if ((nBt == 1) || (nBt == 4) || (nBt == 8) || (nBt == 24)) {
wBits = nBt;
}
else { // nBt = 0
wBits = bm.bmPlanes * bm.bmBitsPixel; // color bits per pixel
}
if (wBits == 1) {
nPaletteSize = 2;
}
else {
if (wBits == 4) {
nPaletteSize = 16;
}
else {
if (wBits == 8) {
nPaletteSize = 256;
}
else {
nPaletteSize = 0; // no palette for 24-bit display
}
}
}
// fills out row to 4-byte boundary
DWORD dwBytes = ((DWORD) bm.bmWidth * wBits) / 32;
if (((DWORD) bm.bmWidth * wBits) % 32) {
dwBytes ++;
}
dwBytes *= 4;//pixels per line
m_dwLength = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize;
if (!AllocateMemory()) return;
pBMIH=BMInfoHdPtr();
pBMIH->biSize = sizeof(BITMAPINFOHEADER);
pBMIH->biWidth = bm.bmWidth;
pBMIH->biHeight = bm.bmHeight;
pBMIH->biPlanes = 1;
pBMIH->biBitCount = wBits; // 1, 4, 8, or 24
if (bCompr && (wBits == 4)) {
pBMIH->biCompression = BI_RLE4;
}
else {
if (bCompr && (wBits == 8)) {
pBMIH->biCompression = BI_RLE8;
}
else {
pBMIH->biCompression = BI_RGB;
}
}
pBMIH->biSizeImage = 0;
pBMIH->biXPelsPerMeter = 0;
pBMIH->biYPelsPerMeter = 0;
pBMIH->biClrUsed = 0;
pBMIH->biClrImportant = 0;
// calls GetDIBits with null data pointer to get size of DIB
pBMI=BMInfoPtr();
::GetDIBits(pDC->GetSafeHdc(), (HBITMAP) pBitmap->GetSafeHandle(),
0, (WORD) bm.bmHeight, NULL, pBMI, DIB_RGB_COLORS);
if (pBMIH->biSizeImage == 0) {//pBMIH????orpBMI
m_dwLength += dwBytes * bm.bmHeight;
pBMIH->biCompression = BI_RGB;
// escape route for device drivers that don't do compression
TRACE("Can't do compression\n");
}
else {
m_dwLength += pBMIH->biSizeImage;
}
if (!AllocateMemory(TRUE)) {
return;
}
pBMIH=BMInfoHdPtr();
pBMI=BMInfoPtr();
m_pData = (BYTE*) pBMIH + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize;
// second GetDIBits call to make DIB
if (!::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)
pBitmap->GetSafeHandle(), 0, (WORD) bm.bmHeight, m_pData,
pBMI, DIB_RGB_COLORS)) {
m_dwLength = 0L;
}
delete pDC->SelectObject(pBitmap); // delete pEmptyBitmap
Dib();
m_pPal=new CPalette;
CreateDIBPalette();
}
///////////////////////////////////////////////////////////////////
CImage::CImage(CImage& img, float scale)
{
WORD scrw,scrh,destw,desth;
DWORD dwDIBHeadLength;
img.Data();
m_bIsDIB = img.m_bIsDIB;
scrw = img.Width();
scrh = img.Height();
destw = (WORD) (scrw * scale);
desth = (WORD) (scrh * scale);
dwDIBHeadLength = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors();
DWORD dwBytes = Transform(destw);
m_dwLength = dwDIBHeadLength + (DWORD) dwBytes * desth;
m_pDib = NULL;
if(img.m_pDib)
{
m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
if(!m_pDib){
AfxMessageBox("Unable to allocate DIB memory");
return;
}
memcpy(m_pDib, img.m_pDib, dwDIBHeadLength);
m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors();
}
//shrink the image
ShrinkImage(img.m_pData, m_pData, scrw, scrh, scale);
LPBITMAPINFOHEADER pBMIH;
pBMIH=BMInfoHdPtr();
pBMIH->biWidth = destw;
pBMIH->biHeight = desth;
Dib(); img.Dib();
m_pPal=new CPalette; CreateDIBPalette();
}
///////////////////////////////////////////////////////////////////
/*CImage::CImage(CImage & img, CSize newSize)
{
WORD scrw,scrh,destw,desth;
DWORD dwDIBHeadLength;
img.Data();
m_bIsDIB = img.m_bIsDIB;
destw = (WORD) newSize.cx;
desth = (WORD) newSize.cy;
scrw = img.Width();
scrh = img.Height();
dwDIBHeadLength = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors();
DWORD dwBytes = Transform(destw);
m_dwLength = dwDIBHeadLength + (DWORD) dwBytes * desth;
m_pDib = NULL;
if(img.m_pDib)
{
m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
if(!m_pDib){
AfxMessageBox("Unable to allocate DIB memory");
return;
}
memcpy(m_pDib, img.m_pDib, dwDIBHeadLength);
m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors();
}
if((destw < scrw)&&(desth < scrh))
ShrinkImage(img.m_pData, m_pData, scrw, scrh, destw, desth);
else //Magnify the image
MagnifyImage(img.m_pData, m_pData, scrw, scrh, destw, desth);
LPBITMAPINFOHEADER pBMIH;
pBMIH=BMInfoHdPtr();
pBMIH->biWidth = destw;
pBMIH->biHeight = desth;
Dib(); img.Dib();
m_pPal=new CPalette; CreateDIBPalette();
}
*/
///////////////////////////////////////////////////////////////////
//before usere call this construction, must guarentee img.Bits() == 8 or 24
CImage::CImage(CImage & img, CSize newSize)
{
int bpp, byteperline;
WORD scrw, scrh, destw, desth;
DWORD dwDIBHeadLength;
img.Data();
m_bIsDIB = img.m_bIsDIB;
bpp = img.Bits();
if(bpp != 8 && bpp != 24)
return;
destw = (WORD) newSize.cx;
desth = (WORD) newSize.cy;
scrw = img.Width();
scrh = img.Height();
if((destw-scrw)*(desth-scrh) < 0)
{
AfxMessageBox("Current version only support!");
return;
}
byteperline = ByteNumForOneLine(destw, bpp);
dwDIBHeadLength = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors();
m_dwLength = dwDIBHeadLength + (DWORD) byteperline * desth;
m_pDib = NULL;
if(img.m_pDib)
{
m_pDib=(BYTE*) GlobalAllocPtr(GHND, m_dwLength);
if(!m_pDib){
AfxMessageBox("Unable to allocate DIB memory");
return;
}
memcpy(m_pDib, img.m_pDib, dwDIBHeadLength);
m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * img.NumColors();
}
if(bpp == 24)
{
BYTE * pSrcByteRGB = new BYTE [scrw * scrh *3];
BYTE * pDestByteRGB = new BYTE [destw * desth *3];
BYTE * pByteB = pSrcByteRGB;
BYTE * pByteG = pSrcByteRGB + scrw * scrh;
BYTE * pByteR = pByteG + scrw * scrh;
BYTE * pSrcByte = img.m_pData;
for (int i = 0; i < scrw; i++)
for (int j = 0; j < scrh; j++)
{
*pByteB = *pSrcByte;
pSrcByte++;
pByteB++;
*pByteG = *pSrcByte;
pSrcByte++;
pByteG++;
*pByteR = *pSrcByte;
pSrcByte++;
pByteR++;
}
for (int k = 0; k < 3; k++)
{
if((destw < scrw)&&(desth < scrh))
ShrinkImage (pSrcByteRGB + scrw * scrh *k, pDestByteRGB + destw * desth *k, scrw, scrh, destw, desth);
else //Magnify the image
MagnifyImage(pSrcByteRGB + scrw * scrh *k, pDestByteRGB + destw * desth *k, scrw, scrh, destw, desth);
}
pByteB = pDestByteRGB;
pByteG = pDestByteRGB + destw * desth;
pByteR = pByteG + destw * desth;
BYTE * pDestByte = m_pData;
for (i = 0; i < destw; i++)
for (int j = 0; j < desth; j++)
{
*pDestByte = *pByteB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -