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

📄 pixelblend.cpp

📁 visual c++数字图像与图形处理中的光盘内容
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////////
//
// PixelBlend.cpp: implementation of the CPixelBlend class.
//
////////////////////////////////////////////////////////////////////////////////
// 版权所有(2002)
// Copyright(2002)
// 编写者: 向世明
// Author: Xiang Shiming



#include "stdafx.h"
#include "PixelBlend.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CPixelBlend,CImageComposite)
CPixelBlend::CPixelBlend()
{
	m_dwOperation = IMAGE_BLEND;

	//缺省设置源和目标均为不透明图像
	m_dwSrcFactor = IMAGE_BLEND_SFACTOR_255;
	m_dwDstFactor = IMAGE_BLEND_DFACTOR_255;
}

CPixelBlend::~CPixelBlend()
{}

#ifdef _DEBUG
void CPixelBlend::Dump(CDumpContext& dc) const
{
	CImageComposite::Dump(dc);
}

void CPixelBlend::AssertValid() const
{
	CImageComposite::AssertValid();
}
#endif


//设置融合计算线索
void CPixelBlend::SetHint(DWORD dwSrcFactor, DWORD dwDstFactor)
{
	m_dwSrcFactor = dwSrcFactor;
	m_dwDstFactor = dwDstFactor;
	if((m_dwSrcFactor < IMAGE_BLEND_SFACTOR_255) ||
		(m_dwSrcFactor > IMAGE_BLEND_SFACTOR_SRC_ALPHA_SATURATE))
		m_dwSrcFactor = IMAGE_BLEND_SFACTOR_255;
	if((m_dwDstFactor < IMAGE_BLEND_DFACTOR_255) ||
		(m_dwDstFactor > IMAGE_BLEND_DFACTOR_255_MINUS_DST_ALPHA))
		m_dwDstFactor = IMAGE_BLEND_DFACTOR_255;
}

//
//bySrcRed,bySrcGreen,bySrcBlue,bySrcAlpha ----源颜色
//byDstRed,byDstGreen,byDstBlue,byDstAlpha ----目标颜色
//不改变源和目标的Alpha值
//完成融合计算
PIXELCOLORRGB CPixelBlend::Blend(BYTE bySrcRed,BYTE bySrcGreen,BYTE bySrcBlue,BYTE bySrcAlpha,BYTE byDstRed,BYTE byDstGreen,BYTE byDstBlue,BYTE byDstAlpha)
{
	//源乘子系数
	BYTE bySrcR,bySrcG,bySrcB;
	
	//目标乘子系数
	BYTE byDstR,byDstG,byDstB;

	switch(m_dwSrcFactor)
	{
		case IMAGE_BLEND_SFACTOR_255:
			bySrcR = bySrcG = bySrcB = 255; break;

		case IMAGE_BLEND_SFACTOR_ZERO:
			bySrcR = bySrcG = bySrcB = 0; break;

		case IMAGE_BLEND_SFACTOR_DST_COLOR:
			bySrcR = byDstRed;
			bySrcG = byDstGreen;
			bySrcB = byDstBlue;
			break;

		case IMAGE_BLEND_SFACTOR_255_MINUS_DST_COLOR:
			bySrcR = (255 - byDstRed);
			bySrcG = (255 - byDstGreen);
			bySrcB = (255 - byDstBlue);
			break;

		case IMAGE_BLEND_SFACTOR_SRC_ALPHA:
			bySrcR = bySrcG = bySrcB = bySrcAlpha; break;

		case IMAGE_BLEND_SFACTOR_255_MINUS_SRC_ALPHA:
			bySrcR = bySrcG = bySrcB = (255 - bySrcAlpha); break;

		case IMAGE_BLEND_SFACTOR_DST_ALPHA:
			bySrcR = bySrcG = bySrcB = byDstAlpha; break;

		case IMAGE_BLEND_SFACTOR_255_MINUS_DST_ALPHA:
			bySrcR = bySrcG = bySrcB = (255 - byDstAlpha); break;
		case IMAGE_BLEND_SFACTOR_SRC_ALPHA_SATURATE:
			bySrcR = bySrcG = bySrcB = min(bySrcAlpha,255 - (byDstAlpha)); break;
		default : break;
	}
	switch(m_dwDstFactor)
	{
		case IMAGE_BLEND_DFACTOR_255:
			byDstR = byDstG = byDstB = 255; break;
		
		case IMAGE_BLEND_DFACTOR_ZERO:
			byDstR = byDstG = byDstB = 0;	break;
		
		case IMAGE_BLEND_DFACTOR_SRC_COLOR:
			byDstR = bySrcRed;
			byDstG = bySrcGreen;
			byDstB = bySrcBlue; 
			break;
	
		case IMAGE_BLEND_DFACTOR_255_MINUS_SRC_COLOR:
			byDstR = (255 - bySrcRed);
			byDstG = (255 - bySrcGreen);
			byDstB = (255 - bySrcBlue); 
			break;

		case IMAGE_BLEND_DFACTOR_SRC_ALPHA:
			byDstR = byDstG = byDstB = bySrcAlpha;	break;

		case IMAGE_BLEND_DFACTOR_255_MINUS_SRC_ALPHA:
			byDstR = byDstG = byDstB = (255 - bySrcAlpha);	break;

		case IMAGE_BLEND_DFACTOR_DST_ALPHA:
			byDstR = byDstG = byDstB = byDstAlpha;	break;

		case IMAGE_BLEND_DFACTOR_255_MINUS_DST_ALPHA:
			byDstR = byDstG = byDstB = (255 - byDstAlpha);	break;
	
		default : break;
	}

	PIXELCOLORRGB rgb;
	//完成融合计算
	int r = (((int)bySrcR * (int)bySrcRed + (int)byDstR * (int)byDstRed) / 255);
	int g = (((int)bySrcG * (int)bySrcGreen + (int)byDstG * (int)byDstGreen) / 255);
	int b = (((int)bySrcB * (int)bySrcBlue + (int)byDstB * (int)byDstBlue) / 255);

	rgb.red = (BYTE)BOUND(r,0,255);
	rgb.green = (BYTE)BOUND(g,0,255);
	rgb.blue = (BYTE)BOUND(b,0,255);
	return rgb;
}

//公有成员函数
//(nXSrc,nYSrc,nWidth,nHeight)	表示合成输入源的哪部分区域:位置和大小
//nXDst,nYDst					表示从目标什么位置开始,大多数情况下,这两个参数均取0值
//lpbyBitsSrc					表示输入源图像像素字节
//nWidthImgSrc,nHeightImgSrc,	分别表示输入源图像的宽度和高度
//lpbyBitsDst					表示目标图像的像素字节
//nWidthImgDst,nHeightImgDst	分别表示目标图像的宽度和高度.

//根据融合因子计算线索完成图像合成
BOOL CPixelBlend::Blend(int nXSrc, int nYSrc, int nWidth, int nHeight, int nXDst, int nYDst, LPBYTE lpbyBitsSrc32, int nWidthImgSrc, int nHeightImgSrc, LPBYTE lpbyBitsDst32, int nWidthImgDst, int nHeightImgDst)
{
	//第一步,参数合法性检测
	ASSERT(lpbyBitsSrc32);
	ASSERT(lpbyBitsDst32);

	if((nXSrc > (nWidthImgSrc - 1)) || (nYSrc > (nHeightImgSrc - 1))) return FALSE;
	if((nXDst > (nWidthImgDst - 1)) || (nYDst > (nHeightImgDst - 1))) return FALSE;

	//有效区域的宽度和高度
	int w = min(nWidth,(nWidthImgSrc - nXSrc));
	int h = min(nHeight,(nHeightImgSrc - nYSrc));
	w = min(w,(nWidthImgDst - nXDst));
	h = min(h,(nHeightImgDst - nYDst));


	//行字节数:扫描
	DWORD dwWidthBytesSrc = (DWORD)nWidthImgSrc * 4;
	DWORD dwWidthBytesDst = (DWORD)nWidthImgDst * 4;

	//开始数据基索引
	DWORD dwBaseIndexSrc = nYSrc * dwWidthBytesSrc + 4 * nXSrc;
	DWORD dwBaseIndexDst = nYDst * dwWidthBytesDst + 4 * nXDst;

	//第二步,实现融合
	for(int i = 0;i < h;i++)
	{
		BYTE* pbySrc = lpbyBitsSrc32 + dwBaseIndexSrc;
		BYTE* pbyDst = lpbyBitsDst32 + dwBaseIndexDst;

		for(int j = 0;j < w;j++)
		{
			//源
			BYTE bySrcBlue = *pbySrc++;
			BYTE bySrcGreen = *pbySrc++;
			BYTE bySrcRed = *pbySrc++;
			BYTE bySrcAlpha = *pbySrc++;

			//目标
			BYTE* pbyDstBlue = pbyDst++;
			BYTE* pbyDstGreen = pbyDst++;
			BYTE* pbyDstRed = pbyDst++;
			BYTE* pbyDstAlpha = pbyDst++;
			
			//目标VS源
			PIXELCOLORRGB rgb = Blend(bySrcRed,bySrcGreen,bySrcBlue,bySrcAlpha,
								*pbyDstRed,*pbyDstGreen,*pbyDstBlue,*pbyDstAlpha);

			*pbyDstBlue = rgb.blue;
			*pbyDstGreen = rgb.green;
			*pbyDstRed = rgb.red;
		}
		dwBaseIndexSrc += dwWidthBytesSrc;
		dwBaseIndexDst += dwWidthBytesDst;
	}
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -