在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 ()后~
是不是很神奇?