C++将图片转换为马赛克效果
1. 算法原理
求出每个小方块内所有像素的颜色平均值,然后用来设置为该小方块的颜色。依次处理每个小方块,即可实现马赛克效果
原图
2. 整张图片处理成马赛克效果
#include "stdafx.h"
#include <graphics.h>
#define N 8
int main()
{
//Step1: 加载图片
IMAGE image;
loadimage(&image, L"C:\\test\\image.jpg");
initgraph(image.getwidth(), image.getheight()); //用图片的大小初始化窗口大小
putimage(0, 0, &image);
//Step2: 对图片经行处理
for (int i = 0; i < image.getheight(); i += N) //遍历整张图片, 步长为N, 即将整张图片分割成若干张N*N大小的小方格,再对每一个N*N的方格依次处理
for (int j = 0; j < image.getwidth(); j += N)
{
int red = 0, green = 0, blue = 0;
for (int x = i; x < i + N; x++) //遍历该小方格(大小: N*N)
for (int y = j; y < j + N; y++)
{
COLORREF color = getpixel(y, x); //用于获取该点的颜色
red += GetRValue(color); //提取该点颜色的red值
green += GetGValue(color);
blue += GetBValue(color);
}
red /= N*N; //求平均
green /= N*N;
blue /= N*N;
setfillcolor(RGB(red, green, blue)); //将平均后的颜色设置为当前填充色(只是设置,并没有填充)
solidrectangle(j, i, j + N, i + N); //填充该小方格(开始填充)
}
//Step3: 保存处理后的图片
saveimage(L"C:\\test\\mosaic.jpg");
closegraph();
return 0;
}
效果
3. 通过鼠标选取区域填充马赛克
#include "stdafx.h"
#include <graphics.h>
#define N 8
int main()
{
//Step1: 加载图片
IMAGE image;
loadimage(&image, L"C:\\test\\image.jpg");
initgraph(image.getwidth(), image.getheight()); //用图片的大小初始化窗口大小
putimage(0, 0, &image);
//Step2: 监听鼠标消息
MOUSEMSG m;
while (true)
{
// 获取一条鼠标消息
m = GetMouseMsg();
switch (m.uMsg)
{
case WM_MOUSEMOVE:
if (m.mkLButton)
{
//Step3: 对图片区域处理
int red = 0, green = 0, blue = 0;
for (int x = m.y; x < m.y + N; x++)
for (int y = m.x; y < m.x + N; y++)
{
COLORREF color = getpixel(y, x);
red += GetRValue(color);
green += GetGValue(color);
blue += GetBValue(color);
}
red /= N * N;
green /= N * N;
blue /= N * N;
setfillcolor(RGB(red, green, blue));
solidrectangle(m.x, m.y, m.x + N, m.y + N);
}
break;
case WM_LBUTTONDOWN:
break;
case WM_RBUTTONUP:
//Step4: 保存处理后的图片
saveimage(L"C:\\test\\mosaic.jpg");
closegraph();
return 0; // 按鼠标右键退出程序
}
}
return 0;
}
效果