www.gusucode.com > 包含近30种图像特效的VC++小程序源码程序 > 包含近30种图像特效的VC++小程序源码程序/code/WaterRoutine.cpp

    //Download by http://www.NewXing.com
/////////////////////////////////////////////////////////////////////////
//类名:CWaterRoutine
//功能:水纹效果
//修改:徐景周(jingzhou_xu@163.net)
//组织:未来工作室(Future Studio)
//日期:2002.1.8
////////////////////////////////////////////////////////////////////////
#include "stdafx.h"				// 加入预编译头文件,jingzhou xu
#include "WaterRoutine.h"
#include <math.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// 取指定范围内的随机数
#define random( min, max ) (( rand() % (int)((( max ) + 1 ) - ( min ))) + ( min ))

// ---------------------------------------------------------
//	名称: CWaterRoutine
//	功能: 构造涵数,初始化工作
//	参数: 无
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
CWaterRoutine::CWaterRoutine()
{
	m_iHeightField1 = NULL;
	m_iHeightField2 = NULL;

	m_iWidth = 0;
	m_iHeight = 0;

	m_bDrawWithLight = TRUE;
	m_iLightModifier = 1;
	m_iHpage = 0;
	m_density = 5;
}

// ---------------------------------------------------------
//	名称: ~CWaterRoutine
//	功能: 析构涵数,清扫工作
//	参数: 无
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
CWaterRoutine::~CWaterRoutine()
{
	// 清除工作
	if(m_iHeightField1 != NULL)
		delete [] m_iHeightField1;
	if(m_iHeightField2 != NULL)
		delete [] m_iHeightField2;

	m_iHeightField1 = NULL;
	m_iHeightField2 = NULL;
}

// ---------------------------------------------------------
//	名称: Create
//	功能: 初始化水纹效果所需数据,需预先调用
//	参数: iWidth -- 目标位图宽度,iHeight -- 目标位图高度
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::Create(int iWidth,int iHeight)
{
	if(m_iHeightField1 != NULL)
		delete [] m_iHeightField1;
	if(m_iHeightField2 != NULL)
		delete [] m_iHeightField2;

	// 创建高度字段
	m_iHeightField1 = new int[(iWidth*iHeight)];
	m_iHeightField2 = new int[(iWidth*iHeight)];

	// 清空高度字段
	memset(m_iHeightField1,0,(iWidth*iHeight)*sizeof(int));
	memset(m_iHeightField2,0,(iWidth*iHeight)*sizeof(int));

	m_iWidth = iWidth;
	m_iHeight = iHeight;

	// 设置当前页
	m_iHpage = 0;

}

// ---------------------------------------------------------
//	名称: FlattenWater
//	功能: 清空水纹效果数据
//	参数: 无
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::FlattenWater()
{
	// 清空高度字段
	memset(m_iHeightField1,0,(m_iWidth*m_iHeight)*sizeof(int));
	memset(m_iHeightField2,0,(m_iWidth*m_iHeight)*sizeof(int));
}

// ---------------------------------------------------------
//	名称: Render
//	功能: 处理水纹效果并将处理好的数据放入目标位图中
//	参数: pSrcImage -- 源位图指针,pTargetImage -- 目标位图指针
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::Render(DWORD* pSrcImage,DWORD* pTargetImage)
{
	// 创建水纹效果
	if(m_bDrawWithLight == FALSE)
	{
		DrawWaterNoLight(m_iHpage,pSrcImage,pTargetImage);
	}
	else
	{
		DrawWaterWithLight(m_iHpage,m_iLightModifier,pSrcImage,pTargetImage);
	}
	CalcWater(m_iHpage,m_density);

	// 两个高度字段间切换
	m_iHpage ^= 1;
}

// ---------------------------------------------------------
//	名称: CalcWater
//	功能: 两个效果高度字段数据间对照处理水纹(类似内部两个位图)
//	参数: npage -- 所在页面,density -- 密度
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::CalcWater(int npage, int density)
{
  int newh;
  int count = m_iWidth + 1;
  int *newptr;
  int *oldptr;

  // 设置指针
  if(npage == 0)
  {
	newptr = &m_iHeightField1[0];
	oldptr = &m_iHeightField2[0];
  }
  else
  {
	newptr = &m_iHeightField2[0];
	oldptr = &m_iHeightField1[0];
  }

  int x, y;

  for (y = (m_iHeight-1)*m_iWidth; count < y; count += 2)
  {
    for (x = count+m_iWidth-2; count < x; count++)
    {

	  // 一次处理周围8个像素(速度优化)
      newh          = ((oldptr[count + m_iWidth]
                      + oldptr[count - m_iWidth]
                      + oldptr[count + 1]
                      + oldptr[count - 1]
                      + oldptr[count - m_iWidth - 1]
                      + oldptr[count - m_iWidth + 1]
                      + oldptr[count + m_iWidth - 1]
                      + oldptr[count + m_iWidth + 1]
                       ) >> 2 )
                      - newptr[count];


      newptr[count] =  newh - (newh >> density);
/*
	  //  淤泥效果
      newh = (oldptr[count]<<2)
           +  oldptr[count-1-m_iWidth]
           +  oldptr[count+1-m_iWidth]
           +  oldptr[count-1+m_iWidth]
           +  oldptr[count+1+m_iWidth]
           + ((oldptr[count-1]
           +   oldptr[count+1]
           +   oldptr[count-m_iWidth]
           +   oldptr[count+m_iWidth])<<1);

      newptr[count] = (newh-(newh>>6)) >> density;
*/
    }
  }
}

// ---------------------------------------------------------
//	名称: SmoothWater
//	功能: 平滑处理水纹(两个效果高度字段处理)
//	参数: npage -- 所在页面
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::SmoothWater(int npage)
{
  int newh;
  int count = m_iWidth + 1;

  int *newptr;
  int *oldptr;

  // 设置指针
  if(npage == 0)
  {
	newptr = &m_iHeightField1[0];
	oldptr = &m_iHeightField2[0];
  }
  else
  {
	newptr = &m_iHeightField2[0];
	oldptr = &m_iHeightField1[0];
  }


  int x, y;

  for(y=1; y<m_iHeight-1; y++)
  {
    for(x=1; x<m_iWidth-1; x++)
    {
	  // 一次处理周围8个像素(速度优化)
      newh          = ((oldptr[count + m_iWidth]
                      + oldptr[count - m_iWidth]
                      + oldptr[count + 1]
                      + oldptr[count - 1]
                      + oldptr[count - m_iWidth - 1]
                      + oldptr[count - m_iWidth + 1]
                      + oldptr[count + m_iWidth - 1]
                      + oldptr[count + m_iWidth + 1]
                       ) >> 3 )
                      + newptr[count];


      newptr[count] =  newh>>1;
      count++;
    }
    count += 2;
  }
}

// ---------------------------------------------------------
//	名称: CalcWaterBigFilter
//	功能: 大波纹处理(未用)
//	参数: npage -- 所在页面,density -- 密度
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::CalcWaterBigFilter(int npage, int density)
{
  int newh;
  int count = (2*m_iWidth) + 2;

  int *newptr;
  int *oldptr;

  // 设置指针
  if(npage == 0)
  {
	newptr = &m_iHeightField1[0];
	oldptr = &m_iHeightField2[0];
  }
  else
  {
	newptr = &m_iHeightField2[0];
	oldptr = &m_iHeightField1[0];
  }

  int x, y;

  for(y=2; y<m_iHeight-2; y++)
  {
    for(x=2; x<m_iWidth-2; x++)
    {
	  // 一次处理周围25个像素(速度优化)
      newh        = (
                     (
                      (
                       (oldptr[count + m_iWidth]
                      + oldptr[count - m_iWidth]
                      + oldptr[count + 1]
                      + oldptr[count - 1]
                       )<<1)
                      + ((oldptr[count - m_iWidth - 1]
                      + oldptr[count - m_iWidth + 1]
                      + oldptr[count + m_iWidth - 1]
                      + oldptr[count + m_iWidth + 1]))
                      + ( (
                          oldptr[count - (m_iWidth*2)]
                        + oldptr[count + (m_iWidth*2)]
                        + oldptr[count - 2]
                        + oldptr[count + 2]
                        ) >> 1 )
                      + ( (
                          oldptr[count - (m_iWidth*2) - 1]
                        + oldptr[count - (m_iWidth*2) + 1]
                        + oldptr[count + (m_iWidth*2) - 1]
                        + oldptr[count + (m_iWidth*2) + 1]
                        + oldptr[count - 2 - m_iWidth]
                        + oldptr[count - 2 + m_iWidth]
                        + oldptr[count + 2 - m_iWidth]
                        + oldptr[count + 2 + m_iWidth]
                        ) >> 2 )
                     )
                    >> 3)
                    - (newptr[count]);


      newptr[count] =  newh - (newh >> density);
      count++;
    }
    count += 4;
  }
}

// ---------------------------------------------------------
//	名称: HeightBlob
//	功能: 环形涟漪效果处理
//	参数: x,y -- 坐标,radius -- 半径,height -- 高度,page -- 所在页面
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::HeightBlob(int x, int y, int radius, int height, int page)
{
  int rquad;
  int cx, cy, cyq;
  int left, top, right, bottom;

  int *newptr;
  int *oldptr;

  // 设置指针
  if(page == 0)
  {
	newptr = &m_iHeightField1[0];
	oldptr = &m_iHeightField2[0];
  }
  else
  {
	newptr = &m_iHeightField2[0];
	oldptr = &m_iHeightField1[0];
  }

  rquad = radius * radius;

  // 创建随机水滴效果
  if(x<0) x = 1+radius+ rand()%(m_iWidth-2*radius-1);
  if(y<0) y = 1+radius+ rand()%(m_iHeight-2*radius-1);

  left=-radius; right = radius;
  top=-radius; bottom = radius;

  // 减裁处理
  if(x - radius < 1) left -= (x-radius-1);
  if(y - radius < 1) top  -= (y-radius-1);
  if(x + radius > m_iWidth-1) right -= (x+radius-m_iWidth+1);
  if(y + radius > m_iHeight-1) bottom-= (y+radius-m_iHeight+1);


  for(cy = top; cy < bottom; cy++)
  {
    cyq = cy*cy;
    for(cx = left; cx < right; cx++)
    {
      if(cx*cx + cyq < rquad)
        newptr[m_iWidth*(cy+y) + (cx+x)] += height;
    }
  }

}

// ---------------------------------------------------------
//	名称: HeightBox
//	功能: 圆角方形涟漪效果处理
//	参数: x,y -- 坐标,radius -- 半径,height -- 高度,page -- 所在页面
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::HeightBox (int x, int y, int radius, int height, int page)
{
  int cx, cy;
  int left, top, right, bottom;
  int *newptr;
  int *oldptr;

  // 设置指针
  if(page == 0)
  {
	newptr = &m_iHeightField1[0];
	oldptr = &m_iHeightField2[0];
  }
  else
  {
	newptr = &m_iHeightField2[0];
	oldptr = &m_iHeightField1[0];
  }

  if(x<0) x = 1+radius+ rand()%(m_iWidth-2*radius-1);
  if(y<0) y = 1+radius+ rand()%(m_iHeight-2*radius-1);

  left=-radius; right = radius;
  top=-radius; bottom = radius;

  // 减裁处理
  if(x - radius < 1) left -= (x-radius-1);
  if(y - radius < 1) top  -= (y-radius-1);
  if(x + radius > m_iWidth-1) right -= (x+radius-m_iWidth+1);
  if(y + radius > m_iHeight-1) bottom-= (y+radius-m_iHeight+1);

  for(cy = top; cy < bottom; cy++)
  {
    for(cx = left; cx < right; cx++)
    {
        newptr[m_iWidth*(cy+y) + (cx+x)] = height;
    }
  }

}

