图像特效之图像水彩特效
转载于风吹夏天博客
作者 | 日期 | 联系方式 |
---|---|---|
风吹夏天 | 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;
}
处理效果: