📄 effect.cpp
字号:
#include "stdafx.h"
#include <math.h>
#include "..\..\Include\Pic\Effect.h"
#include "..\..\Include\fooBit.h"
#include "..\..\Include\C_x86_CPU.h"
//===================================================================
FCDibEffect::FCDibEffect (bool bUndo) : m_UndoFlag(bUndo) {
m_UndoList.clear () ;
m_RedoList.clear () ;
m_hSelRgn = NULL ;
::SetRectEmpty (&m_SelRect) ;
}
FCDibEffect::FCDibEffect (FCDibEffect & dib) : FCDib (* (FCDib *)&dib) {
m_UndoList.clear () ;
m_RedoList.clear () ;
this->SetUndoEnable (dib.GetUndoFlag () ? true : false) ;
m_hSelRgn = NULL ;
::SetRectEmpty (&m_SelRect) ;
}
FCDibEffect::~FCDibEffect () {
this->ClearAllList () ;
this->ClearSelection () ;
}
void FCDibEffect::operator= (const FCDibEffect & pic) {
FCDib::operator = (*(FCDib *)&pic) ;
}
void FCDibEffect::ClearAllList () {
this->ClearRedoList () ;
this->ClearUndoList () ;
}
void FCDibEffect::ClearRedoList () {
FCDib * dib ;
while (!m_RedoList.empty ())
{
dib = m_RedoList.front () ;
m_RedoList.pop_front () ;
delete dib ;
}
}
void FCDibEffect::AddToUndoList () {
this->ClearRedoList () ;
FCDib * now = new FCDib ;
*now = * (FCDib *) this ;
m_UndoList.push_back (now) ;
}
void FCDibEffect::ClearUndoList ()
{
FCDib * dib ;
while (!m_UndoList.empty ())
{
dib = m_UndoList.back () ;
m_UndoList.pop_back () ;
delete dib ;
}
}
//===================================================================
void FCDibEffect::Undo ()
{
if (m_UndoList.empty ())
return ;
FCDib * now = new FCDib ;
*now = * (FCDib *) this ; // 保存当前位图到Redo头
m_RedoList.push_front (now) ;
now = m_UndoList.back () ; // 取出Undo队列末尾的位图
* (FCDib *) this = *now ;
m_UndoList.pop_back () ;
delete now ;
}
void FCDibEffect::Redo ()
{
if (m_RedoList.empty ())
return ;
FCDib * now = new FCDib ;
*now = * (FCDib *) this ; // 保存当前位图到Undo尾
m_UndoList.push_back (now) ;
now = m_RedoList.front () ; // 取出Redo队列开始的位图
* (FCDib *) this = *now ;
m_RedoList.pop_front () ;
delete now ;
}
//===================================================================
void FCDibEffect::Mirror ()
{
if (this->ColorBits() < 8)
return ;
if (m_UndoFlag)
this->AddToUndoList () ;
if (m_hSelRgn == NULL) // 全图
for (DWORD y = 0 ; y < this->Height() ; y++)
switch (this->ColorBits())
{
case 8 : ::fooMemReverse ((BYTE*)this->GetBits (y), Width()) ; break ;
case 16 : ::fooMemReverse ((WORD*)this->GetBits (y), Width()) ; break ;
case 24 : ::fooMemReverse ((RGBTRIPLE*)this->GetBits (y), Width()) ; break ;
case 32 : ::fooMemReverse ((DWORD*)this->GetBits (y), Width()) ; break ;
}
else
{
FCDibEffect block ;
this->GetSubBlock (&block, m_SelRect) ;
block.Mirror () ;
this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
}
}
//===================================================================
void FCDibEffect::Stretch (DWORD dwWidth, DWORD dwHeight, int iType)
{
if ((this->GetHandle() == NULL) || (dwWidth <= 0) || (dwHeight <=0))
return ;
FCDib * Old = NULL ;
if (m_UndoFlag) // 保存当前图象
{
this->AddToUndoList () ;
Old = m_UndoList.back () ; // return FCDib *
}
else
{
Old = new FCDib ;
* Old = * (FCDib *) this ; // 保存当前图象
}
if (iType) // 成比例缩放
{
DWORD dwOldW = Old->Width(), dwOldH = Old->Height() ;
double duOldScale = dwOldW / (double)dwOldH ;
DWORD dwTempW = (DWORD)(duOldScale * dwHeight) ;
if (dwTempW < dwWidth) // 计算新的宽高
dwWidth = dwTempW ;
else
dwHeight = (DWORD)(dwWidth / duOldScale) ;
}
if (this->Create (dwWidth, dwHeight, Old->ColorBits()))
{
HDC hdcDesc = CreateCompatibleDC (NULL),
hdcSrc = CreateCompatibleDC (NULL) ;
if (this->ColorBits() <= 8)
{
int nNum = 1 << this->ColorBits() ;
RGBQUAD * prgb = (RGBQUAD *) new RGBQUAD[nNum] ;
Old->GetColorTable (0, nNum, prgb) ;
this->SetColorTable (0, nNum, prgb) ; // 复制调色板
delete[] prgb ;
}
::SetStretchBltMode (hdcDesc, COLORONCOLOR) ;
HBITMAP hTa = (HBITMAP)SelectObject (hdcDesc, this->GetHandle ()) ;
HBITMAP hTb = (HBITMAP)SelectObject (hdcSrc, Old->GetHandle ()) ;
::StretchBlt (hdcDesc, 0, 0, dwWidth, dwHeight,
hdcSrc, 0, 0, Old->Width(), Old->Height(), SRCCOPY) ;
SelectObject (hdcDesc, hTa) ;
SelectObject (hdcSrc, hTb) ;
DeleteDC (hdcDesc) ;
DeleteDC (hdcSrc) ;
}
if (!m_UndoFlag)
delete Old ;
}
//===================================================================
void FCDibEffect::__BltBlock (const FCDib & Dib, int x, int y)
{
RECT now = {0, 0, Width(), Height()} ,
sub = {x, y, x+Dib.Width(), y+Dib.Height()} ,
rcDest ;
if ((::IntersectRect (&rcDest, &now, &sub) == 0) || (this->ColorBits() != Dib.ColorBits())
|| (this->ColorBits() < 8))
return ; // 没有相交区域
HDC hdcDesc = CreateCompatibleDC (NULL),
hdcSrc = CreateCompatibleDC (NULL) ;
::SetStretchBltMode (hdcDesc, COLORONCOLOR) ;
::SelectObject (hdcDesc, m_hSelRgn);
HBITMAP hTa = (HBITMAP)SelectObject (hdcDesc, this->GetHandle ()) ;
HBITMAP hTb = (HBITMAP)SelectObject (hdcSrc, Dib.GetHandle ()) ;
::BitBlt (hdcDesc, x, y, rcDest.right - rcDest.left, rcDest.bottom - rcDest.top,
hdcSrc, 0, 0, SRCCOPY) ;
SelectObject (hdcDesc, hTa) ;
SelectObject (hdcSrc, hTb) ;
SelectClipRgn (hdcSrc, NULL) ;
DeleteDC (hdcDesc) ;
DeleteDC (hdcSrc) ;
}
//===================================================================
void FCDibEffect::AdjustBrightness (int iPercent, BOOL bFlag)
{
if (this->ColorBits() == 16)
return ;
if (m_UndoFlag)
this->AddToUndoList () ;
if (m_hSelRgn == NULL) // 整图
{
int nSpan = this->ColorBits() / 8 ;
if (!bFlag)
iPercent = 128 * iPercent / 100 ; // 转换成x/128
if (this->ColorBits() > 8)
for (int y=0 ; y < Height() ; y++)
{
BYTE * pPixel = this->GetBits (y) ;
if (bFlag) // 按增量
::fooMMX_ADD ((BYTE *)pPixel, nSpan * Width(), iPercent) ;
else // 按百分比
for (DWORD i = 0 ; i < Width() ; i++, pPixel += nSpan)
{
pPixel[0] = min (pPixel[0] * iPercent / 128, 255) ;
pPixel[1] = min (pPixel[1] * iPercent / 128, 255) ;
pPixel[2] = min (pPixel[2] * iPercent / 128, 255) ;
}
}
else // 调色板图象
{
UINT nNum = 1 << this->ColorBits() ;
RGBQUAD * pPalette = new RGBQUAD [nNum] ;
this->GetColorTable (0, nNum, pPalette) ;
if (bFlag) // 按增量
::fooMMX_ADD ((BYTE *)pPalette, 4 * nNum, iPercent) ;
else // 按百分比
for (int i = 0 ; i < nNum ; i++)
{
pPalette[i].rgbBlue = min (pPalette[i].rgbBlue * iPercent / 128, 255) ;
pPalette[i].rgbGreen = min (pPalette[i].rgbGreen * iPercent / 128, 255) ;
pPalette[i].rgbRed = min (pPalette[i].rgbRed * iPercent / 128, 255) ;
}
this->SetColorTable (0, nNum, pPalette) ;
delete[] pPalette ;
}
}
else
{
FCDibEffect block ;
this->GetSubBlock (&block, m_SelRect) ;
block.AdjustBrightness (iPercent, bFlag) ;
this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
}
}
//===================================================================
void FCDibEffect::AdjustContrast (int iPercent)
{
if (this->ColorBits() == 16)
return ;
if (m_UndoFlag)
this->AddToUndoList () ;
if (m_hSelRgn == NULL) // 整图
{
int nSpan = this->ColorBits() / 8 ;
iPercent = 128 * iPercent / 100 ; // 转换成x/128
if (this->ColorBits() > 8)
for (int y=0 ; y < Height() ; y++)
{
BYTE * pPixel = this->GetBits (y) ;
for (DWORD i = 0 ; i < Width() ; i++, pPixel += nSpan)
{
pPixel[0] = max (min (128 + (pPixel[0] - 128) * iPercent / 128, 255), 0) ;
pPixel[1] = max (min (128 + (pPixel[1] - 128) * iPercent / 128, 255), 0) ;
pPixel[2] = max (min (128 + (pPixel[2] - 128) * iPercent / 128, 255), 0) ;
}
}
else // 调色板图象
{
UINT nNum = 1 << this->ColorBits() ;
RGBQUAD * pPalette = new RGBQUAD [nNum] ;
this->GetColorTable (0, nNum, pPalette) ;
for (int i = 0 ; i < nNum ; i++)
{
pPalette[i].rgbBlue = max (min (128 + (pPalette[i].rgbBlue - 128) * iPercent / 128, 255), 0) ;
pPalette[i].rgbGreen = max (min (128 + (pPalette[i].rgbGreen - 128) * iPercent / 128, 255), 0) ;
pPalette[i].rgbRed = max (min (128 + (pPalette[i].rgbRed - 128) * iPercent / 128, 255), 0) ;
}
this->SetColorTable (0, nNum, pPalette) ;
delete[] pPalette ;
}
}
else
{
FCDibEffect block ;
this->GetSubBlock (&block, m_SelRect) ;
block.AdjustContrast (iPercent) ;
this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
}
}
//===================================================================
void FCDibEffect::AdjustHS (int iPercentHue, int iPercentSat)
{
if (this->ColorBits() == 16)
return ;
if (m_UndoFlag)
this->AddToUndoList () ;
if (m_hSelRgn == NULL) // 整图
{
iPercentHue = 128 * iPercentHue / 100 ; // 转换成x/128
iPercentSat = 128 * iPercentSat / 100 ; // 转换成x/128
int nSpan = this->ColorBits() / 8 ;
double H, L, S ;
if (this->ColorBits() > 8)
for (int y=0 ; y < Height() ; y++)
{
BYTE * pPixel = this->GetBits (y) ;
for (DWORD i = 0 ; i < Width() ; i++, pPixel += nSpan)
{
FCDib::fooRGBtoHLS (*(RGBTRIPLE *)pPixel, &H, &L, &S);
if (iPercentHue != 128)
H = H * iPercentHue / 128 ;
if (iPercentSat != 128)
S = S * iPercentSat / 128 ;
* (RGBTRIPLE *) pPixel = FCDib::fooHLStoRGB (H, L, S) ;
}
}
else // 调色板图象
{
UINT nNum = 1 << this->ColorBits() ;
RGBQUAD * pPalette = new RGBQUAD [nNum] ;
this->GetColorTable (0, nNum, pPalette) ;
for (int i = 0 ; i < nNum ; i++)
{
FCDib::fooRGBtoHLS (*(RGBTRIPLE *)&pPalette[i], &H, &L, &S);
if (iPercentHue != 128)
H = H * iPercentHue / 128 ;
if (iPercentSat != 128)
S = S * iPercentSat / 128 ;
*(RGBTRIPLE *)&pPalette[i] = FCDib::fooHLStoRGB (H, L, S) ;
}
this->SetColorTable (0, nNum, pPalette) ;
delete[] pPalette ;
}
}
else
{
FCDibEffect block ;
this->GetSubBlock (&block, m_SelRect) ;
block.AdjustHS (iPercentHue, iPercentSat) ;
this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
}
}
//===================================================================
void FCDibEffect::AdjustRGB (int iValueR, int iValueG, int iValueB)
{
if (this->ColorBits() == 16)
return ;
if (m_UndoFlag)
this->AddToUndoList () ;
if (m_hSelRgn == NULL) // 整图
{
int nSpan = this->ColorBits() / 8 ; // 每象素字节数3, 4
if (this->ColorBits() > 8)
for (int y=0 ; y < Height() ; y++)
{
BYTE * pPixel = this->GetBits (y) ;
for (int x=0 ; x < Width() ; x++, pPixel += nSpan)
{
if (iValueB != 0)
pPixel[0] = max (min (pPixel[0] + iValueB, 255), 0) ;
if (iValueG != 0)
pPixel[1] = max (min (pPixel[1] + iValueG, 255), 0) ;
if (iValueR != 0)
pPixel[2] = max (min (pPixel[2] + iValueR, 255), 0) ;
}
}
else // 调色板图象
{
UINT nNum = 1 << this->ColorBits() ;
RGBQUAD * pPalette = new RGBQUAD [nNum] ;
this->GetColorTable (0, nNum, pPalette) ;
for (int i=0 ; i < nNum ; i++)
{
if (iValueB != 0)
pPalette[i].rgbBlue = max (min (pPalette[i].rgbBlue + iValueB, 255), 0) ;
if (iValueG != 0)
pPalette[i].rgbGreen = max (min (pPalette[i].rgbGreen + iValueG, 255), 0) ;
if (iValueR != 0)
pPalette[i].rgbRed = max (min (pPalette[i].rgbRed + iValueR, 255), 0) ;
}
this->SetColorTable (0, nNum, pPalette) ;
delete[] pPalette ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -