📄 imageprocessors.cpp
字号:
for (int nY = 0; nY < sizeSrc.cy; nY++)
{
if (nX == 0 || nX == sizeSrc.cx - 1 || nY == 0 || nY == sizeSrc.cy - 1)
{
pDestPixels[nY * sizeDest.cx + nX] = pSrcPixels[nY * sizeSrc.cx + nX];
}
else
{
RGBX* pRGBDest = &pDestPixels[nY * sizeDest.cx + nX];
RGBX* pRGBSrc = &pSrcPixels[nY * sizeDest.cx + nX];
if (crMask == -1 || !(crMask == *pRGBSrc))
{
double dRed = 0, dGreen = 0, dBlue = 0;
int nSubCount = 0;
for (int nSubX = nX - 1; nSubX <= nX + 1; nSubX++)
{
for (int nSubY = nY - 1; nSubY <= nY + 1; nSubY++)
{
RGBX* pRGBSub = &pSrcPixels[nSubY * sizeSrc.cx + nSubX];
double dVMask = dMask[nSubCount];
if (dVMask != 0)
{
dRed += pRGBSub->btRed * dVMask;
dGreen += pRGBSub->btGreen * dVMask;
dBlue += pRGBSub->btBlue * dVMask;
}
nSubCount++;
}
}
dRed = min(255, dRed + 128);
dGreen = min(255, dGreen + 128);
dBlue = min(255, dBlue + 128);
dRed = max(0, dRed);
dGreen = max(0, dGreen);
dBlue = max(0, dBlue);
pRGBDest->btRed = (BYTE)dRed;
pRGBDest->btGreen = (BYTE)dGreen;
pRGBDest->btBlue = (BYTE)dBlue;
}
else
{
*pRGBDest = *pRGBSrc;
}
}
}
}
return TRUE;
}
////////
CImageResizer::CImageResizer(double dFactor) : m_dFactor(dFactor)
{
ASSERT (m_dFactor > 0);
if (m_dFactor > 1)
m_bWeightingEnabled = TRUE;
}
CImageResizer::~CImageResizer()
{
}
CSize CImageResizer::CalcDestSize(CSize sizeSrc)
{
return CSize((int)(sizeSrc.cx * m_dFactor), (int)(sizeSrc.cy * m_dFactor));
}
BOOL CImageResizer::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest,
COLORREF /*crMask*/)
{
BOOL bRes = TRUE;
if (m_dFactor <= 0)
return FALSE;
if (m_dFactor == 1)
bRes = C32BitImageProcessor::ProcessPixels(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
else if (m_dFactor > 1)
bRes = Enlarge(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
else
bRes = Shrink(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
return TRUE;
}
BOOL CImageResizer::Enlarge(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest)
{
ASSERT (m_dFactor > 1);
if (m_dFactor <= 1)
return FALSE;
double dFactor = 1 / m_dFactor;
double dXSrc = 0;
for (int nX = 0; nX < sizeDest.cx; nX++)
{
double dYSrc = 0;
for (int nY = 0; nY < sizeDest.cy; nY++)
{
CalcWeightedColor(pSrcPixels, sizeSrc, dXSrc, dYSrc, pDestPixels[nY * sizeDest.cx + nX]);
dYSrc += dFactor; // next dest pixel in source coords
}
dXSrc += dFactor; // next dest pixel in source coords
}
return TRUE;
}
BOOL CImageResizer::Shrink(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest)
{
ASSERT (m_dFactor < 1 && m_dFactor > 0);
if (m_dFactor >= 1 || m_dFactor <= 0)
return FALSE;
double dFactor = 1 / m_dFactor;
double dXEnd = -dFactor / 2;
int nXStart, nXEnd = -1;
for (int nX = 0; nX < sizeDest.cx; nX++)
{
int nYStart, nYEnd = -1;
double dYEnd = -dFactor / 2;
nXStart = nXEnd + 1;
dXEnd += dFactor;
nXEnd = min(sizeSrc.cx - 1, (int)dXEnd + 1);
if (nXStart > nXEnd)
continue;
for (int nY = 0; nY < sizeDest.cy; nY++)
{
nYStart = nYEnd + 1;
dYEnd += dFactor;
nYEnd = min(sizeSrc.cy - 1, (int)dYEnd + 1);
if (nYStart > nYEnd)
continue;
int nCount = 0, nRed = 0, nGreen = 0, nBlue = 0;
// average the pixels over the range
for (int nXSub = nXStart; nXSub <= nXEnd; nXSub++)
{
for (int nYSub = nYStart; nYSub <= nYEnd; nYSub++)
{
RGBX* pRGBSrc = &pSrcPixels[nYSub * sizeSrc.cx + nXSub];
nRed += pRGBSrc->btRed;
nGreen += pRGBSrc->btGreen;
nBlue += pRGBSrc->btBlue;
nCount++;
}
}
RGBX* pRGBDest = &pDestPixels[nY * sizeDest.cx + nX];
pRGBDest->btRed = (BYTE)(nRed / nCount);
pRGBDest->btGreen = (BYTE)(nGreen / nCount);
pRGBDest->btBlue = (BYTE)(nBlue / nCount);
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
CImageNegator::CImageNegator()
{
}
CImageNegator::~CImageNegator()
{
}
BOOL CImageNegator::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize /*sizeDest*/,
COLORREF /*crMask*/)
{
for (int nX = 0; nX < sizeSrc.cx; nX++)
{
for (int nY = 0; nY < sizeSrc.cy; nY++)
{
RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX];
RGBX* pRGBDest = &pDestPixels[nY * sizeSrc.cx + nX];
pRGBDest->btRed = (BYTE)(255 - pRGBSrc->btRed);
pRGBDest->btGreen = (BYTE)(255 - pRGBSrc->btGreen);
pRGBDest->btBlue = (BYTE)(255 - pRGBSrc->btBlue);
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
CImageFlipper::CImageFlipper(BOOL bHorz, BOOL bVert) : m_bHorz(bHorz), m_bVert(bVert)
{
}
CImageFlipper::~CImageFlipper()
{
}
BOOL CImageFlipper::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest,
COLORREF /*crMask*/)
{
for (int nX = 0; nX < sizeSrc.cx; nX++)
{
int nDestX = m_bHorz ? sizeDest.cx - nX - 1 : nX;
for (int nY = 0; nY < sizeSrc.cy; nY++)
{
RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX];
int nDestY = m_bVert ? sizeDest.cy - nY - 1 : nY;
RGBX* pRGBDest = &pDestPixels[nDestY * sizeDest.cx + nDestX];
*pRGBDest = *pRGBSrc;
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
CColorReplacer::CColorReplacer(COLORREF crFrom, COLORREF crTo) : m_crFrom(crFrom), m_crTo(crTo)
{
}
CColorReplacer::~CColorReplacer()
{
}
BOOL CColorReplacer::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest,
COLORREF /*crMask*/)
{
BOOL bRes = TRUE;
if (m_crFrom == m_crTo)
bRes = C32BitImageProcessor::ProcessPixels(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
else
{
RGBX rgbFrom(m_crFrom), rgbTo(m_crTo);
for (int nX = 0; nX < sizeSrc.cx; nX++)
{
for (int nY = 0; nY < sizeSrc.cy; nY++)
{
RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX];
RGBX* pRGBDest = &pDestPixels[nY * sizeDest.cx + nX];
if (*pRGBSrc == rgbFrom)
*pRGBDest = rgbTo;
else
*pRGBDest = *pRGBSrc;
}
}
}
return bRes;
}
//////////////////////////////////////////////////////////////////////
CImageColorizer::CImageColorizer(COLORREF color) : m_color(color)
{
}
CImageColorizer::~CImageColorizer()
{
}
BOOL CImageColorizer::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest,
COLORREF /*crMask*/)
{
BOOL bRes = TRUE;
if (m_color == 0)
FillMemory(pDestPixels, sizeDest.cx * sizeDest.cy * 4, 0);
else if (m_color == RGB(255, 255, 255))
return CImageGrayer::ProcessPixels(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
else
{
RGBX rgb(m_color);
int nColorLum = rgb.Luminance();
if (!nColorLum)
FillMemory(pDestPixels, sizeDest.cx * sizeDest.cy * 4, 0);
else
{
for (int nX = 0; nX < sizeSrc.cx; nX++)
{
for (int nY = 0; nY < sizeSrc.cy; nY++)
{
RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX];
RGBX* pRGBDest = &pDestPixels[nY * sizeDest.cx + nX];
pRGBDest->MakeGray(*pRGBSrc);
int nPixelLum = pRGBDest->Luminance();
pRGBDest->btRed = (BYTE)min(255, MulDiv((int)rgb.btRed, nPixelLum, nColorLum));
pRGBDest->btGreen = (BYTE)min(255, MulDiv((int)rgb.btGreen, nPixelLum, nColorLum));
pRGBDest->btBlue = (BYTE)min(255, MulDiv((int)rgb.btBlue, nPixelLum, nColorLum));
}
}
}
}
return bRes;
}
//////////////////////////////////////////////////////////////////////
CImageTinter::CImageTinter(COLORREF color, int nAmount) : m_color(color)
{
m_nAmount = max(-100, min(100, nAmount));
}
CImageTinter::~CImageTinter()
{
}
BOOL CImageTinter::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest,
COLORREF crMask)
{
BOOL bRes = TRUE;
if (!m_nAmount)
bRes = C32BitImageProcessor::ProcessPixels(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
else
{
RGBX rgb(m_color);
float fFactor = m_nAmount / 100.0f;
for (int nX = 0; nX < sizeSrc.cx; nX++)
{
for (int nY = 0; nY < sizeSrc.cy; nY++)
{
RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX];
RGBX* pRGBDest = &pDestPixels[nY * sizeDest.cx + nX];
if (crMask == -1 || !(crMask == *pRGBSrc))
{
pRGBDest->btRed = (BYTE)min(255, max(0, (int)(pRGBSrc->btRed + (int)(rgb.btRed * fFactor))));
pRGBDest->btGreen = (BYTE)min(255, max(0, (int)(pRGBSrc->btGreen + (int)(rgb.btGreen * fFactor))));
pRGBDest->btBlue = (BYTE)min(255, max(0, (int)(pRGBSrc->btBlue + (int)(rgb.btBlue * fFactor))));
}
else
*pRGBDest = *pRGBSrc;
}
}
}
return bRes;
}
//////////////////////////////////////////////////////////////////////
CImageContraster::CImageContraster(int nAmount)
{
m_nAmount = max(-100, min(200, nAmount));
}
CImageContraster::~CImageContraster()
{
}
BOOL CImageContraster::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest,
COLORREF crMask)
{
BOOL bRes = TRUE;
if (!m_nAmount)
bRes = C32BitImageProcessor::ProcessPixels(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
else
{
float fFactor = 1.0f + m_nAmount / 100.0f;
for (int nX = 0; nX < sizeSrc.cx; nX++)
{
for (int nY = 0; nY < sizeSrc.cy; nY++)
{
RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX];
RGBX* pRGBDest = &pDestPixels[nY * sizeDest.cx + nX];
if (crMask == -1 || !(crMask == *pRGBSrc))
{
pRGBDest->btRed = (BYTE)max(0, min(255, (int)((pRGBSrc->btRed - 128) * fFactor) + 128));
pRGBDest->btGreen = (BYTE)max(0, min(255, (int)((pRGBSrc->btGreen - 128) * fFactor) + 128));
pRGBDest->btBlue = (BYTE)max(0, min(255, (int)((pRGBSrc->btBlue - 128) * fFactor) + 128));
}
else
*pRGBDest = *pRGBSrc;
}
}
}
return bRes;
}
////////////////////////////////////////////////////////////////////
// color mapping
struct COLORMAPPING
{
COLORREF color;
UINT nSysColor;
};
static COLORMAPPING COLORMAPPINGS[] =
{
{ 0x000000, COLOR_BTNTEXT }, // black
{ 0x808080, COLOR_BTNSHADOW }, // dark gray
{ 0xC0C0C0, COLOR_BTNFACE }, // bright gray
{ 0xFFFFFF, COLOR_BTNHIGHLIGHT } // white
};
BOOL CImageSysColorMapper::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize sizeDest,
COLORREF /*crMask*/)
{
static int NUMCOLORMAPS = sizeof(COLORMAPPINGS) / sizeof(COLORMAPPING);
for (int nMap = 0; nMap < NUMCOLORMAPS; nMap++)
{
CColorReplacer cr(COLORMAPPINGS[nMap].color, GetSysColor(COLORMAPPINGS[nMap].nSysColor));
cr.ProcessPixels(pSrcPixels, sizeSrc, pDestPixels, sizeDest);
// switch source and dest for next iteration provided its not the last
if (nMap < NUMCOLORMAPS - 1)
{
RGBX* pTemp = pSrcPixels;
pSrcPixels = pDestPixels;
pDestPixels = pTemp;
}
}
return TRUE;
}
////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -