📄 cimageb.cpp
字号:
/*
* File: cimageb.cc
* Purpose: Platform Independent Image Base Class (Windows version)
* Author: Alejandro Aguilar Sierra
* Created: 1995
* Copyright: (c) 1995 Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
*/
#include "stdafx.h"
#include <windowsx.h>
#include "cmap.h"
#include "cimageb.h"
#include "dibutils.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
void
CImageImpl::Create(int width, int height, int depth, int colortype)
{
Width = width; Height = height; Depth = depth;
ColorType = (colortype>=0) ? colortype: ((Depth>8) ? COLORTYPE_COLOR: 0);
if (lpbi)
GlobalFreePtr(lpbi);
RawImage = 0;
if (imagePalette)
delete imagePalette;
imagePalette = 0;
if (lpbi = DibCreate(Depth, Width, Height)) {
RawImage = (ImagePointerType)DibPtr(lpbi);
EffWidth = (long)(((long)Width*Depth + 31) / 32) * 4;
}
}
CImageImpl::~CImageImpl ( )
{
if (lpbi) {
GlobalFreePtr(lpbi);
delete imagePalette;
}
}
int CImageImpl::GetIndex(int x, int y)
{
if (!Inside(x, y) || (Depth>8)) return -1;
ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3);
int index = (int)(*ImagePointer);
return index;
}
BOOL CImageImpl::GetRGB(int x, int y, byte* r, byte* g, byte* b)
{
if (!Inside(x, y)) return FALSE;
if (imagePalette) {
return imagePalette->GetRGB(GetIndex(x, y), r, g, b);
/* PALETTEENTRY entry;
::GetPaletteEntries((HPALETTE) (*imagePalette), GetIndex(x, y), 1, &entry);
*r = entry.peRed;
*g = entry.peGreen;
*b = entry.peBlue; */
} else {
ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3);
*b = ImagePointer[0];
*g = ImagePointer[1];
*r = ImagePointer[2];
}
return TRUE;
}
BOOL CImageImpl::SetIndex(int x, int y, int index)
{
if (!Inside(x, y) || (Depth>8)) return FALSE;
ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3);
*ImagePointer = index;
return TRUE;
}
BOOL CImageImpl::SetRGB(int x, int y, byte r, byte g, byte b)
{
if (!Inside(x, y)) return FALSE;
if (ColorType & COLORTYPE_PALETTE)
{
if (!imagePalette) return FALSE;
SetIndex(x, y, imagePalette->GetPixel(r, g, b));
} else {
ImagePointerType ImagePointer = RawImage + EffWidth*y + (x*Depth >> 3);
ImagePointer[0] = b;
ImagePointer[1] = g;
ImagePointer[2] = r;
}
return TRUE;
}
BOOL CImageImpl::SetPalette(CImagePalette* colourmap)
{
if (!colourmap)
return FALSE;
ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR);
imagePalette = colourmap;
return DibSetUsage(lpbi, (HPALETTE) (*imagePalette), CIMAGE_COLORS );
}
BOOL
CImageImpl::SetPalette(int n, byte *r, byte *g, byte *b)
{
imagePalette = new CImagePalette();
if (!imagePalette)
return FALSE;
if (!g) g = r;
if (!b) b = g;
imagePalette->Create(n, r, g, b);
ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR);
return DibSetUsage(lpbi, (HPALETTE) (*imagePalette), CIMAGE_COLORS );
}
BOOL
CImageImpl::SetPalette(int n, rgb_color_struct *rgb_struct)
{
if (imagePalette)
AfxMessageBox("CImageImpl::imagePalette already exists!");
imagePalette = new CImagePalette();
if (!imagePalette)
return FALSE;
byte r[256], g[256], b[256];
for(int i=0; i<n; i++)
{
r[i] = rgb_struct[i].red;
g[i] = rgb_struct[i].green;
b[i] = rgb_struct[i].blue;
}
imagePalette->Create(n, r, g, b);
ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR);
return DibSetUsage(lpbi, (HPALETTE) (*imagePalette), CIMAGE_COLORS );
}
BOOL CImageImpl::Draw(CDC *cdc, int x, int y, int dx, int dy, int xs, int ys)
{
if (lpbi)
{
HDC dc = cdc->GetSafeHdc();
if (dc) {
::RealizePalette(dc);
if (dx==-1) dx = GetWidth();
if (dy==-1) dy = GetHeight();
SetDIBitsToDevice(dc, x, y, dx, dy, xs, 0, ys, dy,
RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS );
}
return TRUE;
}
else
return FALSE;
}
BOOL CImageImpl::Stretch(CDC *cdc, int xd, int yd, int dxd, int dyd,
int xs, int ys, int dxs, int dys)
{
if (lpbi)
{
HDC dc = cdc->GetSafeHdc();
if (dc) {
if (dxd==-1) dxd = GetWidth();
if (dyd==-1) dyd = GetHeight();
if (dxs==-1) dxs = Width - xs;
if (dys==-1) dys = Height - ys;
::RealizePalette(dc);
#ifdef WIN32 // Paul Shirley's patch
SetStretchBltMode(dc, COLORONCOLOR);
#else
SetStretchBltMode(dc, STRETCH_DELETESCANS);
#endif
if (bgindex == -1)
{
StretchDIBits(dc, xd, yd, dxd, dyd, xs, ys, dxs, dys,
RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS, SRCCOPY);
}
else
{
//HDC tmpdc = CreateCompatibleDC(dc);
//HBITMAP tmpbmp = CreateCompatibleBitmap(dc, dxd, dyd);
//SelectObject(tmpdc, tmpbmp);
//BitBlt(tmpdc, 0, 0, dxd, dyd, dc, xd, yd, SRCCOPY);
unsigned char* save_index = new unsigned char[Height*Width];
int black = imagePalette->GetPixel(0, 0, 0);
int white = imagePalette->GetPixel(255, 255, 255);
// Make background white and foreground black to use as mask...
int x, y;
for (y = 0; y < Height; y++)
for (x = 0; x < Width; x++)
{
long i = ((long)y*Width)+x;
save_index[i] = (unsigned char)GetIndex(x, y);
if (GetIndex(x, y) == bgindex)
SetIndex(x, y, white);
else
SetIndex(x, y, black);
}
// AND into the canvas, this will preserve the background but
// turn the foreground white...
//StretchDIBits(tmpdc, 0, 0, dxd, dyd, xs, ys, dxs, dys,
StretchDIBits(dc, xd, yd, dxd, dyd, xs, ys, dxs, dys,
RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS, SRCAND);
// Restore foreground & make background black...
for (y = 0; y < Height; y++)
for (x = 0; x < Width; x++)
{
long i = ((long)y*Width)+x;
SetIndex(x, y, save_index[i]);
if (GetIndex(x, y) == bgindex)
SetIndex(x, y, black);
}
// OR into the canvas, this will preserve the background but
// copy the foreground...
//StretchDIBits(tmpdc, 0, 0, dxd, dyd, xs, ys, dxs, dys,
StretchDIBits(dc, xd, yd, dxd, dyd, xs, ys, dxs, dys,
RawImage, (BITMAPINFO *)lpbi, CIMAGE_COLORS, SRCPAINT);
for (y = 0; y < Height; y++)
for (x = 0; x < Width; x++)
{
long i = ((long)y*Width)+x;
SetIndex(x, y, save_index[i]);
}
delete [] save_index;
//BitBlt(dc, xd, yd, dxd, dyd, tmpdc, 0, 0, SRCCOPY);
//DeleteDC(tmpdc);
//DeleteObject(tmpbmp);
}
}
return TRUE;
}
else
return FALSE;
}
void CImageImpl::TransferBits(CImageImpl *from)
{
if (lpbi)
{
GlobalFreePtr(lpbi);
lpbi = NULL;
}
if (imagePalette)
{
delete imagePalette;
imagePalette = NULL;
}
lpbi = from->lpbi;
bgindex = from->bgindex;
imagePalette = from->imagePalette;
RawImage = from->RawImage;
Width = from->Width;
Height = from->Height;
Depth = from->Depth;
ColorType = from->ColorType;
EffWidth = from->EffWidth;
from->RawImage = NULL;
from->lpbi = NULL;
from->imagePalette = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -