⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 granulationfilter.cpp

📁 visual c++数字图像与图形处理中的光盘内容
💻 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 + -