绿色风's Blog
专注AutoIT(Au3)
  • 首页
  • 流●年
  • 笔●记
    • 学习随记
    • 源码示例
  • 脚●本
    • UDF(收集)
    • 工作室UDF
    • 工具●教程
    • 教程之GDI
  • 作●品
  • 下●载
  • 情怀ExcelTip
2月92015

[教程]第十五讲GDI+图像之颜色矩阵

作者:绿色风   发布:2015-2-9 23:23 Monday   分类:   阅读:16652次   评论:0条  
一、GDI+图像绘制时,可以通过图像属性来改变图像
1、图像属性建立
$hIA = _GDIPlus_ImageAttributesCreate()
2、图像属性设置颜色矩阵
_GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $pColorMatrix)
$pColorMatrix为指向颜色矩阵的指针
3、根据图像属性绘制图像
_GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, 位图句柄, 源矩形区域, 目标矩形区域, $hIA)
二、颜色矩阵
_GDIPlus_ColorMatrixCreate()
例子中有几个颜色矩阵的示例
颜色矩阵网上写的较好的,地址
GDI+ for VCL基础 -- 颜色调整矩阵ColorMatrix详解
GDI+ ColorMatrix的完全揭秘
测试中发现图像属性设置颜色矩阵,只对24位色以上起作用,所以示例中增加了位深不足时,转换位深的例子

aaa.gif

#include <APIConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>
#include <GDIPlusEx.au3>
#include <GuiSlider.au3>

Global $au3Dir = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\Autoit", "InstallDir");au3安装目录
Global $imageFile = $au3Dir & '\Examples\WinAPIEx\Extras\AutoIt.bmp'

Global $hCallback = DllCallbackRegister("YourFunc", "int", "hWnd;uint;wparam;lparam");函数名,返回值,参数
Global $ptrCallback = DllCallbackGetPtr($hCallback)

Global $flag = 0
_GDIPlus_Startup()
Global $hfileBitmap = _GDIPlus_BitmapCreateFromFile($imageFile)
Global $fileW = _GDIPlus_ImageGetWidth($hfileBitmap)
Global $fileH = _GDIPlus_ImageGetHeight($hfileBitmap)
;左上角、右上角和左下角
Global $left[2] = [5, 5], $right[2] = [305, 5], $leftd[2] = [5, 305]
Global $TempBitmap = _GDIPlus_ImageClone($hfileBitmap)
Global $hBitmap
;色调,亮度,饱和度,对比度
Global $hue = 0, $Lum = 0, $Sat = 1, $Con = 1
Global $hWnd, $hPicWnd, $hOldProc
Global $color[4][2]
Global $hRestore, $hGray, $hInverse, $hRed
Global $open, $save

GuiInit()

update()

While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3
                        ExitLoop
                Case $hRestore
                        restore()
                Case $hGray
                        gray()
                Case $hInverse
                        inverse()
                Case $hRed
                        red()
                Case $open
                        open()
                Case $save
                        save()
        EndSwitch
WEnd
_GDIPlus_ImageDispose($TempBitmap)
_GDIPlus_BitmapDispose($hfileBitmap)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()
GUIDelete()
Exit

Func GuiInit()
        $hWnd = GUICreate("第十五讲GDI+图像", 500, 525)
        GUICtrlCreatePic("", 0, 0, 500, 400)
        $hPicWnd = GUICtrlGetHandle(-1)
        $hOldProc = _WinAPI_SetWindowLong($hPicWnd, $GWL_WNDPROC, $ptrCallback)

        GUICtrlCreateLabel(" 图像色调", 5, 405)
        $color[0][0] = GUICtrlCreateSlider(80, 405, 100)
        GUICtrlSetLimit(-1, 360, 0)
        GUICtrlSetData(-1, $hue)
        _GUICtrlSlider_SetTicFreq(-1, 30)
        $color[0][1] = GUICtrlCreateLabel("", 190, 405, 40, 25)
        GUICtrlSetData(-1, $hue)

        GUICtrlCreateLabel(" 图像亮度", 5, 435)
        $color[1][0] = GUICtrlCreateSlider(80, 435, 100)
        GUICtrlSetLimit(-1, 10, -10)
        GUICtrlSetData(-1, $Lum)
        _GUICtrlSlider_SetTicFreq(-1, 2)
        $color[1][1] = GUICtrlCreateLabel("", 190, 435, 40, 25)
        GUICtrlSetData(-1, $Lum)

        GUICtrlCreateLabel("图像饱和度", 5, 465)
        $color[2][0] = GUICtrlCreateSlider(80, 465, 100)
        GUICtrlSetLimit(-1, 10, 0)
        GUICtrlSetData(-1, 1)
        _GUICtrlSlider_SetTicFreq(-1, 1)
        $color[2][1] = GUICtrlCreateLabel("", 190, 465, 40, 25)
        GUICtrlSetData(-1, $Sat)

        GUICtrlCreateLabel("图像对比度", 5, 495)
        $color[3][0] = GUICtrlCreateSlider(80, 495, 100)
        GUICtrlSetLimit(-1, 100, 10)
        _GUICtrlSlider_SetTicFreq(-1, 10)
        GUICtrlSetData(-1, 10)
        $color[3][1] = GUICtrlCreateLabel("", 190, 495, 40, 25)
        GUICtrlSetData(-1, $Con)

        $hRestore = GUICtrlCreateButton("复位颜色", 250, 405)
        $hGray = GUICtrlCreateButton("灰度图", 250, 435)
        $hInverse = GUICtrlCreateButton("反色图", 250, 465)
        $hRed = GUICtrlCreateButton("红色通道", 250, 495)

        $open = GUICtrlCreateButton("打开", 350, 405, 100, 50)
        $save = GUICtrlCreateButton("保存", 350, 465, 100, 50)
        GUIRegisterMsg($WM_HSCROLL, "onHSCROLL")
        GUISetState()
EndFunc   ;==>GuiInit

Func onHSCROLL($hWnd, $iMsg, $wParam, $lParam)
        Switch $lParam
                Case GUICtrlGetHandle($color[0][0])
                        $hue = GUICtrlRead($color[0][0])
                        GUICtrlSetData($color[0][1], $hue)
                Case GUICtrlGetHandle($color[1][0])
                        $Lum = GUICtrlRead($color[1][0]) / 10
                        GUICtrlSetData($color[1][1], $Lum)
                Case GUICtrlGetHandle($color[2][0])
                        $Sat = GUICtrlRead($color[2][0])
                        GUICtrlSetData($color[2][1], $Sat)
                Case GUICtrlGetHandle($color[3][0])
                        $Con = GUICtrlRead($color[3][0])/10
                        GUICtrlSetData($color[3][1], $Con)
        EndSwitch
        ChangeColor()
EndFunc   ;==>onHSCROLL

Func YourFunc($hWnd, $iMsg, $wParam, $lParam)
        Switch $iMsg
                Case $WM_PAINT
                        Local $tPAINTSTRUCT
                        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
                        update()
                        Return _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
                Case $WM_MOUSEMOVE
                        WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
                Case $WM_LBUTTONDOWN
                        WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
                Case $WM_LBUTTONUP
                        WM_LBUTTONUP($hWnd, $iMsg, $wParam, $lParam)
        EndSwitch
        Return _WinAPI_CallWindowProc($hOldProc, $hWnd, $iMsg, $wParam, $lParam);没有处理的消息让原先的处理程序处理
EndFunc   ;==>YourFunc

Func WM_MOUSEMOVE($hWnd, $Msg, $wParam, $lParam)
        Switch $flag
                Case 1
                        $left[0] = _WinAPI_LoWord($lParam)
                        $left[1] = _WinAPI_HiWord($lParam)
                        _WinAPI_InvalidateRect($hWnd)
                Case 2
                        $right[0] = _WinAPI_LoWord($lParam)
                        $right[1] = _WinAPI_HiWord($lParam)
                        _WinAPI_InvalidateRect($hWnd)
                Case 3
                        $leftd[0] = _WinAPI_LoWord($lParam)
                        $leftd[1] = _WinAPI_HiWord($lParam)
                        _WinAPI_InvalidateRect($hWnd)
        EndSwitch
        Return 1
