📄 jzimage.cpp
字号:
// JzImage.cpp: implementation of the CJzImage class.
//
//////////////////////////////////////////////////////////////////////
#include "JzImage.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CJzImage::CJzImage()
{
pScr = NULL;
pDib = NULL;
}
CJzImage::CJzImage(PSCRINFO pscr)
{
pScr = pscr;
pDib = NULL;
memset(&head,0,sizeof(BITMAPINFOHEADER));
memset(&info,0,sizeof(CXIMAGEINFO));
info.nBkgndIndex = -1;
//init default attributes
info.nQuality = 90;
}
CJzImage::~CJzImage()
{
}
////////////////////////////////////////////////////////////////////////////////
/**
* returns the pointer to the first palette index
*/
RGBQUAD* CJzImage::GetPalette() const
{
if ((pDib)&&(head.biClrUsed))
return (RGBQUAD*)((BYTE*)pDib + sizeof(BITMAPINFOHEADER));
return NULL;
}
DWORD CJzImage::GetPaletteSize()
{
return (head.biClrUsed * sizeof(RGBQUAD));
}
void CJzImage::SetPixelIndex(long x,long y,BYTE i)
{
if ((pDib==NULL)||(head.biClrUsed==0)||
(x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) return ;
if (head.biBitCount==8){
info.pImage[y*info.dwEffWidth + x]=i;
return;
} else {
BYTE pos;
BYTE* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
if (head.biBitCount==4){
pos = (BYTE)(4*(1-x%2));
*iDst &= ~(0x0F<<pos);
*iDst |= ((i & 0x0F)<<pos);
return;
} else if (head.biBitCount==1){
pos = (BYTE)(7-x%8);
*iDst &= ~(0x01<<pos);
*iDst |= ((i & 0x01)<<pos);
return;
}
}
}
long CJzImage::GetTransIndex() const
{
return info.nBkgndIndex;
}
////////////////////////////////////////////////////////////////////////////////
// CxImage
////////////////////////////////////////////////////////////////////////////////
/**
* Initialize the internal structures
*/
void CJzImage::Startup(DWORD imagetype)
{
//init pointers
pDib = NULL;
//pLayers = NULL;
//init structures
memset(&head,0,sizeof(BITMAPINFOHEADER));
memset(&info,0,sizeof(CXIMAGEINFO));
//init default attributes
info.dwType = imagetype;
//info.nQuality = 90;
//info.nAlphaMax = 255;
info.nBkgndIndex = -1;
//info.bEnabled = true;
//SetXDPI(96);
//SetYDPI(96);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sized image constructor
* \param dwWidth: width
* \param dwHeight: height
* \param wBpp: bit per pixel, can be 1, 4, 8, 24
* \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
*/
CJzImage::CJzImage(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype)
{
Startup(imagetype);
Create(dwWidth,dwHeight,wBpp,imagetype);
}
////////////////////////////////////////////////////////////////////////////////
/**
* Checks if the coordinates are inside the image
* \return true if x and y are both inside the image
*/
bool CJzImage::IsInside(long x, long y) {
return (0<=y && y<head.biHeight && 0<=x && x<head.biWidth);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
DWORD CJzImage::GetHeight() const
{
return head.biHeight;
}
////////////////////////////////////////////////////////////////////////////////
DWORD CJzImage::GetWidth() const
{
return head.biWidth;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return DWORD aligned width of the image.
*/
DWORD CJzImage::GetEffWidth() const
{
return info.dwEffWidth;
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return: 1, 4, 8, 24.
*/
WORD CJzImage::GetBpp() const
{
return head.biBitCount;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* Copies the image attributes from an existing image.
* - Works only on an empty image, and the image will be still empty.
* - <b> Use it before Create() </b>
*/
void CJzImage::CopyInfo(const CJzImage &src)
{
if (pDib==NULL) memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/**
* returns the palette dimension in byte
*/
long CJzImage::GetSize()
{
return head.biSize + head.biSizeImage + GetPaletteSize();
}
////////////////////////////////////////////////////////////////////////////////
/**
* Call this function to destroy image pixels, alpha channel, selection and sub layers.
* - Attributes are not erased, but IsValid returns false.
*
* \return true if everything is freed, false if the image is a Ghost
*/
bool CJzImage::Destroy()
{
/*
//free this only if it's valid and it's not a ghost
if (info.pGhost==NULL){
if (pLayers) {
for(long n=0; n<info.nNumLayers;n++){ delete pLayers[n]; }
free(pLayers); pLayers=0;
}
if (pSelection) {free(pSelection); pSelection=0;}
if (pAlpha) {free(pAlpha); pAlpha=0;}
*/
if (pDib) {free(pDib); pDib=0; }
return true;
// }
// return false;
}
////////////////////////////////////////////////////////////////////////////////
void* CJzImage::Create(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype)
{
// destroy the existing image (if any)
if (!Destroy())
return NULL;
// prevent further actions if width or height are not vaild <Balabasnia>
if ((dwWidth == 0) || (dwHeight == 0)){
strcpy(info.szLastError,"CxImage::Create : width and height must be greater than zero");
return NULL;
}
// Make sure bits per pixel is valid
if (wBpp <= 1) wBpp = 1;
else if (wBpp <= 4) wBpp = 4;
else if (wBpp <= 8) wBpp = 8;
else wBpp = 24;
// limit memory requirements (and also a check for bad parameters)
if (((dwWidth*dwHeight*wBpp)>>8) > CXIMAGE_MAX_MEMORY){
strcpy(info.szLastError,"CXIMAGE_MAX_MEMORY exceeded");
return NULL;
}
// set the correct bpp value
switch (wBpp){
case 1:
head.biClrUsed = 2; break;
case 4:
head.biClrUsed = 16; break;
case 8:
head.biClrUsed = 256; break;
default:
head.biClrUsed = 0;
}
//set the common image informations
info.dwEffWidth = ((((wBpp * dwWidth) + 31) / 32) * 4);
info.dwType = imagetype;
// initialize BITMAPINFOHEADER
head.biSize = sizeof(BITMAPINFOHEADER); //<ralphw>
head.biWidth = dwWidth; // fill in width from parameter
head.biHeight = dwHeight; // fill in height from parameter
head.biPlanes = 1; // must be 1
head.biBitCount = (WORD)wBpp; // from parameter
head.biCompression = BI_RGB;
head.biSizeImage = info.dwEffWidth * dwHeight;
// head.biXPelsPerMeter = 0; See SetXDPI
// head.biYPelsPerMeter = 0; See SetYDPI
head.biClrImportant = 0;
pDib = malloc(GetSize()); // alloc memory block to store our bitmap
//printf("===== create image: %x w: %d h: %d size: %d \n", pDib, dwWidth, dwHeight, GetSize() );
if (!pDib){
strcpy(info.szLastError,"CxImage::Create can't allocate memory");
printf(" =====%d======= pDlib error !===========\n", GetSize());
return NULL;
}
//clear the palette
RGBQUAD* pal=GetPalette();
if (pal) memset(pal,0,GetPaletteSize());
//Destroy the existing selection
/*
#if CXIMAGE_SUPPORT_SELECTION
if (pSelection) SelectionDelete();
#endif //CXIMAGE_SUPPORT_SELECTION
*/
//Destroy the existing alpha channel
/*
#if CXIMAGE_SUPPORT_ALPHA
if (pAlpha) AlphaDelete();
#endif //CXIMAGE_SUPPORT_ALPHA
*/
// use our bitmap info structure to fill in first part of
// our DIB with the BITMAPINFOHEADER
BITMAPINFOHEADER* lpbi;
lpbi = (BITMAPINFOHEADER*)(pDib);
*lpbi = head;
info.pImage=GetBits();
return pDib; //return handle to the DIB
}
////////////////////////////////////////////////////////////////////////////////
void CJzImage::Clear(BYTE bval)
{
if (pDib == 0) return;
if (GetBpp() == 1){
if (bval > 0) bval = 255;
}
if (GetBpp() == 4){
bval = (BYTE)(17*(0x0F & bval));
}
memset(info.pImage,bval,head.biSizeImage);
}
////////////////////////////////////////////////////////////////////////////////
/**
* \return original image format
* \sa ENUM_CXIMAGE_FORMATS.
*/
DWORD CJzImage::GetType() const
{
return info.dwType;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Transfers the image from an existing source image. The source becomes empty.
* \return true if everything is ok
*/
bool CJzImage::Transfer(CJzImage &from)
{
if (!Destroy())
return false;
memcpy(&head,&from.head,sizeof(BITMAPINFOHEADER));
memcpy(&info,&from.info,sizeof(CXIMAGEINFO));
pDib = from.pDib;
//pAlpha = from.pAlpha;
memset(&from.head,0,sizeof(BITMAPINFOHEADER));
memset(&from.info,0,sizeof(CXIMAGEINFO));
from.pDib = NULL;//from.pAlpha = NULL;
//from.pLayers = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the color used for transparency with 24 bpp images.
* You must call SetTransIndex(0) to enable the effect, SetTransIndex(-1) to disable it.
*/
void CJzImage::SetTransColor(RGBQUAD rgb)
{
rgb.rgbReserved=0;
info.nBkgndColor = rgb;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Sets the index used for transparency with 1, 4 and 8 bpp images. Set to -1 to remove the effect.
*/
void CJzImage::SetTransIndex(long idx)
{
info.nBkgndIndex = idx;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Returns the color of the specified index.
*/
RGBQUAD CJzImage::GetPaletteColor(BYTE idx)
{
RGBQUAD rgb = {0,0,0,0};
if ((pDib)&&(head.biClrUsed)){
BYTE* iDst = (BYTE*)(pDib) + sizeof(BITMAPINFOHEADER);
if (idx<head.biClrUsed){
long ldx=idx*sizeof(RGBQUAD);
rgb.rgbBlue = iDst[ldx++];
rgb.rgbGreen=iDst[ldx++];
rgb.rgbRed =iDst[ldx++];
rgb.rgbReserved = iDst[ldx];
}
}
return rgb;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -