📄 ximage.cpp
字号:
#include "StdAfx.h"
#include "ximage.h"
CXImage::CXImage(void)
: m_b555Mode(false)
, m_pAreaIndex(NULL)
, m_pAreaIndex555(NULL)
, m_pArea(NULL)
, m_pAreaBuf(NULL)
{
}
CXImage::~CXImage(void)
{
EndIncise();
}
// 初始化(分配空间和计算查找表)
// 参数:图像的宽和高,以及分割所需参数
bool CXImage::InitIncise(unsigned int width, unsigned int height, SHSVRGB::INCISECOLOR clr, bool b555Mode)
{
EndIncise();
m_b555Mode= b555Mode;
try
{
if (m_b555Mode)
m_pAreaIndex555= new CAreaIndex555(clr);
else
m_pAreaIndex= new CAreaIndex(clr);
m_pArea= new CImageBuffer<unsigned char>(width, height);
m_pAreaBuf= new CImageBuffer<unsigned char>(width, height);
return true;
}
catch(...)
{
delete m_pAreaIndex; m_pAreaIndex= NULL;
delete m_pAreaIndex555; m_pAreaIndex555= NULL;
delete m_pArea; m_pArea= NULL;
delete m_pAreaBuf; m_pAreaBuf= NULL;
return false;
}
}
// 释放空间
void CXImage::EndIncise(void)
{
delete m_pAreaIndex; m_pAreaIndex= NULL;
delete m_pAreaIndex555; m_pAreaIndex555= NULL;
delete m_pArea; m_pArea= NULL;
delete m_pAreaBuf; m_pAreaBuf= NULL;
}
// 颜色切分
void CXImage::InciseImage(LPI_DXSURFACE ps)
{
}
void CXImage::InciseImage(const BITMAPINFOHEADER * const pBMPHdr)
{
long lPitch= 2 * pBMPHdr->biWidth;
lPitch+= (4 - lPitch % 4) % 4;
for (unsigned int y= 0; y < pBMPHdr->biHeight; y++)
{
unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(pBMPHdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
unsigned char *pdst= m_pArea->m_pScanLine[y];
for (unsigned int x= 0; x < pBMPHdr->biWidth; x++)
{
m_pArea->m_pScanLine[y][x]= m_pAreaIndex555->m_Index[psrc[x]];
}
}
}
void CXImage::InciseImageASM(const BITMAPINFOHEADER * const pBMPHdr)
{
long lPitch= 2 * pBMPHdr->biWidth;
lPitch+= (4 - lPitch % 4) % 4;
unsigned int wid= pBMPHdr->biWidth;
unsigned int hei= pBMPHdr->biHeight;
unsigned char *pindex= m_pAreaIndex555->m_Index;
for (unsigned int y= 0; y < hei; y++)
{
unsigned short *psrc= reinterpret_cast<unsigned short *>(reinterpret_cast<unsigned char *>(const_cast<BITMAPINFOHEADER *>(pBMPHdr)) + sizeof(BITMAPINFOHEADER) + y * lPitch);
unsigned char *pdst= m_pArea->m_pScanLine[y];
__asm
{
mov esi, psrc;
mov edi, pdst;
mov edx, pindex;
xor eax, eax;
xor ebx, ebx;
loop_x:
mov bx, [esi + eax * 2]; // psrc[x] => bx
mov bl, [edx + ebx]; // m_Index[psrc[x]] => bl;
mov [edi + eax], bl; // bl => m_pScanLine[y][x]
inc eax;
cmp eax, wid;
jnz loop_x;
}
}
}
// 开运算
void CXImage::OperatorOpen(void)
{
this->DilationASM(m_pArea, m_pAreaBuf);
this->ErosionASM(m_pAreaBuf, m_pArea);
}
// 闭运算
void CXImage::OperatorClose(void)
{
this->ErosionASM(m_pArea, m_pAreaBuf);
this->DilationASM(m_pAreaBuf, m_pArea);
}
// 清除边框
void CXImage::ClearBorder(CImageBuffer<unsigned char>* pSrc)
{
for (unsigned int y= 0; y < pSrc->m_height; y++)
{
pSrc->m_pScanLine[y][0]= 0;
pSrc->m_pScanLine[y][pSrc->m_width - 1]= 0;
}
for (unsigned int x= 0; x < pSrc->m_width; x++)
{
pSrc->m_pScanLine[0][x]= 0;
pSrc->m_pScanLine[pSrc->m_height - 1][x]= 0;
}
}
void CXImage::ClearBorderASM(CImageBuffer<unsigned char>* pSrc)
{
unsigned char **psl= pSrc->m_pScanLine;
unsigned int hei= pSrc->m_height;
unsigned int wid= pSrc->m_width;
__asm
{
mov eax, 0;
mov ebx, wid;
dec ebx; // wid - 1 => ebx
mov ecx, hei;
mov esi, psl;
loop_y:
mov edi, [esi + eax * 4]; // (unsigned char *)edi = psl[y]
mov [edi], 0;
mov [edi + ebx], 0;
inc eax;
cmp eax, ecx;
jnz loop_y;
}
__asm
{
mov eax, 0;
mov ebx, hei;
dec ebx; // hei - 1 => ebx;
mov ecx, wid;
mov esi, psl;
loop_x:
mov edi, [esi]; // (unsigned char *)edi = psl[0]
mov [edi + eax], 0;
mov edi, [esi + ebx * 4]; // (unsigned char *)edi = psl[height - 1]
mov [edi + eax], 0;
inc eax;
cmp eax, ecx;
jnz loop_x;
}
}
// 膨胀
void CXImage::Dilation(CImageBuffer<unsigned char>* pSrc, CImageBuffer<unsigned char>* pDest)
{
ClearBorder(pDest);
for (unsigned int y= 1; y < pSrc->m_height - 1; y++)
{
for (unsigned int x= 1; x < pSrc->m_width - 1; x++)
{
// 计算空点数目
int k= pSrc->m_pScanLine[y - 1][x - 1] +
pSrc->m_pScanLine[y - 1][x] +
pSrc->m_pScanLine[y - 1][x + 1] +
pSrc->m_pScanLine[y][x - 1] +
pSrc->m_pScanLine[y][x + 1] +
pSrc->m_pScanLine[y + 1][x - 1] +
pSrc->m_pScanLine[y + 1][x] +
pSrc->m_pScanLine[y + 1][x + 1];
k= 8 - k;
if (k < 4)
pDest->m_pScanLine[y][x]= 1;
else
pDest->m_pScanLine[y][x]= pSrc->m_pScanLine[y][x];
}
}
}
void CXImage::DilationASM(CImageBuffer<unsigned char>* pSrc, CImageBuffer<unsigned char>* pDest)
{
ClearBorderASM(pDest);
unsigned int hei= pSrc->m_height - 1;
unsigned int wid= pSrc->m_width - 1;
for (unsigned int y= 1; y < hei; y++)
{
unsigned char *pSrc1= pSrc->m_pScanLine[y - 1];
unsigned char *pSrc2= pSrc->m_pScanLine[y];
unsigned char *pSrc3= pSrc->m_pScanLine[y + 1];
unsigned char *pDst= pDest->m_pScanLine[y];
__asm
{
mov eax, 1;
mov esi, pSrc1; // m_pScanLine[y - 1];
mov edi, pSrc2; // m_pScanLine[y];
mov ebx, pSrc3; // m_pScanLine[y + 1];
mov ecx, pDst;
loop_x:
inc ecx;
dec eax; // x - 1 => eax;
mov dl, [esi + eax]; // [y - 1][x - 1];
add dl, [edi + eax]; // [y][x - 1];
add dl, [ebx + eax]; // [y + 1][x - 1];
inc eax; // x => eax;
add dl, [esi + eax]; // [y - 1][x];
add dl, [ebx + eax]; // [y + 1][x];
mov dh, [edi + eax]; // [y][x] => dh;
inc eax; // x + 1 => eax;
add dl, [esi + eax]; // [y - 1][x + 1];
add dl, [edi + eax]; // [y][x + 1];
add dl, [ebx + eax]; // [y + 1][x + 1];
// now none zero point number in dl
mov [ecx], dh;
cmp dl, 4;
jb no_draw;
mov [ecx], 1;
no_draw:
cmp eax, wid;
jnz loop_x;
}
}
}
// 腐蚀
void CXImage::Erosion(CImageBuffer<unsigned char>* pSrc, CImageBuffer<unsigned char>* pDest)
{
ClearBorder(pDest);
for (unsigned int y= 1; y < pSrc->m_height - 1; y++)
{
for (unsigned int x= 1; x < pSrc->m_width - 1; x++)
{
// 计算像点数目
int k= pSrc->m_pScanLine[y - 1][x - 1] +
pSrc->m_pScanLine[y - 1][x] +
pSrc->m_pScanLine[y - 1][x + 1] +
pSrc->m_pScanLine[y][x - 1] +
pSrc->m_pScanLine[y][x + 1] +
pSrc->m_pScanLine[y + 1][x - 1] +
pSrc->m_pScanLine[y + 1][x] +
pSrc->m_pScanLine[y + 1][x + 1];
if (k < 4)
pDest->m_pScanLine[y][x]= 0;
else
pDest->m_pScanLine[y][x]= pSrc->m_pScanLine[y][x];
}
}
}
void CXImage::ErosionASM(CImageBuffer<unsigned char>* pSrc, CImageBuffer<unsigned char>* pDest)
{
ClearBorderASM(pDest);
unsigned int hei= pSrc->m_height - 1;
unsigned int wid= pSrc->m_width - 1;
for (unsigned int y= 1; y < hei; y++)
{
unsigned char *pSrc1= pSrc->m_pScanLine[y - 1];
unsigned char *pSrc2= pSrc->m_pScanLine[y];
unsigned char *pSrc3= pSrc->m_pScanLine[y + 1];
unsigned char *pDst= pDest->m_pScanLine[y];
__asm
{
mov eax, 1;
mov esi, pSrc1; // m_pScanLine[y - 1];
mov edi, pSrc2; // m_pScanLine[y];
mov ebx, pSrc3; // m_pScanLine[y + 1];
mov ecx, pDst;
loop_x:
inc ecx;
dec eax; // x - 1 => eax;
mov dl, [esi + eax]; // [y - 1][x - 1];
add dl, [edi + eax]; // [y][x - 1];
add dl, [ebx + eax]; // [y + 1][x - 1];
inc eax; // x => eax;
add dl, [esi + eax]; // [y - 1][x];
add dl, [ebx + eax]; // [y + 1][x];
mov dh, [edi + eax]; // [y][x] => dh;
inc eax; // x + 1 => eax;
add dl, [esi + eax]; // [y - 1][x + 1];
add dl, [edi + eax]; // [y][x + 1];
add dl, [ebx + eax]; // [y + 1][x + 1];
// now none zero point number in dl
mov [ecx], 0;
cmp dl, 4;
jb no_draw;
mov [ecx], dh;
no_draw:
cmp eax, wid;
jnz loop_x;
}
}
}
// 将二值图像转换为DS图像
void CXImage::ConvertOutDS(LPI_DXSURFACE ps)
{
LPI_BASICGRAPHIC pbg= ps->GetGraphic();
pbg->BeginPaint();
for (unsigned int y= 0; y < m_pArea->m_height; y++)
{
for (unsigned int x= 0; x < m_pArea->m_width; x++)
{
if (m_pArea->m_pScanLine[y][x])
pbg->SetPixelV(x, y, 0x00FF0000);
else
pbg->SetPixelV(x, y, 0x00000000);
}
}
pbg->EndPaint();
}
void CXImage::ConvertOutDSASM(LPI_DXSURFACE ps)
{
IMAGEMEMORY img;
ps->LockImage(&img);
unsigned int hei= m_pArea->m_height;
unsigned int wid= m_pArea->m_width;
if (img.bitcount == 16)
{
for (unsigned int y= 0; y < hei; y++)
{
unsigned char *pSrc= m_pArea->m_pScanLine[y];
unsigned short *pDst= reinterpret_cast<unsigned short *>(img.pMemory + y * img.lPitch);
__asm
{
mov eax, 0;
mov esi, pSrc;
mov edi, pDst;
mov cx, 0xF800;
mov dx, 0x0000;
loop_x_16:
mov [edi], dx;
mov bl, [esi];
cmp bl, 0;
jz nodraw_16;
draw_16:
mov [edi], cx;
nodraw_16:
inc esi;
add edi, 2;
inc eax;
cmp eax, wid;
jnz loop_x_16;
}
// for (unsigned int x= 0; x < wid; x++)
// {
// if (pSrc[x])
// (*pDst++)= 0xF800;
// else
// (*pDst++)= 0x0000;
// }
}
}
else if (img.bitcount == 32)
{
for (unsigned int y= 0; y < hei; y++)
{
unsigned char *pSrc= m_pArea->m_pScanLine[y];
unsigned int *pDst= reinterpret_cast<unsigned int *>(img.pMemory + y * img.lPitch);
__asm
{
mov eax, 0;
mov esi, pSrc;
mov edi, pDst;
mov ecx, 0xFFFF0000;
mov edx, 0x00000000;
loop_x_32:
mov [edi], edx;
mov bl, [esi];
cmp bl, 0;
jz nodraw_32;
draw_32:
mov [edi], ecx;
nodraw_32:
inc esi;
add edi, 4;
inc eax;
cmp eax, wid;
jnz loop_x_32;
}
// for (unsigned int x= 0; x < wid; x++)
// {
// if (pSrc[x])
// (*pDst++)= 0xFFFF0000;
// else
// (*pDst++)= 0xFF000000;
// }
}
}
ps->UnlockImage();
}
// 获取缓冲
CImageBuffer<unsigned char> *CXImage::GetImageBuffer(CImageBuffer<unsigned char> *pDst)
{
for (unsigned int y= 0; y < m_pArea->m_height; y++)
{
for (unsigned int x= 0; x < m_pArea->m_width; x++)
{
pDst->m_pScanLine[y][x]= m_pArea->m_pScanLine[y][x];
}
}
return pDst;
}
CImageBuffer<unsigned char> *CXImage::GetImageBufferASM(CImageBuffer<unsigned char> *pDst)
{
unsigned int hei= m_pArea->m_height;
unsigned int wid= m_pArea->m_width;
for (unsigned int y= 0; y < hei; y++)
{
memcpy(pDst->m_pScanLine[y], m_pArea->m_pScanLine[y], wid);
}
return pDst;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -