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



