图像特效之水彩特效

图像特效之图像水彩特效

转载于风吹夏天博客

作者日期联系方式
风吹夏天2015年10月31日wincoder#qq.com


关键代码实现:

int OilPaint(IMAGE_TYPE *bmp_img,int brushSize, int coarseness)
{
	DWORD width,height,dst_index,index,top,bottom,left,right;
	WORD  biBitCount;
	T_U8 *bmp_data,Gray,R,G,B,*GrayImage,*Result_img,BytePerPixel = 3;
	T_U32 line_byte,*RedAverage,*GreenAverage,*BlueAverage;
	T_U16 i,j,m,n,k;
	T_U8 chosenIntensity,intensity ;
	int lenArray,*CountIntensity,maxInstance;
	
	BITMAPFILEHEADER bf;
	BITMAPINFOHEADER bi;

	FILE *OilPaint_BMP_fp = fopen("OilPaint_BMP.bmp","wb");
	
	if(NULL == OilPaint_BMP_fp)
	{
		printf("Can't open OilPaint_BMP.bmp\n");
		return -1;
	}

	if (brushSize < 1) brushSize = 1;
    if (brushSize > 8) brushSize = 8;

    if (coarseness < 1) coarseness = 1;
    if (coarseness > 255) coarseness = 255;
	

	memset(&bf, 0, sizeof(bf));
	memset(&bi, 0, sizeof(bi));

	memcpy(&bf,bmp_img,14);
	memcpy(&bi,&bmp_img[14],40);

	height = bi.biHeight;
	width  = bi.biWidth;
	biBitCount = bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
	line_byte =(width*3+3) & ~0x3;

	fwrite(&bf,sizeof(BITMAPFILEHEADER),1,OilPaint_BMP_fp);
	fwrite(&bi,sizeof(BITMAPINFOHEADER),1,OilPaint_BMP_fp);


	lenArray =  coarseness + 1;
	CountIntensity = (int *)malloc(lenArray*sizeof(int));
	RedAverage = (T_U32*)malloc(lenArray*sizeof(T_U32));
	GreenAverage = (T_U32*)malloc(lenArray*sizeof(T_U32));
	BlueAverage = (T_U32*)malloc(lenArray*sizeof(T_U32));
	GrayImage = (T_U8*)malloc(height*line_byte*sizeof(T_U8));
	Result_img = (T_U8*)malloc(height*line_byte*sizeof(T_U8));



	if(GrayImage == NULL || CountIntensity == NULL || RedAverage == NULL || GreenAverage == NULL ||\
		            BlueAverage == NULL || Result_img == NULL)
	{
		printf("Can't malloc for programm!\n");
		return -1;
	}

	
	memset(GrayImage,0,height*line_byte*sizeof(T_U8));
	memset(Result_img,0,height*line_byte*sizeof(T_U8));

	bmp_data = bmp_img + BMPHEADSIZE;
	
        //转换为灰度图像
	for(i = 0;i < height;i++) 
	{
		
		for(j = 0; j < width;j++)
		{
			index = i*line_byte+3*j;
			B = bmp_data[index];
			G = bmp_data[index+1];
			R = bmp_data[index+2];
			Gray = (T_U8)((R*19661 + G*38666 + B*7409) >> 16);

			GrayImage[index] = Gray;
			GrayImage[index+1] = Gray;
			GrayImage[index+2] = Gray;
		}
	}

	
	for(i = 0;i < height;i++)
	{
		
		top = i - brushSize;
		bottom = i+brushSize+1;

		if(top<0) top = 0;
        if(bottom >=height) bottom = height - 1;
		dst_index = i*line_byte;
		for(j = 0;j < width;j++)
		{
			
			left = j - brushSize;
			right = j + brushSize+1;

			if(left<0) left = 0;
            if(right>=width) right = width - 1;

              //数组初始化
			for(m = 0; m < lenArray;m++)
			{
				CountIntensity[m] = 0;
				RedAverage[m] = 0;
				GreenAverage[m] = 0;
				BlueAverage[m] = 0;
			}

			for(m = top;m < bottom;m++)
			{
				for(n = left;n < right;n++)
				{
					index = m*line_byte+3*n;
					intensity = CLIP255((int)(coarseness*GrayImage[index]/255.0));
					CountIntensity[intensity]++;

					 BlueAverage[intensity] += bmp_data[index];
					 GreenAverage[intensity]+= bmp_data[index+1];
					 RedAverage[intensity]  += bmp_data[index+2];

				}
			}

			 chosenIntensity = 0;
			 maxInstance = CountIntensity[0];
			 for(k=1;k<lenArray;k++)
			  {
				 if(CountIntensity[k]>maxInstance)
				 {
					chosenIntensity = (T_U8)k;
					maxInstance = CountIntensity[k];
				  }
			 }

                       //按照参考博文,计算出来得maxInstance有时候会为0,需要做处理
			 if(maxInstance == 0)
			{
					 Result_img[dst_index] = bmp_data[dst_index];
					 Result_img[dst_index+1] = bmp_data[dst_index+1];
					 Result_img[dst_index+2] = bmp_data[dst_index+2];
			 }
			 else
			{
				Result_img[dst_index]   = CLIP255((int)(BlueAverage[chosenIntensity] / ((float)(maxInstance))));
				Result_img[dst_index+1] = CLIP255((int)(GreenAverage[chosenIntensity] /((float) (maxInstance))));
				Result_img[dst_index+2] = CLIP255((int)(RedAverage[chosenIntensity] / ((float)(maxInstance))));
			 }


			 dst_index = dst_index + BytePerPixel;
		}
	}
	

    fwrite(Result_img, line_byte*height*sizeof(T_U8), 1, OilPaint_BMP_fp);
    fclose(OilPaint_BMP_fp);  
    free(Result_img);
    free(GrayImage);
   free(GrayImage);
   free(RedAverage);
   free(GreenAverage);
   free(BlueAverage);
   free(CountIntensity);
 return 0;
}

处理效果:



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值