栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

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

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

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

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

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

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

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

如图所示:

 原图:

变黑白: 

#include 
#include 

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 
#include 

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 
#include 

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 ()后~

 是不是很神奇?

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/690601.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号