C语言练习18---百变女神

在C语言基础语法第十篇中,我们介绍了 二进制 位运算,即 &,|,~ 。 在机缘巧合下,我又了解到图片处理与二进制的关系,在此分享一下。

我们的每一张图片都是有许许多多个像素点组成,如图所示:

那么像素点,到底是什么呢,他与我们的二进制又有什么关系呢?

像素点的存储分好多种,我只说我了解到的,毕竟咱也不是专门搞图像,对这方面只是有所了解

一个像素点按四字节存储,也就是一个int的大小,前8位表示透明度,后面依次如图所示。

红,绿,蓝为三原色,利用这三种颜色可以调出256*256*256=16777216种颜色

 接下来就是我们的百变女神上场!

先在网上搜索一张美女图片保存在项目文件中

如图所示:

 原图:

变黑白: 

#include <stdio.h>
#include <easyx.h>

int main()
{
   //定义一张图片
	IMAGE Bety_img;
	loadimage(&Bety_img, "1.jpg");      //将图片保存在Bety_img中
	int width = Bety_img.getwidth();    //宽度
	int height = Bety_img.getheight();  //高度
	initgraph(width,height);            //创建一个和照片一样大的窗口
	putimage(0, 0, &Bety_img);          //图片贴在窗口上

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			int color = getpixel(x, y); //获取像素点

			int red = (color >> 16) & 0xff;

			int green = (color >> 8) & 0xff;

			int blue = color & 0xff;
			//黑白
			int rgb = (red + green + blue) / 3;
			
			color = (rgb << 16) + (rgb << 8) + rgb;
		
			putpixel(x, y, color);   //每次输出一个像素点
		}
	}

	system("pause");
	return 0;
}

再变:

#include <stdio.h>
#include <easyx.h>

int main()
{
   //定义一张图片
	IMAGE Bety_img;
	loadimage(&Bety_img, "1.jpg");      //将图片保存在Bety_img中
	int width = Bety_img.getwidth();    //宽度
	int height = Bety_img.getheight();  //高度
	initgraph(width,height);            //创建一个和照片一样大的窗口
	putimage(0, 0, &Bety_img);          //图片贴在窗口上

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			int color = getpixel(x, y); //获取像素点

			int red = (color >> 16) & 0xff;

			int green = (color >> 8) & 0xff;

			int blue = color & 0xff;
			//黑白
			int rgb = (red + green + blue) / 3;
			//反色
			rgb = 255 - rgb;
			color = (rgb << 16) + (rgb << 8) + rgb;
		
			putpixel(x, y, color);   //每次输出一个像素点
		}
	}

	system("pause");
	return 0;
}

 

 接下来就是我们的马赛克女神

思路:

 白色方格中像素点的个数和放大后成马赛克状的像素点的个数相同

观察不难发现,马赛克图里的色彩几乎相同,以上图为例,我们只要取出小方格里像素点颜色的数据,然后红,绿,蓝分别求和,再除以小方格里像素点的个数,最后再将平均后的像素点一个一个的填回小方格,就成了马赛克!

若是整张图打马赛克,划分多个小格子,亦是同样的道理

 

#include <stdio.h>
#include <easyx.h>

int main()
{
   //定义一张图片
	IMAGE Bety_img;
	loadimage(&Bety_img, "1.jpg");      //将图片保存在Bety_img中
	int width = Bety_img.getwidth();    //宽度
	int height = Bety_img.getheight();  //高度
	initgraph(width,height);            //创建一个和照片一样大的窗口
	putimage(0, 0, &Bety_img);          //图片贴在窗口上
	getchar();
	int size = 5;       //小方格的边长
	int redsum = 0;     //红色总和
	int greensum = 0;   //绿色和
	int bluesum = 0;    //蓝色总和
	int count = 0;          //一个格子中像素点的总和,有些边上的像素点不在格子内
	int color = 0;      //像素点数据
	        //划分小方格
	for (int y = 0; y < height; y += size)
	{
		for (int x = 0; x < width; x += size)
		{
			  //数据清零
			redsum = greensum = bluesum = count = 0;  
		      //具体找到小格子内像素点在图片的位置(以图片为坐标系)
			for (int lat_y = y; lat_y < min(y + size, height); lat_y++)
			{
				
				for (int lat_x = x; lat_x < min(x + size, width); lat_x++)
				{
					color = getpixel(lat_x, lat_y);       //获取像素点
					redsum += (color >> 16) & 0xff;
					greensum += (color >> 8) & 0xff;
					bluesum += color & 0xff;
					count++;
				}
			}  //这个循环结束小格子里的数据统计完成

			redsum /= count;
			greensum /= count;
			bluesum /= count;
				//将平均后的像素点填回小方格
				color = (redsum << 16) + (greensum << 8) + bluesum;
				for (int lat_y = y; lat_y < min(y + size, height); lat_y++)
				{
					redsum = greensum = bluesum = count = 0;
					for (int lat_x = x; lat_x < min(x + size, width); lat_x++)
					{
						putpixel(lat_x, lat_y, color);
					}
				}
			}
		}
	
	system("pause");
	return 0;
}

getchar ()后~

 是不是很神奇?

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值