EndFunc   ;==>WM_MOUSEMOVE

Func WM_LBUTTONDOWN($hWnd, $Msg, $wParam, $lParam)
        Local $tPoint = _WinAPI_CreatePoint(_WinAPI_LoWord($lParam), _WinAPI_HiWord($lParam))
        $tRect = _WinAPI_CreateRect($left[0] - 3, $left[1] - 3, $left[0] + 3, $left[1] + 3)
        If _WinAPI_PtInRect($tRect, $tPoint) Then
                $flag = 1
        EndIf
        $tRect = _WinAPI_CreateRect($right[0] - 3, $right[1] - 3, $right[0] + 3, $right[1] + 3)
        If _WinAPI_PtInRect($tRect, $tPoint) Then
                $flag = 2
        EndIf
        $tRect = _WinAPI_CreateRect($leftd[0] - 3, $leftd[1] - 3, $leftd[0] + 3, $leftd[1] + 3)
        If _WinAPI_PtInRect($tRect, $tPoint) Then
                $flag = 3
        EndIf
        Return 0
EndFunc   ;==>WM_LBUTTONDOWN

Func WM_LBUTTONUP($hWnd, $Msg, $wParam, $lParam)
        $flag = 0
        Return 0
EndFunc   ;==>WM_LBUTTONUP

Func update()
        Local $HWND_CX = _WinAPI_GetWindowWidth($hPicWnd)
        Local $HWND_CY = _WinAPI_GetWindowHeight($hPicWnd)
        Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hPicWnd)
        ;==========================二次缓冲绘制开始,先把图片绘制在$hBitmap上=======================
        _GDIPlus_BitmapDispose($hBitmap)
        $hBitmap = _GDIPlus_BitmapCreateFromGraphics($HWND_CX, $HWND_CY, $hGraphics)
        Local $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFECE9D8)
        ;根据三点确定平行四边形,把图像绘制到平行四边形中
        _GDIPlus_GraphicsDrawImagePointsRect($hBackbuffer, $TempBitmap, $left[0], $left[1], $right[0], $right[1], $leftd[0], $leftd[1], _
                        0, 0, $fileW, $fileH)
        Local $hPen = _GDIPlus_PenCreate(0xFFFF0000)
        ;绘制确定平行四边形的三个点的区域,当鼠标在这区域时能拖动
        _GDIPlus_GraphicsDrawRect($hBackbuffer, $left[0] - 3, $left[1] - 3, 6, 6, $hPen)
        _GDIPlus_GraphicsDrawRect($hBackbuffer, $right[0] - 3, $right[1] - 3, 6, 6, $hPen)
        _GDIPlus_GraphicsDrawRect($hBackbuffer, $leftd[0] - 3, $leftd[1] - 3, 6, 6, $hPen)
        ;绘制图片控件的下边框,看着舒服一点
        _GDIPlus_PenSetColor($hPen, 0xFFA0A0A0)
        _GDIPlus_GraphicsDrawLine($hBackbuffer, 0, $HWND_CY - 1, $HWND_CX, $HWND_CY - 1, $hPen)
        _GDIPlus_PenDispose($hPen)
        ;==========================二次缓冲绘制结束=======================
        ;==========================把$hBitmap绘制到$pic控件画布上=======================
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $HWND_CX, $HWND_CY)  

        _GDIPlus_GraphicsDispose($hBackbuffer)
        _GDIPlus_GraphicsDispose($hGraphics)
EndFunc   ;==>update

Func ChangeColor()
        Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($TempBitmap)
        Local $hIA = _GDIPlus_ImageAttributesCreate()
        ;创建单位颜色矩阵
        Local $tColorMatrix = _GDIPlus_ColorMatrixCreate()
        Local $pColorMatrix = DllStructGetPtr($tColorMatrix)
        ;创建色调颜色矩阵
        Local $tPreHue = _GDIPlus_ColorMatrixCreate()
        Local $tPostHue = _GDIPlus_ColorMatrixCreate()
        _GDIPlus_ColorMatrixInitHue($tPreHue, $tPostHue)
        ;创建亮度颜色矩阵
        Local $tLumMatrix = _GDIPlus_ColorMatrixCreateTranslate($Lum, $Lum, $Lum)
        ;创建饱和度颜色矩阵
        Local $tSatMatrix = _GDIPlus_ColorMatrixCreateSaturation($Sat)
        ;创建对比度颜色矩阵,对比度矩阵网上说法较多,我感觉这个效果还可以
        Local $tConMatrix = _GDIPlus_ColorMatrixCreateScale($Con, $Con, $Con)
        ;矩阵相乘
        _GDIPlus_ColorMatrixMultiply($tColorMatrix, $tLumMatrix)
        _GDIPlus_ColorMatrixMultiply($tColorMatrix, $tSatMatrix)
        _GDIPlus_ColorMatrixMultiply($tColorMatrix, $tConMatrix)
        ;通过旋转$hue角度调整图像色调
        _GDIPlus_ColorMatrixRotateHue($tColorMatrix, $tPreHue, $tPostHue, $hue)
        ;设置颜色矩阵到图像属性
        _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $pColorMatrix)
        ;根据$hIA图像属性绘制图像
        _GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, $hfileBitmap, 0, 0, $fileW, $fileH, 0, 0, $fileW, $fileH, $hIA)
        _GDIPlus_GraphicsDispose($hGraphics)
        _GDIPlus_ImageAttributesDispose($hIA)
        ;更新图片控件
        _WinAPI_InvalidateRect($hPicWnd)
EndFunc   ;==>ChangeColor

Func restore()
        Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($TempBitmap)
        _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hfileBitmap, 0, 0, $fileW, $fileH, 0, 0, $fileW, $fileH)
        _GDIPlus_GraphicsDispose($hGraphics)
        ;更新图片控件
        _WinAPI_InvalidateRect($hPicWnd)
EndFunc   ;==>restore

Func gray()
        Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($TempBitmap)
        Local $hIA = _GDIPlus_ImageAttributesCreate()
        ;灰度矩阵
        Local $tColorMatrix = _GDIPlus_ColorMatrixCreateGrayScale()
        Local $pColorMatrix = DllStructGetPtr($tColorMatrix)
        _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $pColorMatrix)
        _GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, $hfileBitmap, 0, 0, $fileW, $fileH, 0, 0, $fileW, $fileH, $hIA)
        _GDIPlus_GraphicsDispose($hGraphics)
        _GDIPlus_ImageAttributesDispose($hIA)
        ;更新图片控件
        _WinAPI_InvalidateRect($hPicWnd)
EndFunc   ;==>gray

Func inverse()
        Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($TempBitmap)
        Local $hIA = _GDIPlus_ImageAttributesCreate()
        ;反色矩阵
        Local $tColorMatrix = _GDIPlus_ColorMatrixCreateNegative()
        Local $pColorMatrix = DllStructGetPtr($tColorMatrix)
        _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $pColorMatrix)
        _GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, $hfileBitmap, 0, 0, $fileW, $fileH, 0, 0, $fileW, $fileH, $hIA)
        _GDIPlus_GraphicsDispose($hGraphics)
        _GDIPlus_ImageAttributesDispose($hIA)
        ;更新图片控件
        _WinAPI_InvalidateRect($hPicWnd)
EndFunc   ;==>inverse

Func red()
        Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($TempBitmap)
        Local $hIA = _GDIPlus_ImageAttributesCreate()
        Local $tColorMatrix = _GDIPlus_ColorMatrixCreate()
        Local $pColorMatrix = DllStructGetPtr($tColorMatrix)
        DllStructSetData($tColorMatrix, "m", 1, 1);主对角线1设置为1,就是红色成份全部显示
        DllStructSetData($tColorMatrix, "m", 0, 7);主对角线7设置为0,就是绿色成份不显示
        DllStructSetData($tColorMatrix, "m", 0, 13);主对角线13设置为0,就是蓝色成份不显示
        _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $pColorMatrix)
        _GDIPlus_GraphicsDrawImageRectRectIA($hGraphics, $hfileBitmap, 0, 0, $fileW, $fileH, 0, 0, $fileW, $fileH, $hIA)
        _GDIPlus_GraphicsDispose($hGraphics)
        _GDIPlus_ImageAttributesDispose($hIA)
        ;更新图片控件
        _WinAPI_InvalidateRect($hPicWnd)
