/* 像素是指由图像的小方格组成的,是图像的最小单位,以一个单一颜色的小格存在。 */ #include <graphics.h> #include <conio.h> #include <stdio.h> //将图片转换为马赛克效果 //算法:求出每个小方块内所有像素的颜色平均值,然后用来设置为该小方块的颜色。 //依次处理每个小方块,即可实现马赛克效果。 //pimg:图片地址 tilesize:方块尺寸 startx,starty:起始坐标 void Mosaic(IMAGE *pimg, int tilesize, int startx, int starty) { int width = pimg->getwidth(); // 获取图像的宽 640 int height = pimg->getheight(); // 获取图像的高 480 int redsum; // 红色值的和 int greensum; // 绿色值的和 int bluesum; // 蓝色值的和 int count; // 每个小方块内的像素数量 int color; // 每个像素的颜色 int x, y, tx, ty; // 循环变量 // 获取指向显存的指针 DWORD* pMem = GetImageBuffer(pimg); // 求出左上角第一个方块的坐标 startx = (startx % tilesize == 0 ? 0 : startx % tilesize - tilesize);//0 starty = (starty % tilesize == 0 ? 0 : starty % tilesize - tilesize);//0 // 处理每一个小方块 for (y = starty; y < height; y += tilesize)//0-10-20...480 for (x = startx; x < width; x += tilesize)//0-10-20...640 { // 清空累加值 redsum = greensum = bluesum = count = 0; // 求小方块的红、绿、蓝颜色值的和 //遍历小方块每一个像素点 for (ty = min(y + tilesize, height) - 1; ty >= max(y, 0); ty--)//9-8-7...0 for (tx = min(x + tilesize, width) - 1; tx >= max(x, 0); tx--)//9-8-7...0 { color = pMem[ty * width + tx];//9*640+9 给每一个像素点赋值 redsum += GetRValue(color);//求出三原色的值 greensum += GetGValue(color); bluesum += GetBValue(color); count++;//像素点的数量 } // 求红、绿、蓝颜色的平均值 redsum /= count; greensum /= count; bluesum /= count; // 设置小方块内的每个像素为平均颜色值 color = RGB(redsum, greensum, bluesum); //遍历每一个小方块 for (ty = min(y + tilesize, height) - 1; ty >= max(y, 0); ty--) for (tx = min(x + tilesize, width) - 1; tx >= max(x, 0); tx--) pMem[ty * width + tx] = color;//讲求出的整个方块像素的平均值赋给方块 } } // 将图片进行模糊处理 //算法:遍历图片像素,将每个像素颜色值与其周围像素颜色值求和,取平均值对其赋值 void Blur(IMAGE *pimg) { DWORD* pMem = GetImageBuffer(pimg);// 获取指向显存的指针 COLORREF color; int r, g, b; int num = 0;//像素点位置 int width = pimg->getwidth();//获取图像的宽度 int height = pimg->getheight();//获取图像的高度 int m, n, i;//循环变量 // 计算 9 格方向系数 -641 -640 -639 -1 0 1 639 640 641 int cell[9] = { -(width + 1), -width, -(width - 1), -1, 0, 1, width - 1, width, width + 1 }; // 逐个像素点读取计算 640*480-1 0 for (i = width * height - 1; i >= 0; i--) { // 累加周围 9 格颜色值 for (n = 0, m = 0; n < 9; n++) { // 位置定位 num = i + cell[n];//640*480-1-641 640*480-1-640 640 // 判断位置值是否越界 if (num < 0 || num >= width * height) { color = RGB(0, 0, 0); // 将越界像素赋值为0 m++; // 统计越界像素数 } else color = pMem[num];//讲当前像素点的颜色值赋给color // 累加颜色值 r += GetRValue(color); g += GetGValue(color); b += GetBValue(color); } // 将平均值赋值该像素 pMem[i] = RGB(r / (9 - m), g / (9 - m), b / (9 - m)); r = g = b = 0; } } // 底片效果 /* 底片效果使用如下公式: pMem[i] = (~pMem[i]) & 0x00FFFFFF */ void ColorInvert(IMAGE *pimg) { // 获取指向显存的指针 DWORD* pMem = GetImageBuffer(pimg); // 直接对显存赋值,遍历每一个像素点 for (int i = pimg->getwidth() * pimg->getheight() - 1; i >= 0; i--) pMem[i] = (~pMem[i]) & 0x00FFFFFF;//111111111111 000011111111 /* 分析操作数0x00ffffff的二进制值为32位,最高8位为0,其余为1,综合按位与的运算规则, 可以知道结果的最高8位为0,剩余24位与左边操作数的低24位值相同。 于是a&0x00ffffff就是取a的低24位,即低3字节的值。 比如0x12345678 & 0x00ffffff = 0x00345678。 */ } // 彩色图像转换为灰度图像 /* 灰度图是指只含亮度信息,不含色彩信息的图象 彩色转换为灰度使用如下公式: Gray = R * 0.299 + G * 0.587 + B * 0.114 为了提高运算速度,将这个公式转换为整数运算: Gray = (R * 229 + G * 587 + B * 114 + 500) / 1000 */ void ColorToGray(IMAGE *pimg) { DWORD *p = GetImageBuffer(pimg); COLORREF c; // 逐个像素点读取计算 for (int i = pimg->getwidth() * pimg->getheight() - 1; i >= 0; i--) { c = BGR(p[i]);//用于交换颜色中的蓝色和红色 c = (GetRValue(c) * 299 + GetGValue(c) * 587 + GetBValue(c) * 114 + 500) / 1000; p[i] = RGB(c, c, c); // 由于是灰度值,无需再执行 BGR 转换 } } // 主函数 void main() { // 初始化绘图环境 initgraph(640, 480); // 获取图像 IMAGE img; loadimage(&img, _T("1.jpg")); // 显示原始图像 putimage(0, 0, &img); // 任意键执行11111 //_getch(); setbkmode(0); settextcolor(BLACK); outtextxy(200, 150, "请选择要对图片进行的处理:"); outtextxy(250, 200, "a.马赛克效果"); outtextxy(250, 250, "b.模糊效果"); outtextxy(250, 300, "c.底片效果"); outtextxy(250, 350, "d.灰度效果"); switch (_getch()) { case 'a': // 将图片转换为马赛克效果 Mosaic(&img, 10, 0, 0); // 显示处理后的图像 putimage(0, 0, &img); break; case 'b': // 模糊处理 10 次 for (int m = 0; m < 10; m++) Blur(&img); // 显示处理后的图像 putimage(0, 0, &img); break; case 'c': // 底片效果 ColorInvert(&img); // 显示处理后的图像 putimage(0, 0, &img); break; case 'd': // 处理图像为灰度 ColorToGray(&img); // 显示处理后的图像 putimage(0, 0, &img); break; default: loadimage(&img, _T("1.jpg")); // 显示原始图像 putimage(0, 0, &img); break; } // 任意键关闭绘图环境 _getch(); closegraph(); }