zoukankan      html  css  js  c++  java
  • 利用GDI+处理图像的色彩

    首先先介绍一下ColorMatrix结构体:表示颜色的变换关系,定义如下:

    typedef struct {
    
      REAL m[5][5];
    
    } ColorMatrix;

    ColorMatrix结构体一般和ImageAttribute类配合使用,使用的方式是先调用ImageAttibute::SetColorMatrix,运用该颜色变化矩阵,然后在绘制函数中将ImageAttribute对象作为DrawImage函数参数。以下的图像色彩变换都会用到这个结构体。

    获取对应编码器的CLSID
     1  int GetEncoderClsid(const WCHAR* format, CLSID* pClisd); // 获取对应编码器的CLSID
     2 
     3 int CMyDlg::GetEncoderClsid(const WCHAR* format, CLSID* pClisd) // 获取对应编码器的CLSID
     4 {
     5   UINT num = 0; // 图像编码器的数量
     6   UINT size = 0; // 图像编码器数组的字节数
     7 
     8   Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
     9   GetImageEncodersSize(&num, &size);
    10   if (size == 0)
    11   return -1;
    12   pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
    13 
    14   GetImageEncoders(num, size, pImageCodecInfo);
    15   for(UINT j = 0;j<num;++j)
    16   {
    17     if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
    18     {
    19       *pClisd = pImageCodecInfo[j].Clsid;
    20       free(pImageCodecInfo);
    21       return j; 
    22     }
    23   }
    24   free(pImageCodecInfo);
    25   return -1;
    26 }

    一、改变图像的透明度:只需要缩放Alpha分量就能到达效果。

    BOOL ChangeImageAlpha(const CString& imagePath, REAL alpha, const CString& savePath); 
    /**********************************************************************************
    * 作用:改变指定图像的透明度,并将新图像按照指定的图像格式和路径保存
    * 参数:imagePath 为原图路径
    * alpha 为分量缩放系数
    * savePath 为用于保存处理后图像的路径
    * 返回值: 转换是否成功
    **********************************************************************************/
    BOOL CMyGDIDlg::ChangeImageAlpha(const CString& imagePath, REAL alpha, const CString& savePath)
    {
       Bitmap bitmap(imagePath);
      if (bitmap.GetLastStatus() != Ok)
      return false;
    
      int nWidth = bitmap.GetWidth();
      int nHeight = bitmap.GetHeight();
    
      // 构建新图像对象
      Bitmap image(nWidth, nHeight);
      Rect rect(0, 0, nWidth, nHeight);
      // 利用新图像对象绘制
      Graphics graph(&image);
    
      // 构建颜色变化矩阵
      ColorMatrix colorMatrix = {
      1, 0, 0, 0, 0,
      0, 1, 0, 0, 0,
      0, 0, 1, 0, 0,
      0, 0, 0, alpha, 0,
      0, 0, 0, 0, 1
      };
    
      ImageAttributes imageAttr;
      imageAttr.SetColorMatrix(&colorMatrix);
    
      // 运用颜色变换矩阵绘制新图像
      graph.DrawImage(&bitmap, rect, 0, 0, nWidth, nHeight, UnitPixel, &imageAttr);
    
      CLSID encoderClsid; // 文件编码器的CLSID
      CString strExt = savePath.Right(3);
      strExt.MakeLower();
      // 根据扩展名获得不同的CLSID
      if (strExt == _T("png"))
        GetEncoderClsid(_T("image/png"), &encoderClsid);
      else if (strExt == _T("jpg"))
        GetEncoderClsid(_T("image/jpg"), &encoderClsid);
      else 
        GetEncoderClsid(_T("image/bmp"), &encoderClsid);
    
      if (image.Save(savePath, &encoderClsid, NULL) == Ok)
        return true;
      else
        return false;
    }

    调用: ChangeImageAlpha(_T("E:\素材\jpg\1.jpg"), 0.5, _T("D:\1.png"));

    二、将图像转换为灰度图:原理就是使图中红、绿、蓝3个分量值相等。一般有3中方式:

    (1)平均值法:使每个像素的三原色值等于红、绿、蓝3分量的平均值

      R = G = B = (R + G +B) / 3

    (2)最大值法:每个像素的三原色等于红、绿、蓝3分量的最大值

      R = G = B = max(R, G, B)

    (3)加权平均值法:给予红、绿、蓝3分量不同的权值然后相加

      R = G = B = WrR + WgG + WbB

      人眼对于三原色的敏感度从高到底分别是绿、红、蓝,所以三原色权值取值关系应该是 Wg > Wr > Wb。

       依据YUV颜色空间可知当 R = G = B = 0.299R + 0.587 + 0.114B时能够的到最合理的灰度图。

      算法与前文类似,在这里只需修改一下颜色变化矩阵即可: 

     // 构建颜色变化矩阵
    
      ColorMatrix colorMatrix = {
        0.299f, 0.299f, 0.299f, 0, 0,
        0.587f, 0.587f, 0.587f, 0, 0,
        0.114f, 0.114f, 0.114f, 0, 0,
        0, 0, 0, 1, 0,
        0, 0, 0, 0, 1
      };

    三、改变图像的亮度:是通过改变红、绿、蓝颜色分量的增量来实现的。公式如下:  

    // brightness 为亮度变化量
    
      REAL f = brightness / 255.0f;
      // 构建颜色变化矩阵
      ColorMatrix colorMatrix = {
        1, 0, 0, 0, 0,
        0, 1, 0, 0, 0,
        0, 0, 1, 0, 0,
        0, 0, 0, 1, 0,
        f, f, f, 0, 1
      };

    四、改变图像的对比度:一般来说对比度越大,图像越清晰醒目,色彩也越鲜明艳丽;而对比度越小,则会让图画显得比较灰暗。

      图像的对比度变化公式如下:其中f为对比度,默认为1.

      Rt = 128 + (R - 128)f

      Gt = 128 + (G -128)f

      Bt = 128+ (B - 128)f 

     REAL f = 0.0f;
      if (contrast >= 0)
        f = (contrast + 10.0f) / 10.0f;
      else
        f = (255 + contrast) / 255.0f;
      // 构建颜色变化矩阵
      ColorMatrix colorMatrix = {
        f, 0, 0, 0, 0,
        0, f, 0, 0, 0,
        0, 0, f, 0, 0,
        0, 0, 0, 1, 0,
        0.5f*(1-f), 0.5f*(1 - f), 0.5f*(1 - f), 0, 1
      };

      

  • 相关阅读:
    【MySQL】MySQL的Sequence
    【Spring】Junit加载Spring容器作单元测试
    【Java】JDBC连接MySQL
    【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)
    【Java】Map杂谈,hashcode()、equals()、HashMap、TreeMap、LinkedHashMap、ConcurrentHashMap
    【Java】常见的Set类型,HashSet、TreeSet、LinkedHashSet
    【数据结构和算法】选择排序
    【数据结构与算法】插入排序
    【数据结构与算法】冒泡排序
    【Web】写个HTML页面去调试HTTP接口方便些
  • 原文地址:https://www.cnblogs.com/luzuwei/p/9022354.html
Copyright © 2011-2022 走看看