EndFunc   ;==>red

Func open()
        $imageFile = FileOpenDialog("请选择文件", @DesktopDir, "图像 (*.jpg;*.bmp;*.png)")
        If @error Then
                MsgBox(4096, "", "没有选择文件!")
        Else
                _GDIPlus_ImageDispose($TempBitmap)
                _GDIPlus_BitmapDispose($hfileBitmap)
                Local $hfile = _GDIPlus_BitmapCreateFromFile($imageFile)                
                $fileW = _GDIPlus_ImageGetWidth($hfileBitmap)
                $fileH = _GDIPlus_ImageGetHeight($hfileBitmap)
                $ret = _GDIPlus_ImageGetPixelFormat($hfile);获取颜色位深,位深小于24不能使用颜色矩阵
                If $ret[1] < 24 Then;如果位深小于24,则转换为24位深位图
                        $hfileBitmap = _GDIPlus_BitmapCreateFromScan0($fileW, $fileH);建立24位深位图
                        Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hfileBitmap)
                        _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hfile, 0, 0, $fileW, $fileH, 0, 0, $fileW, $fileH)
                        _GDIPlus_GraphicsDispose($hGraphics)
                Else
                        $hfileBitmap = _GDIPlus_ImageClone($hfile)
                EndIf
                _GDIPlus_ImageDispose($hfile)
                $TempBitmap = _GDIPlus_ImageClone($hfileBitmap)
                _WinAPI_InvalidateRect($hPicWnd)
        EndIf
EndFunc   ;==>open

Func save()
        Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
        _GDIPlus_ImageSaveToFileEx($hBitmap, @DesktopDir & "\15讲图像.jpg", $sCLSID)
        MsgBox(4096,"","图像保存成功!")
EndFunc   ;==>save```

 





本文固定链接: http://www.jianyiit.com/post-70.html

blogger
该日志由 绿色风 于2015-2-9 23:23 Monday发表在 分类下。
版权所有:《绿色风's Blog》 → 《[教程]第十五讲GDI+图像之颜色矩阵》;
除特别标注,本博客很多文章均为原创. 互联分享,尊重版权,转载请以链接形式标明本文地址;
本文标签:

扫描二维码,在手机上阅读
上一篇::[教程] 第十六讲 GDI+图像之图像属性项读取EXIF信息及缩略图读取
下一篇:吐嘈一下

热门文章

相关文章

  • [教程]第二讲 GDI文字DrawText
  • [教程] 第十一讲 GDI+画笔及线型
  • [教程] 第六讲 GDI设置图像到控件
  • [教程]第十讲之分解2-多色渐变画刷
  • [教程]第三讲 GDI画笔、线型
取消回复

发表评论

亲,头像对么?

82 + 30 =

提交中,请稍候……


木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!


    站点统计
    • 运行时间: 20254 天
    • 日志总数: 365 篇
    • 评论数量: 7238 条
    • 微语数量: 6 条
    • 附件总量: 388 件
  • 逝出的青春

  • 打赏"绿色风"



      扫码关注本站公众号 可搜本站内容

  • Autoit V3 脚本交流群

      常驻群1:905774875
      常驻群2:40672266


  • 链接

    • AU3中文论坛
    • Excel资料库
    • 完美者博客
    • 顺网小哥'S Blog
    • 猛牛哥的博客
    • 网吧系统下载
  • 分类

    • 流●年(66)
    • 笔●记(0)
    • 脚●本(0)
    • 作品(21)
    • 学习随记(51)
    • 源码示例(68)
    • UDF(收集)(26)
    • 工作室UDF(30)
    • 工具●教程(62)
    • 教程之GDI(24)
Copyright © 2013 绿色风's Blog. Powered by emlog. Theme by 射雕天龙. 鄂ICP备2021011689号-1 鄂公网安备42102302000078号 sitemap