// ---------------------------------------------------------
//	名称: WarpBlob
//	功能: 波浪形水纹处理
//	参数: x,y -- 坐标,radius -- 半径,height -- 高度,page -- 所在页面
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::WarpBlob(int x, int y, int radius, int height, int page)
{
  int cx, cy;
  int left,top,right,bottom;
  int square;
  int radsquare = radius * radius;
  int *newptr;
  int *oldptr;

  // 设置指针
  if(page == 0)
  {
	newptr = &m_iHeightField1[0];
	oldptr = &m_iHeightField2[0];
  }
  else
  {
	newptr = &m_iHeightField2[0];
	oldptr = &m_iHeightField1[0];
  }
//  radsquare = (radius*radius) << 8;
  radsquare = (radius*radius);

  height /= 64;

  left=-radius; right = radius;
  top=-radius; bottom = radius;

  // 减裁处理
  if(x - radius < 1) left -= (x-radius-1);
  if(y - radius < 1) top  -= (y-radius-1);
  if(x + radius > m_iWidth-1) right -= (x+radius-m_iWidth+1);
  if(y + radius > m_iHeight-1) bottom-= (y+radius-m_iHeight+1);

  for(cy = top; cy < bottom; cy++)
  {
    for(cx = left; cx < right; cx++)
    {
      square = cy*cy + cx*cx;
//      square <<= 8;
      if(square < radsquare)
      {
//        Height[page][WATERWID*(cy+y) + cx+x]
//          += (sqrt(radsquare)-sqrt(square))*height;
        newptr[m_iWidth*(cy+y) + cx+x]
          += int((radius-sqrt(square))*(float)(height));
      }
    }
  }
}

// ---------------------------------------------------------
//	名称: SineBlob
//	功能: 具有正弦角度水痕效果处理
//	参数: x,y -- 坐标,radius -- 半径,height -- 高度,page -- 所在页面
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::SineBlob(int x, int y, int radius, int height, int page)
{
  int cx, cy;
  int left,top,right,bottom;
  int square, dist;
  int radsquare = radius * radius;
  float length = float((1024.0/(float)radius)*(1024.0/(float)radius));
  int *newptr;
  int *oldptr;

  // 设置指针
  if(page == 0)
  {
	newptr = &m_iHeightField1[0];
	oldptr = &m_iHeightField2[0];
  }
  else
  {
	newptr = &m_iHeightField2[0];
	oldptr = &m_iHeightField1[0];
  }

  if(x<0) x = 1+radius+ rand()%(m_iWidth-2*radius-1);
  if(y<0) y = 1+radius+ rand()%(m_iHeight-2*radius-1);


//  radsquare = (radius*radius) << 8;
  radsquare = (radius*radius);

//  height /= 8;

  left=-radius; right = radius;
  top=-radius; bottom = radius;


  // 减裁处理
  if(x - radius < 1) left -= (x-radius-1);
  if(y - radius < 1) top  -= (y-radius-1);
  if(x + radius > m_iWidth-1) right -= (x+radius-m_iWidth+1);
  if(y + radius > m_iHeight-1) bottom-= (y+radius-m_iHeight+1);

  for(cy = top; cy < bottom; cy++)
  {
    for(cx = left; cx < right; cx++)
    {
      square = cy*cy + cx*cx;
      if(square < radsquare)
      {
        dist = int(sqrt(square*length));
        newptr[m_iWidth*(cy+y) + cx+x]
          += (int)((cos(dist)+0xffff)*(height)) >> 19;
      }
    }
  }
}

// ---------------------------------------------------------
//	名称: DrawWaterNoLight
//	功能: 暗色处理水纹,并真正交它放入目标位图中(未用)
//	参数: page -- 所在页,pSrcImage -- 源位图,pTargetImage -- 目标位图
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::DrawWaterNoLight(int page,DWORD* pSrcImage,DWORD* pTargetImage)
{

//  int ox, oy;
  int dx, dy;
  int x, y;
  DWORD c;

  int offset=m_iWidth + 1;

  int *ptr = &m_iHeightField1[0];

  for (y = (m_iHeight-1)*m_iWidth; offset < y; offset += 2)
  {
    for (x = offset+m_iWidth-2; offset < x; offset++)
    {
      dx = ptr[offset] - ptr[offset+1];
      dy = ptr[offset] - ptr[offset+m_iWidth];

	  // 绘制有阴影水纹(通过dx值)
//      c = BkGdImage[offset + WATERWID*(dy>>3) + (dx>>3)];
	  c = pSrcImage[offset + m_iWidth*(dy>>3) + (dx>>3)];

     // If anyone knows a better/faster way to do this, please tell me...
//      temp[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
	  pTargetImage[offset] = c;

      offset++;
      dx = ptr[offset] - ptr[offset+1];
      dy = ptr[offset] - ptr[offset+m_iWidth];
//    c = BkGdImage[offset + m_iWidth*(dy>>3) + (dx>>3)];
	  c = pSrcImage[offset + m_iWidth*(dy>>3) + (dx>>3)];
	  pTargetImage[offset] = c;
//      temp[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
 
    }
  }
}

// ---------------------------------------------------------
//	名称: DrawWaterWithLight
//	功能: 亮色处理水纹,并真正交它放入目标位图中
//	参数: page -- 所在页,LightModifier -- 亮度系数,
//		  pSrcImage -- 源位图,pTargetImage -- 目标位图
//	返回: 无
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
void CWaterRoutine::DrawWaterWithLight(int page, int LightModifier,DWORD* pSrcImage,DWORD* pTargetImage)
{

//  int ox, oy;
  int dx, dy;
  int x, y;
  DWORD c;

//  int offset=m_iWidth + 1;
  int offset = 0;
  long lIndex;
  long lBreak = m_iWidth*m_iHeight;

  int *ptr = &m_iHeightField1[0];

  // 修正原循环中遗漏掉部分处理,原部分已注释掉,jingzhou xu.
  // 利用原不变pSrcImage背景图中像素,经处理后放入pTargetImage效果图中
  for (y = m_iHeight*m_iWidth; offset < y; )		//y = (m_iHeight-1)*m_iWidth; offset < y; offset += 2)
  {
    for (x = offset+m_iWidth; offset < x; offset++)	//x = offset+m_iWidth-2; offset < x; offset++)
    {
      dx = ptr[offset] - ptr[offset+1];
      dy = ptr[offset] - ptr[offset+m_iWidth];

	  lIndex = offset + m_iWidth*(dy>>3) + (dx>>3);
	  if(lIndex < lBreak && lIndex >= 0)
	  {
		  c = pSrcImage[lIndex];// - (dx>>LightModifier);
		 
		  c = GetShiftedColor(c,dx);

 		  pTargetImage[offset] = c;
 	  }

      offset++;
      dx = ptr[offset] - ptr[offset+1];
      dy = ptr[offset] - ptr[offset+m_iWidth];

	  lIndex = offset + m_iWidth*(dy>>3) + (dx>>3);
	  if(lIndex < lBreak && lIndex >= 0)
	  {
		  c = pSrcImage[lIndex];// - (dx>>LightModifier);
		  c = GetShiftedColor(c,dx);
	//      temp[offset] = (c < 0) ? 0 : (c > 255) ? 255 : c;
		  pTargetImage[offset] = c;
	  }
 
    }
  }
 
}

// ---------------------------------------------------------
//	名称: GetShiftedColor
//	功能: 获取差值颜色
//	参数: COLORREF -- 源颜色,shift -- 差值
//	返回: 目标颜色
//	修改: 徐景周,2002.4.8
// ---------------------------------------------------------
inline COLORREF CWaterRoutine::GetShiftedColor(COLORREF color,int shift)
{
	long R;
	long G;
	long B;
	int ir;
	int ig;
	int ib;

	R = GetRValue(color)-shift;
	G = GetGValue(color)-shift;
	B = GetBValue(color)-shift;

	ir = (R < 0) ? 0 : (R > 255) ? 255 : R;
	ig = (G < 0) ? 0 : (G > 255) ? 255 : G;
	ib = (B < 0) ? 0 : (B > 255) ? 255 : B;

	return RGB(ir,ig,ib);
}

// ---------------------------------------------------------
//	名称: DrawDiffuse
//	功能: 类似油画扩散效果(以像素周围4x4方阵随机像素添充)
//	参数: pSrcImage -- 源不变图数据地址,pTargetImage -- 目标效果图数据地址
//	返回: 无
//	编写: 徐景周,2002.1.8
// ---------------------------------------------------------
void CWaterRoutine::DrawDiffuse(DWORD* pSrcImage,DWORD* pTargetImage)
{
	int i,j,k;
	DWORD c;

	// 以时间为随机数种子
//	srand(static_cast<unsigned int>(time(NULL)));
	double f = RAND_MAX;
	for(i = 2;i < m_iWidth; ++i)
		for(j = 2;j < m_iHeight; ++j)
		{
			k = static_cast<int>(15*(rand()/f));
			c = pSrcImage[(i+k%4-2) + (j+k/4-2)*m_iWidth];
			pTargetImage[i+j*m_iWidth] = c;
		}
}