📄 granulationfilter.cpp
字号:
/////////////////////////////////////////////////////////////////////////////////
//
// GranulationFilter.cpp: implementation of the CGranulationFilter class.
//
////////////////////////////////////////////////////////////////////////////////
// 版权所有(2002)
// Copyright(2002)
// 编写者: 向世明
// Author: Xiang Shiming
#include "stdafx.h"
#include "GranulationFilter.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CGranulationFilter, CImageAreaProcess)
CGranulationFilter::CGranulationFilter()
{
m_dwOperation = IMAGE_GRANUALATION_PLOT_FILTER;
m_nRows = 3;
m_nCols = 3;
}
CGranulationFilter::~CGranulationFilter()
{
}
#ifdef _DEBUG
void CGranulationFilter::Dump(CDumpContext& dc) const
{
CImageAreaProcess::Dump(dc);
}
void CGranulationFilter::AssertValid() const
{
CImageAreaProcess::AssertValid();
}
#endif
void CGranulationFilter::SetGranulationSize(int nWidth, int nHeight)
{
m_nRows = nHeight;
m_nCols = nWidth;
if(m_nRows <= 0) m_nRows = 1;
if(m_nCols <= 0) m_nCols = 1;
}
BOOL CGranulationFilter::Filter(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
//第一步, 参数合法性检测
ASSERT(lpbyBits32);
if((m_nRows == 1) && (m_nCols == 1))return FALSE;
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//建立一份拷贝
BYTE* pbySrcCopy = new BYTE[ (dwWidthBytes * nScanHeight) ];
if(pbySrcCopy == 0) return FALSE;
::CopyMemory(pbySrcCopy, lpbyBits32, dwWidthBytes * nScanHeight);
int i;
int nPlotsx = w / m_nCols;
int nPlotsy = h / m_nRows;
int yy = y;
//处理左上角
for(i = 0;i < nPlotsy; i++)
{
//小块左上角x坐标
int xx = x;
for(int j = 0; j < nPlotsx; j++)
{
Granulate(pbySrcCopy, xx, yy, m_nCols, m_nRows, dwWidthBytes, lpbyBits32);
xx += m_nCols;
}
yy += m_nRows;
}
//水平方向上的残留宽度
int nRemnantx = w - (nPlotsx * m_nCols);
if(nRemnantx > 0)
{
yy = y;
int xx = x + (nPlotsx * m_nCols);
for(i = 0;i < nPlotsy;i++)
{
Granulate(pbySrcCopy, xx, yy, nRemnantx, m_nRows, dwWidthBytes, lpbyBits32);
yy += m_nRows;
}
}
//垂直方向上残留的高度
int nRemnanty = h - (nPlotsy * m_nRows);
if(nRemnanty > 0)
{
yy = y + (nPlotsy * m_nRows);
int xx = x;
for(int j = 0;j < nPlotsx;j++)
{
Granulate(pbySrcCopy, xx, yy, m_nCols, nRemnanty, dwWidthBytes, lpbyBits32);
xx += m_nCols;
}
}
//可能在右下角残留一个很小的块
if((nRemnantx > 0) && (nRemnanty > 0))
Granulate(pbySrcCopy, (w - nRemnantx), (h - nRemnanty), nRemnantx, nRemnanty, dwWidthBytes, lpbyBits32);
delete[] pbySrcCopy;
return TRUE;
}
//lppbyBitsSrc32----源像素值
//x, y, nWidth, int nHeight, 定义粒化小块的大小和位置
//dwWidthBytes扫描宽度, 以字节为单位
//lpbyBitsDst32----目的像素值
void CGranulationFilter::Granulate(LPBYTE lpbyBitsSrc32, int x, int y, int nWidth, int nHeight, DWORD dwWidthBytes, LPBYTE lpbyBitsDst32)
{
//从源中取出数据
//颗粒像素总数
int nGranulationSize = nWidth * nHeight;
int i, nRed, nGreen, nBlue;
nRed = nGreen = nBlue = 0;
for(i = 0;i < nHeight;i++)
{
//y坐标
int yy = y + i;
//指针, 指向行数据
BYTE* pbySrc = lpbyBitsSrc32 + ((DWORD)yy) * dwWidthBytes + 4 * x;
for(int j = 0;j < nWidth;j++)
{
//x坐标
//记录颜色分量
nBlue += *pbySrc++;
nGreen += *pbySrc++;
nRed += *pbySrc++;
pbySrc++;
}
}
BYTE byRed = (BYTE)(nRed / nGranulationSize);
BYTE byGreen = (BYTE)(nGreen / nGranulationSize);
BYTE byBlue = (BYTE)(nBlue / nGranulationSize);
for(i = 0;i < nHeight;i++)
{
//当前像素y坐标
int yy = y + i;
//指向目的地址
BYTE* pbyDst = lpbyBitsDst32 + ((DWORD)yy) * dwWidthBytes + 4 * x;
for(int j = 0;j < nWidth;j++)
{
*pbyDst++ = byBlue;
*pbyDst++ = byGreen;
*pbyDst++ = byRed;
pbyDst++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -