• 图像处理加强版


    /*
    像素是指由图像的小方格组成的,是图像的最小单位,以一个单一颜色的小格存在。
    */
    #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();
    }
  • 相关阅读:
    Tree
    a letter and a number
    A problem is easy
    connect设置超时的方法
    C++客户端访问Java服务端发布的SOAP模式的WebService接口
    gSoap的“error LNK2001: 无法解析的外部符号 _namespaces”解决方法
    先序序列和后序序列并不能唯一确定二叉树
    二叉树的非递归遍历
    web service,soap ,http,tcp,udp
    byte[]数组和int之间的转换
  • 原文地址:https://www.cnblogs.com/506941763lcj/p/9880261.html
Copyright © 2020-2023  润新知