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

typedef struct {

  REAL m[][];

} ColorMatrix;

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

获取对应编码器的CLSID
   int GetEncoderClsid(const WCHAR* format, CLSID* pClisd); // 获取对应编码器的CLSID

  int CMyDlg::GetEncoderClsid(const WCHAR* format, CLSID* pClisd) // 获取对应编码器的CLSID
{
  UINT num = ; // 图像编码器的数量
  UINT size = ; // 图像编码器数组的字节数   Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
  GetImageEncodersSize(&num, &size);
  if (size == )
  return -;
  pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));   GetImageEncoders(num, size, pImageCodecInfo);
  for(UINT j = ;j<num;++j)
  {
    if (wcscmp(pImageCodecInfo[j].MimeType, format) == )
    {
      *pClisd = pImageCodecInfo[j].Clsid;
      free(pImageCodecInfo);
      return j;
    }
  }
  free(pImageCodecInfo);
  return -;
}

一、改变图像的透明度:只需要缩放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(, , nWidth, nHeight);
  // 利用新图像对象绘制
  Graphics graph(&image);   // 构建颜色变化矩阵
  ColorMatrix colorMatrix = {
  , , , , ,
  , , , , ,
  , , , , ,
  , , , alpha, ,
  , , , ,
  };   ImageAttributes imageAttr;
  imageAttr.SetColorMatrix(&colorMatrix);   // 运用颜色变换矩阵绘制新图像
  graph.DrawImage(&bitmap, rect, , , nWidth, nHeight, UnitPixel, &imageAttr);   CLSID encoderClsid; // 文件编码器的CLSID
  CString strExt = savePath.Right();
  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.587f, 0.587f, 0.587f, , ,
    0.114f, 0.114f, 0.114f, , ,
    , , , , ,
    , , , ,
  };

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

// brightness 为亮度变化量

  REAL f = brightness / 255.0f;
  // 构建颜色变化矩阵
  ColorMatrix colorMatrix = {
    , , , , ,
    , , , , ,
    , , , , ,
    , , , , ,
    f, f, f, ,
  };

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

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

  Rt = 128 + (R - 128)f

  Gt = 128 + (G -128)f

  Bt = 128+ (B - 128)f 

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

利用GDI+处理图像的色彩的更多相关文章

  1. 利用GDI+处理图像,包括图像的的裁剪显示、转置、镜像、简单旋转、变形等。

    一.图像的裁剪显示:有时程序需要显示图像的一部分而不是全部.实例代码如下: CDC* pDC = GetDC(); Graphics graph(pDC->GetSafeHdc()); Imag ...

  2. 超全面的.NET GDI+图形图像编程教程

    本篇主题内容是.NET GDI+图形图像编程系列的教程,不要被这个滚动条吓到,为了查找方便,我没有分开写,上面加了目录了,而且很多都是源码和图片~ (*^_^*) 本人也为了学习深刻,另一方面也是为了 ...

  3. 利用OpenCV给图像添加中文标注

    利用OpenCV给图像添加中文标注 : 参考:http://blog.sina.com.cn/s/blog_6bbd2dd101012dbh.html  和https://blog.csdn.net/ ...

  4. [转]超全面的.NET GDI+图形图像编程教程

    本篇主题内容是.NET GDI+图形图像编程系列的教程,不要被这个滚动条吓到,为了查找方便,我没有分开写,上面加了目录了,而且很多都是源码和图片~ GDI+绘图基础 编写图形程序时需要使用GDI(Gr ...

  5. 学习笔记:利用GDI+生成简单的验证码图片

    学习笔记:利用GDI+生成简单的验证码图片 /// <summary> /// 单击图片时切换图片 /// </summary> /// <param name=&quo ...

  6. C#利用GDI+绘制旋转文字等效果

    C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经 ...

  7. 8 个优秀的 Linux 图形图像及色彩工具

    8 个优秀的 Linux 图形图像及色彩工具 1. 硬件色彩分析器LPROF LPROF 是一个用于创建设备兼容,如相机.扫描仪.显示器的ICC兼容型材的颜色分析器.这些配置提供跨设备的色彩一致性.他 ...

  8. 利用matlab求图像均值和方差的几种方法

    一.求均值 % 求一副灰度图像的均值 close all; clear; clc; i=imread('d:/lena.jpg'); %载入真彩色图像 i=rgb2gray(i); %转换为灰度图 i ...

  9. OpenCV与Python之图像的读入与显示以及利用Numpy的图像转换

    1:读入图像,显示图像与保存图像 代码: import cv2 img=cv2.imread('lena.jpg',cv2.IMREAD_COLOR) cv2.namedWindow('lena',c ...

随机推荐

  1. Python之路(第十六篇)xml模块、datetime模块

    一.xml模块 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单, xml比较早,早期许多软件都是用xml,至今很多传统公司如金融行业的很多系统的接口还主要 ...

  2. 爬虫初窥day3:BeautifulSoup

    信息提取 1.通过Tag对象的属性和方法 #!/usr/bin/python # -*- coding: utf- -*- from urllib.request import urlopen fro ...

  3. redis在游戏服务器中的使用初探(三) 信息存储

    摘要: 搭建了服务器环境 有了客户端 我们来假想下以下应用场景:我们简单举个实例来描述下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:用户ID,为查找的key,存储的value ...

  4. android udp 无法收到数据 (模拟器中)

    解决方法:1. 运行模拟器2. 打开window 命令行执行:telnet localhost 55545554是模拟器的端口,执行之后会进入android console3. 在console下执行 ...

  5. SWE_Browser编译

    QRD从android4.4开始使用SWE_Browser,android原始代码中不再提供Browser.最近在做一个QRD8916_113517 CMCC入库版本,需要使用SWE_Browser. ...

  6. 【转】C#异步的世界【下】

    [转]C#异步的世界[下] 接上篇:<C#异步的世界[上]> 上篇主要分析了async\await之前的一些异步模式,今天说异步的主要是指C#5的async\await异步.在此为了方便的 ...

  7. 2017/2/12:springMVC的简单文件上传跟拦截器

    1.写文件上传的界面jsp代码如下重点为文件上传标签的类型 2.写登录成功跟失败的界面:成功自己写 3.写springMVC的文件上传的controller的方法 4.最后一步配置spring-ser ...

  8. 【Go】 Go 语言环境安装

    安装环境/工具 1.Linux(CentOS 7.4版) 2.go1.11.2.linux-amd64.tar Go 语言环境安装 1.下载安装包 安装包下载地址为:https://golang.or ...

  9. android c 读写文件

    1.包含头文件 #include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcn ...

  10. tms web core 通过URL 传递参数

    一般我们都会通过URL 给服务器传递很多参数,通过参数来决定对应的处理,今天就大概讲一下 如果通过URL 参数实现一些功能. 1.通过参数跳入不同的界面 首先我们先建立一个tms web core 工 ...