4.保留一点颜色,理解调色板

其实在第二节我们已经介绍了调色板,在那里我们将图像进行了反色,我们采用的其中一种方法是把调色板

进行反色。

在这里我们介绍一下如何在调色板里保留一些颜色,这样我们可以在图像上画图,有利于显示。

先介绍我们这一期的画图函数

 

描绘细节点函数(细节点是指纹中的一个概念,在后续文章中会介绍)

,这个函数可以指定一个坐标位置x,y,把图像上这个点的附近画一个小圆圈。

像素值是1。
void paint_min(unsigned char *pImg, int x, int y, int w, int h)
{
 if(x<2 || y<2 || x>w-3 || y>h-3) return;
 pImg[(y-1)*w+x-2]=1;
 pImg[   y *w+x-2]=1;
 pImg[(y+1)*w+x-2]=1;
 pImg[(y+2)*w+x-1]=1;
 pImg[(y+2)*w+ x ]=1;
 pImg[(y+2)*w+x+1]=1;
 pImg[(y+1)*w+x+2]=1;
 pImg[  y  *w+x+2]=1;
 pImg[(y-1)*w+x+2]=1;
 pImg[(y-2)*w+x+1]=1;
 pImg[(y-2)*w+ x ]=1;
 pImg[(y-2)*w+x-1]=1;
}
画矩形函数,这个函数描绘了一个像素值为color的函数

void draw_rect(unsigned char *pImg, int x0, int y0, int x1, int y1, int w, int h, int color)
{
 int i, j;
 
 if(x0<0 || x1>w-1 || y0<0 || y1>h-1) return;
 for(i=y0; i<y1; i++)
 {
  pImg[i*w+x0]=color;
  pImg[i*w+x1]=color;
 }
 for(j=x0; j<x1; j++)
 {
  pImg[y0*w+j]=color;
  pImg[y1*w+j]=color;
 }
}

 

接下来是另外一个保存图像的函数,这里我们改变了调色板1,2,3,分别保留为红颜色,绿颜色,蓝颜色

void write_color_bmp(const char* pszFileName,  unsigned char* pImg, int w, int h)
{   
 BITMAPFILEHEADER bfh;   
 BITMAPINFOHEADER bmh;
 RGBQUAD bmiColors[256];
 FILE* fp;
 int i; 
 
 fp=fopen(pszFileName, "wb");
 if(fp==NULL) return; 
 //写位图文件头 
 bfh.bfType       = 0x4d42;
 bfh.bfSize       = GET_ALIGN(w)*h+1078;
 bfh.bfOffBits    = 1078;  bfh.bfReserved1=0; 
 bfh.bfReserved2  = 0;   
 //设置位图参数   
 bmh.biSize       = 40;   
 bmh.biWidth      = w;   
 bmh.biHeight     = h;   
 bmh.biPlanes     = 1;   
 bmh.biBitCount    = 8;   
 bmh.biCompression = 0;   
 bmh.biSizeImage   = GET_ALIGN(w)*h;   
 bmh.biXPelsPerMeter = 0;  
 bmh.biYPelsPerMeter = 0;   
 bmh.biClrUsed      = 0;   
 bmh.biClrImportant = 0;
 //创建256个灰度调色板  
 for(i=0; i<256; i++) 
 {   
  bmiColors[i].rgbRed   = (BYTE)i;   
  bmiColors[i].rgbGreen = (BYTE)i;   
  bmiColors[i].rgbBlue  = (BYTE)i; 
 } 

 //调色板1为红颜色

 bmiColors[1].rgbRed   = 255;   
 bmiColors[1].rgbGreen = 0;   
 bmiColors[1].rgbBlue  = 0; 

//调色板2为绿颜色

 bmiColors[2].rgbRed   = 0;   
 bmiColors[2].rgbGreen = 255;   
 bmiColors[2].rgbBlue  = 0; 

//调色板3为蓝颜色

 bmiColors[3].rgbRed   = 0;   
 bmiColors[3].rgbGreen = 0;   
 bmiColors[3].rgbBlue  = 255; 

 fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fp);
 fwrite(&bmh, sizeof(BITMAPINFOHEADER), 1, fp);
 fwrite(bmiColors, sizeof(RGBQUAD), 256, fp); //行倒过来,对齐后写入
 for(i=0; i<h; i++)
 { 
  fwrite(pImg+(h-i-1)*w, 1, GET_ALIGN(w), fp);  
 }
 fclose(fp);
}

 

接下来是我们的测试代码,注意我们要画颜色的时候最好要把保留的像素改变成近似的颜色。

比如我们这里保留了调色板1,2,3,在原先灰度图里,1,2,3其实和颜色0的纯黑色是非常接近的。

int step4(void)
{
 int w, h, i;
 unsigned char *pImg;

 printf("step4: reserve color!/n");
 pImg= read_bmp("test.bmp", &w, &h);
 if(pImg==NULL) return -1;

//把原始像素值为1,2,3的全部设置为0

 for(i=0; i<w*h; i++)
 {
  if(pImg[i]==1 || pImg[i]==2 || pImg[i]==3) pImg[i]=0;
 }
 paint_min(pImg, 98, 79, w, h);
 paint_min(pImg, 49, 87, w, h);
 draw_rect(pImg,10,10,110,110,   w, h, 2);
 draw_rect(pImg,174,156,194,176, w, h, 3);
 write_color_bmp("test_color.bmp", pImg, w, h);
 return 1;
}

这是输出的测试结果,可以看到我们画出了2个红色的小圈,一个绿色的大矩形框,一个蓝色的矩形框

4.保留一点颜色,理解调色板

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值