sd23 发表于 2013-8-12 00:13:11

[已解决] GDI+ 缩放移动矩阵的问题 求助

本帖最后由 sd23 于 2013-8-12 10:33 编辑

目的:在数组循环绘制中,通过缩放移动矩阵,始终将当前(最后)一根矩形条完整的撑满窗口(忽略之前的)

问题: 目前表面看就是移动距离的问题,但又没发现移动计算错误,找不到解决的途径了......

附上代码:;缩放移动矩阵测试
;目的:在数组循环绘制中,始终将当前(最后)一根矩形条完整的撑满窗口(忽略之前的)
;这段代码,表面看就是移动距离的问题,但又没发现移动计算错误,找不到解决的途径了....
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Global $IMG,$graph,$xi=1
Local $Width=500,$high=250
Local $hWnd = GUICreate("GDI+ Example", 400, 320)
GUISetState()
Local $sForm1 = GUICreate("", $Width, $high, 0, 0, $WS_CHILD, $WS_EX_ACCEPTFILES, $hWnd);子窗口
Local $label = GUICtrlCreateLabel("",0,0,$Width,$high)
GUICtrlSetBkColor(-1,0x000000)
Local $label2 = ControlGetHandle($sForm1, "", $label);内部句柄
GUISetState()
;------
_GDIPlus_Startup();初始化gdi+
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($label2);图形对象
$IMG = _GDIPlus_BitmapCreateFromGraphics($Width,$high,$hGraphics);位图对象
$graph = _GDIPlus_ImageGetGraphicsContext($IMG);图形场景
Local $hMatrix = _GDIPlus_MatrixCreate();矩阵对象
Local $hPen = _GDIPlus_PenCreate(0xFF00FF00, 2);画笔对象
;------------------------------------------------------------------------
Local $array
;矩形条数组,=最大值,=最小值; (不直接用像素,是因为原始数据为其他数值)
;要求:不论,怎样改(范围 0-800),最后一根矩形条都能在窗口中完全显示并撑满窗口(忽略之前的)
$array=700
$array=10   
$array=720
$array=100
$array=630
$array=50
$array=750
$array=170
$array=650
$array=30
;------------------------------
$array=800;最大800 固定
$array=0    ;最小 0固定
;----------------------------------------------------
Local $Highest = $array
Local $Lowest = $array
For $i=2 To 6
    If $array[$i] > $Highest Then $Highest = $array[$i]
        If $array[$i] < $Lowest Then $Lowest = $array[$i]
Next
;----------------------------------------------------
Local $Range1,$Range2
Local $Pixel = $high/$Highest-$Lowest ;窗口y范围中单位数值的像素系数
Local $xSpread,$xZoom,$Mobile
$Range1 = $Highest-$Lowest
$Range1 = $Highest
$Range1 = $Lowest

For $i=1 To 6
        $Range2 = $array[$i] - $array[$i]
        $Range2 = $Range2 * $Pixel ;当前矩形范围值转像素
        $Range2 = $high - $array[$i] * $Pixel
    $Zoom = $Range1/$Range2;缩放系数
        ;-------------
        If $array[$i] <> $Range1 Or $array[$i] <> $Range1 Then       
                $Range1 = $Highest-$Range1   
                $xSpread = $Highest-$array[$i]
                $xZoom = $xSpread * $Zoom
                ;--------------------
               
                $Mobile = ($Range1-$xSpread*$Zoom) * $Pixel;移动 (像素)
               
                ;问题:移动像素的计算公式反复验证也没发现问题,所以找不到方向了....
                ;现象:当前绘制的矩形(最后一根)不能完整的撑满窗口,最高值或范围变小到一定程度时更会离谱的移动矩阵
               
                ;--------------------
               
       _suofangjz($Zoom,$Mobile);缩放移动 矩阵
               
                $Range1 = $Range2
                $Range1 = $array[$i]
                $Range1 = $array[$i]
    EndIf                
        ;--------------
    _Draw($Range2,$Range2);绘制
        _GDIPlus_GraphicsDrawImage($hGraphics, $IMG, 0, 0);绘制图像对象
    Sleep(2000)
Next
;------------------------------------------------------
;缩放移动 矩阵
Func _suofangjz($Zoom,$Mobile)
    _GDIPlus_MatrixScale($hMatrix, 1, $Zoom);缩放矩阵
        _GDIPlus_MatrixTranslate($hMatrix, 0, $Mobile);移动矩阵
        _GDIPlus_GraphicsSetTransform($hGraphics, $hMatrix);设置新的图像对象的世界坐标空间
        _GDIPlus_GraphicsClear($hGraphics);清除
EndFunc
;--------------------------
;绘制
Func _Draw($Range_p,$Range_h)
        _GDIPlus_GraphicsDrawRect($graph, $xi, $Range_h, 10, $Range_p, $hPen);绘制矩形
        $xi += 20
EndFunc
;==================================================================
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE;关闭

; 清理资源
_GDIPlus_PenDispose($hPen);释放画笔对象
_GDIPlus_MatrixDispose($hMatrix);;释放矩阵对象
_GDIPlus_GraphicsDispose($hGraphics);;释放图形对象
_GDIPlus_Shutdown();;清理微软 Windows GDI+ 使用的资源

Duvet 发表于 2013-8-12 09:57:11

可以理解成這個意思嗎?
當前繪製的長條圖高度,縮放為Label的高度

自定義函數 _suofangjz
應該是先移動後縮放


;缩放移动矩阵测试
;目的:在数组循环绘制中,始终将当前(最后)一根矩形条完整的撑满窗口(忽略之前的)
;这段代码,表面看就是移动距离的问题,但又没发现移动计算错误,找不到解决的途径了....
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Global $IMG,$graph,$xi=1
Local $Width=500,$High=250
Local $hWnd = GUICreate("GDI+ Example", 400, 320)
GUISetState()
Local $sForm1 = GUICreate("", $Width, $High, 0, 0, $WS_CHILD, $WS_EX_ACCEPTFILES, $hWnd);子窗口
Local $label = GUICtrlCreateLabel("",0,0,$Width,$High)
GUICtrlSetBkColor(-1, 0)
Local $label2 = ControlGetHandle($sForm1, "", $label);内部句柄
GUISetState()
;------
_GDIPlus_Startup();初始化gdi+
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($label2);图形对象
$IMG = _GDIPlus_BitmapCreateFromGraphics($Width,$High,$hGraphics);位图对象
$graph = _GDIPlus_ImageGetGraphicsContext($IMG);图形场景
Local $hMatrix = _GDIPlus_MatrixCreate();矩阵对象
Local $hPen = _GDIPlus_PenCreate(0, 2);画笔对象
;------------------------------------------------------------------------
;矩形条数组,=最大值,=最小值; (不直接用像素,是因为原始数据为其他数值)
;要求:不论,怎样改(范围 0-800),最后一根矩形条都能在窗口中完全显示并撑满窗口(忽略之前的)
Local $array = [ _
                , _
                , _
                , _
                , _
                , _
                , _
                ]
;----------------------------------------------------
Local $Highest = $array
Local $Lowest = $array
For $i = 2 To 6
        If $array[$i] > $Highest Then $Highest = $array[$i]
        If $array[$i] < $Lowest Then $Lowest = $array[$i]
Next
;----------------------------------------------------
Local $Range1,$Range2
Local $Pixel = $High/$Highest-$Lowest ;窗口y范围中单位数值的像素系数
Local $xSpread,$xZoom,$Mobile
$Range1 = $Highest-$Lowest
$Range1 = $Highest
$Range1 = $Lowest
Local $aColor =
For $i = 1 To 6
        _GDIPlus_PenSetColor($hPen, $aColor[$i])

        $Range2 = $array[$i] - $array[$i]
        $Range2 = $Range2 * $Pixel ;当前矩形范围值转像素
        $Range2 = $High - $array[$i] * $Pixel
        $Zoom = $Range1/$Range2;缩放系数
        ;-------------
        If $array[$i] <> $Range1 Or $array[$i] <> $Range1 Then
                $Range1 = $Highest-$Range1
                $xSpread = $Highest-$array[$i]
                $xZoom = $xSpread * $Zoom
                ;--------------------

                $Mobile = ($Range1-$xSpread*$Zoom) * $Pixel;移动 (像素)

                ;问题:移动像素的计算公式反复验证也没发现问题,所以找不到方向了....
                ;现象:当前绘制的矩形(最后一根)不能完整的撑满窗口,最高值或范围变小到一定程度时更会离谱的移动矩阵

                ;--------------------

                _suofangjz($Zoom,$Mobile);缩放移动 矩阵

                $Range1 = $Range2
                $Range1 = $array[$i]
                $Range1 = $array[$i]
        EndIf

        ;--------------
    _Draw($Range2,$Range2);绘制
    _GDIPlus_GraphicsDrawImage($hGraphics, $IMG, 0, 0);绘制图像对象
    Sleep(2000)
Next
;------------------------------------------------------
;缩放移动 矩阵
Func _suofangjz($Zoom, $Mobile)
        _GDIPlus_MatrixTranslate($hMatrix, 0, $Mobile);移动矩阵
        _GDIPlus_MatrixScale($hMatrix, 1, $Zoom);缩放矩阵
        _GDIPlus_GraphicsSetTransform($hGraphics, $hMatrix);设置新的图像对象的世界坐标空间
        _GDIPlus_GraphicsClear($hGraphics);清除
EndFunc
;--------------------------
;绘制
Func _Draw($Range_p,$Range_h)
      _GDIPlus_GraphicsDrawRect($graph, $xi, $Range_h, 10, $Range_p, $hPen);绘制矩形
      $xi += 20
EndFunc
;==================================================================
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE;关闭
; 清理资源
_GDIPlus_PenDispose($hPen);释放画笔对象
_GDIPlus_MatrixDispose($hMatrix);;释放矩阵对象
_GDIPlus_GraphicsDispose($hGraphics);;释放图形对象
_GDIPlus_Shutdown();;清理微软 Windows GDI+ 使用的资源

seniors 发表于 2013-8-12 10:07:47

最简单方法,先把原来尺寸的图画好
再用_GDIPlus_GraphicsDrawImageRectRect画到指定大小的矩形中

无需计算缩放因子

sd23 发表于 2013-8-12 10:29:03

回复 3# Duvet


Duvet高人啊,这么快,基本达到目的!非常感谢!

我先移动后缩放也试过几次,可惜都不得要领......

sd23 发表于 2013-8-12 10:31:28

回复 4# seniors

谢谢回复,不过我这个是依次动态添加不同大小图形的,所以不能一次绘制

Duvet 发表于 2013-8-12 10:32:47

真正的高人在4樓

sd23 发表于 2013-8-12 10:36:27

本帖最后由 sd23 于 2013-8-12 10:38 编辑

回复 7# Duvet

是吗 看来是我太肤浅了,必须好好琢磨琢磨seniors的意思,谢谢!!
页: [1]
查看完整版本: [已解决] GDI+ 缩放移动矩阵的问题 求助