📄 pixelprocessorbase.h
字号:
/*
* Copyright (C) =USTC= Fu Li
*
* Author : Fu Li
* Create : 2005-7-29
* Home : http://www.crazy-bit.com/
* Mail : crazybit@263.net
* History :
*/
#ifndef __FOO_PIXEL_PROCESSOR_BASE__2005_07_29__H__
#define __FOO_PIXEL_PROCESSOR_BASE__2005_07_29__H__
#include "../ObjImage.h"
#include "../FColor.h"
//class FCInterface_PixelProcess ;
class FCSinglePixelProcessBase ;
class FCPixelGrayscale ; // gray scale (>=24 bit)
class FCPixelFillColor ; // Fill color (>=24 bit)
class FCPixelHueSaturation ; // hue saturation (>=24 bit)
class FCPixelGradientBase ; // base class of gradient fill (>=24 bit)
class FCPixelGradientLine ; // gradient fill linear (>=24 bit)
class FCPixelGradientBiLine ; // gradient fill bilinear (>=24 bit)
class FCPixelGradientConicalSym ; // gradient fill symmetric conical (>=24 bit)
class FCPixelGradientConicalASym ; // gradient fill Anti-symmetric conical (>=24 bit)
class FCPixelGradientRect ; // gradient fill rect (>=24 bit)
class FCPixelGradientRadial ; // gradient fill radial (>=24 bit)
class FCPixelLUTRoutine ; // LUT(look up table) routine (>=24 bit)
class FCPixelBrightness ; // adjust brightness (>=24 bit)
class FCPixelContrast ; // adjust contrast (>=24 bit)
class FCPixelGamma ; // adjust gamma (>=24 bit)
class FCPixelInvert ; // negate (>=24 bit)
class FCPixelSolarize ; // Solarize (>=24 bit)
class FCPixelPosterize ; // posterize (>=24 bit)
//=============================================================================
/**
* Base class of processor.
*/
class FCSinglePixelProcessBase : public FCInterface_PixelProcess
{
public:
FCSinglePixelProcessBase() : m_pImgOld(0) {}
virtual ~FCSinglePixelProcessBase() {if(m_pImgOld) delete m_pImgOld;}
/// whether the image can be disposed by this processor.
/// default test image's bpp >= 24
virtual BOOL ValidateColorBits (const FCObjImage* pImg)
{
return pImg->IsValidImage() && (pImg->ColorBits() >= 24) ;
}
protected:
void SetBackupImage (const FCObjImage* pImg)
{
if (pImg)
{
if (m_pImgOld)
delete m_pImgOld ;
m_pImgOld = new FCObjImage(*pImg) ;
}
}
FCObjImage* GetBackupImage() const {return m_pImgOld;}
private:
FCObjImage * m_pImgOld ; // 有些时候要保存原图后处理,在构造时new出
} ;
//=============================================================================
/// Gray scale image (>=24 bit).
class FCPixelGrayscale : public FCSinglePixelProcessBase
{
virtual void ProcessPixel (FCObjImage* pImg, int x, int y, BYTE* pPixel)
{
PCL_R(pPixel) = PCL_G(pPixel) = PCL_B(pPixel) = FCColor::GetGrayscale (pPixel) ;
}
} ;
//=============================================================================
/// Fill color (>=24 bit)
class FCPixelFillColor : public FCSinglePixelProcessBase
{
public:
/// @param nAlpha == -1, not fill alpha
FCPixelFillColor (RGBQUAD crFill, int nAlpha=-1) : m_crFill(crFill), m_nAlpha(nAlpha), m_bIsFillAlpha(false) {}
private:
virtual BOOL ValidateColorBits (const FCObjImage* pImg) ;
virtual void ProcessPixel (FCObjImage* pImg, int x, int y, BYTE* pPixel)
{
FCColor::CopyPixel (pPixel, &m_crFill, m_bIsFillAlpha ? 4 : 3) ;
}
RGBQUAD m_crFill ;
int m_nAlpha ;
bool m_bIsFillAlpha ;
};
//=============================================================================
/// Adjust image's hue-saturation (>=24 bit).
class FCPixelHueSaturation : public FCSinglePixelProcessBase
{
public:
/// param's unit is percentage (>=0).
FCPixelHueSaturation (int nPercentHue, int nPercentSat) : m_nPercentHue(FMax(0,nPercentHue)), m_nPercentSat(FMax(0,nPercentSat)) {}
private:
virtual void ProcessPixel (FCObjImage* pImg, int x, int y, BYTE* pPixel)
{
double H, L, S ;
FCColor::RGBtoHLS (pPixel, &H, &L, &S) ;
if (m_nPercentHue != 100) H = H * m_nPercentHue / 100 ;
if (m_nPercentSat != 100) S = S * m_nPercentSat / 100 ;
RGBQUAD cr = FCColor::HLStoRGB (H, L, S) ;
FCColor::CopyPixel (pPixel, &cr, 3) ;
}
int m_nPercentHue, m_nPercentSat ;
} ;
//=============================================================================
/// Base class of gradient fill (>=24 bit)
class FCPixelGradientBase : public FCSinglePixelProcessBase
{
public:
FCPixelGradientBase (RGBQUAD crStart, RGBQUAD crEnd, REPEAT_MODE nRepeat=REPEAT_NONE) : m_crStart(crStart), m_crEnd(crEnd), m_nRepeat(nRepeat) {}
virtual void ProcessPixel (FCObjImage* pImg, int x, int y, BYTE* pPixel) ;
protected:
virtual double CalculateFactor (int nX, int nY) =0 ;
private:
RGBQUAD m_crStart, m_crEnd ;
REPEAT_MODE m_nRepeat ; // type of repeat
};
//=============================================================================
/// Gradient fill linear (>=24 bit)
class FCPixelGradientLine : public FCPixelGradientBase
{
public:
FCPixelGradientLine (POINT ptStart, POINT ptEnd, RGBQUAD crStart, RGBQUAD crEnd, REPEAT_MODE nRepeat = REPEAT_NONE) : FCPixelGradientBase (crStart, crEnd, nRepeat)
{
m_ptStart = ptStart; m_ptEnd = ptEnd;
m_fDist = FHypot ((double)(m_ptStart.x-m_ptEnd.x), (double)(m_ptStart.y-m_ptEnd.y)) ;
m_fRatX = (m_ptEnd.x-m_ptStart.x) / m_fDist ;
m_fRatY = (m_ptEnd.y-m_ptStart.y) / m_fDist ;
}
protected:
virtual double CalculateFactor (int nX, int nY)
{
double rat = m_fRatX * (nX-m_ptStart.x) + m_fRatY * (nY-m_ptStart.y) ;
rat = rat / m_fDist ;
return (rat < 0.0) ? 0.0 : rat ;
}
protected:
POINT m_ptStart, m_ptEnd ; // coordinate on image
double m_fRatX, m_fRatY ;
double m_fDist ;
};
//=============================================================================
/// Gradient fill bilinear (>=24 bit)
class FCPixelGradientBiLine : public FCPixelGradientLine
{
public:
FCPixelGradientBiLine (POINT ptStart, POINT ptEnd, RGBQUAD crStart, RGBQUAD crEnd, REPEAT_MODE nRepeat = REPEAT_NONE) : FCPixelGradientLine (ptStart, ptEnd, crStart, crEnd, nRepeat) {}
protected:
virtual double CalculateFactor (int nX, int nY)
{
double rat = m_fRatX * (nX-m_ptStart.x) + m_fRatY * (nY-m_ptStart.y) ;
rat = rat / m_fDist ;
return fabs(rat) ;
}
};
//=============================================================================
/// Gradient fill symmetric conical (>=24 bit)
class FCPixelGradientConicalSym : public FCPixelGradientLine
{
public:
FCPixelGradientConicalSym (POINT ptStart, POINT ptEnd, RGBQUAD crStart, RGBQUAD crEnd, REPEAT_MODE nRepeat = REPEAT_NONE) : FCPixelGradientLine (ptStart, ptEnd, crStart, crEnd, nRepeat) {}
protected:
virtual double CalculateFactor (int nX, int nY)
{
double rat ;
double dx = nX-m_ptStart.x, dy = nY-m_ptStart.y ;
if ((dx != 0) || (dy != 0))
{
double dr = FHypot (dx, dy) ;
rat = m_fRatX * dx / dr + m_fRatY * dy / dr ;
rat = FClamp (rat, -1.0, 1.0) ;
rat = acos(rat) / LIB_PI ;
rat = FClamp (rat, 0.0, 1.0) ;
}
else
rat = 0.5 ;
return rat ;
}
};
//=============================================================================
/// Gradient fill Anti-symmetric conical (>=24 bit)
class FCPixelGradientConicalASym : public FCPixelGradientLine
{
public:
FCPixelGradientConicalASym (POINT ptStart, POINT ptEnd, RGBQUAD crStart, RGBQUAD crEnd, REPEAT_MODE nRepeat = REPEAT_NONE) : FCPixelGradientLine (ptStart, ptEnd, crStart, crEnd, nRepeat) {}
protected:
virtual double CalculateFactor (int nX, int nY)
{
double rat ;
double dx = nX-m_ptStart.x, dy = nY-m_ptStart.y ;
if ((dx != 0) || (dy != 0))
{
double ang0, ang1, ang ;
ang0 = atan2 (m_fRatX, m_fRatY) + LIB_PI ;
ang1 = atan2 (dx, dy) + LIB_PI ;
ang = ang1 - ang0 ;
if (ang < 0.0)
ang += LIB_2PI ;
rat = ang / LIB_2PI ;
rat = FClamp (rat, 0.0, 1.0) ;
}
else
rat = 0.5 ;
return rat ;
}
};
//=============================================================================
/// Gradient fill rect (>=24 bit)
class FCPixelGradientRect : public FCPixelGradientBase
{
public:
FCPixelGradientRect (RECT rcRect, RGBQUAD crStart, RGBQUAD crEnd, REPEAT_MODE nRepeat = REPEAT_NONE) : FCPixelGradientBase (crStart, crEnd, nRepeat)
{
assert (!IsRectEmpty(&rcRect)) ;
m_ptCenter.x = (rcRect.left + rcRect.right) / 2.0 ;
m_ptCenter.y = (rcRect.top + rcRect.bottom) / 2.0 ;
m_fRadiusX = RECTWIDTH(rcRect) / 2.0 ;
m_fRadiusY = RECTHEIGHT(rcRect) / 2.0 ;
}
protected:
virtual double CalculateFactor (int nX, int nY)
{
double ratX = fabs((nX-m_ptCenter.x) / m_fRadiusX),
ratY = fabs((nY-m_ptCenter.y) / m_fRadiusY) ;
return FMax(ratX, ratY) ;
}
protected:
POINT_F m_ptCenter ;
double m_fRadiusX, m_fRadiusY ;
};
//=============================================================================
/// Gradient fill radial (>=24 bit)
class FCPixelGradientRadial : public FCPixelGradientBase
{
public:
FCPixelGradientRadial (RECT rcEllipse, RGBQUAD crStart, RGBQUAD crEnd, REPEAT_MODE nRepeat = REPEAT_NONE) : FCPixelGradientBase (crStart, crEnd, nRepeat)
{
assert (!IsRectEmpty(&rcEllipse)) ;
m_ptCenter.x = (rcEllipse.left + rcEllipse.right) / 2.0 ;
m_ptCenter.y = (rcEllipse.top + rcEllipse.bottom) / 2.0 ;
m_fRadiusX = RECTWIDTH(rcEllipse) / 2.0 ;
m_fRadiusY = RECTHEIGHT(rcEllipse) / 2.0 ;
}
protected:
virtual double CalculateFactor (int nX, int nY)
{
double rat = FHypot((nX-m_ptCenter.x)/m_fRadiusX, (nY-m_ptCenter.y)/m_fRadiusY) ;
return rat ;
}
protected:
POINT_F m_ptCenter ;
double m_fRadiusX, m_fRadiusY ;
};
//=============================================================================
/// LUT(look up table) routine (>=24 bit)
class FCPixelLUTRoutine : public FCSinglePixelProcessBase
{
public:
/// @param nChannel : process channel, use OR to combine
FCPixelLUTRoutine (IMAGE_CHANNEL nChannel = CHANNEL_RGB)
{
m_bChannelR = nChannel & CHANNEL_RED ;
m_bChannelG = nChannel & CHANNEL_GREEN ;
m_bChannelB = nChannel & CHANNEL_BLUE ;
}
protected:
/// Initialize LUT.
virtual int InitLUTtable (int nLUTIndex) =0 ;
private:
virtual void OnEnterProcess (FCObjImage* pImg, RECT& rcImg)
{
for (int i=0 ; i <= 0xFF ; i++)
m_LUT[i] = this->InitLUTtable (i) ;
}
virtual void ProcessPixel (FCObjImage* pImg, int x, int y, BYTE* pPixel)
{
if (m_bChannelB) PCL_B(pPixel) = m_LUT[PCL_B(pPixel)] ;
if (m_bChannelG) PCL_G(pPixel) = m_LUT[PCL_G(pPixel)] ;
if (m_bChannelR) PCL_R(pPixel) = m_LUT[PCL_R(pPixel)] ;
}
private:
int m_LUT[256] ;
BOOL m_bChannelR, m_bChannelG, m_bChannelB ;
} ;
//=============================================================================
/// Adjust brightness (>=24 bit)
class FCPixelBrightness : public FCPixelLUTRoutine
{
public:
/// @param nPercent (>=0)
FCPixelBrightness (int nPercent, IMAGE_CHANNEL nChannel = CHANNEL_RGB) : FCPixelLUTRoutine(nChannel), m_nPercent(FMax(0,nPercent)) {}
private:
virtual int InitLUTtable (int nLUTIndex)
{
return FClamp0255 (nLUTIndex * m_nPercent / 100) ;
}
int m_nPercent ;
} ;
//=============================================================================
/// Adjust contrast (>=24 bit)
class FCPixelContrast : public FCPixelLUTRoutine
{
public:
/// @param nPercent (>=0)
FCPixelContrast (int nPercent, IMAGE_CHANNEL nChannel = CHANNEL_RGB) : FCPixelLUTRoutine(nChannel), m_nPercent(FMax(0,nPercent)) {}
private:
virtual int InitLUTtable (int nLUTIndex)
{
return FClamp0255 (128 + (nLUTIndex - 128) * m_nPercent / 100) ;
}
int m_nPercent ;
} ;
//=============================================================================
/// Adjust gamma (>=24 bit)
class FCPixelGamma : public FCPixelLUTRoutine
{
public:
/// @param fGamma (>=0.0)
FCPixelGamma (double fGamma, IMAGE_CHANNEL nChannel = CHANNEL_RGB) : FCPixelLUTRoutine(nChannel)
{
fGamma = FMax (0.0, fGamma) ;
m_fInvGamma = 1.0 / fGamma ;
}
private:
virtual int InitLUTtable (int nLUTIndex)
{
double fMax = pow (255.0, m_fInvGamma) / 255.0 ;
return FClamp0255 (FRound (pow((double)nLUTIndex, m_fInvGamma) / fMax)) ;
}
double m_fInvGamma ;
} ;
//=============================================================================
/// Negate (>=24 bit)
class FCPixelInvert : public FCPixelLUTRoutine
{
public:
FCPixelInvert (IMAGE_CHANNEL nChannel = CHANNEL_RGB) : FCPixelLUTRoutine(nChannel) {}
protected:
virtual int InitLUTtable (int nLUTIndex)
{
return (255 - nLUTIndex) ;
}
} ;
//=============================================================================
/// Solarize (>=24 bit)
class FCPixelSolarize : public FCPixelLUTRoutine
{
public:
FCPixelSolarize (int nThreshold, IMAGE_CHANNEL nChannel = CHANNEL_RGB) : FCPixelLUTRoutine(nChannel), m_nThreshold(FClamp0255(nThreshold)) {}
private:
virtual int InitLUTtable (int nLUTIndex)
{
return (nLUTIndex >= m_nThreshold) ? (255 - nLUTIndex) : nLUTIndex ;
}
int m_nThreshold ;
} ;
//=============================================================================
/// Posterize (>=24 bit)
class FCPixelPosterize : public FCPixelLUTRoutine
{
public:
FCPixelPosterize (int nLevel, IMAGE_CHANNEL nChannel = CHANNEL_RGB) : FCPixelLUTRoutine(nChannel), m_nLevel(FMax(2,nLevel)) {}
private:
virtual int InitLUTtable (int nLUTIndex)
{
double du1 = 255.0 / (m_nLevel - 1.0) ;
return FClamp0255 (FRound (du1 * FRound (nLUTIndex / du1))) ;
}
int m_nLevel ;
} ;
//=============================================================================
// inline Implement
//=============================================================================
#include "PixelProcessorBase.inl"
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -