找回密码
 加入
搜索
查看: 4228|回复: 7

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

  [复制链接]
发表于 2013-8-12 00:13:11 | 显示全部楼层 |阅读模式
本帖最后由 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[7][2]
;矩形条数组,[n][0]=最大值,[n][1]=最小值; (不直接用像素,是因为原始数据为其他数值)
;要求:不论[n][0],[n][1]怎样改(范围 0-800),最后一根矩形条都能在窗口中完全显示并撑满窗口(忽略之前的)
$array[1][0]=700  
$array[1][1]=10   
$array[2][0]=720  
$array[2][1]=100  
$array[3][0]=630 
$array[3][1]=50  
$array[4][0]=750  
$array[4][1]=170 
$array[5][0]=650  
$array[5][1]=30 
;------------------------------
$array[6][0]=800  ;最大800 固定
$array[6][1]=0    ;最小 0  固定
;----------------------------------------------------
Local $Highest = $array[1][0] 
Local $Lowest = $array[1][1] 
For $i=2 To 6
    If $array[$i][0] > $Highest Then $Highest = $array[$i][0] 
        If $array[$i][1] < $Lowest Then $Lowest = $array[$i][1] 
Next 
;----------------------------------------------------
Local $Range1[5],$Range2[4]
Local $Pixel = $high/$Highest-$Lowest ;窗口y范围中单位数值的像素系数
Local $xSpread,$xZoom,$Mobile
$Range1[1] = $Highest-$Lowest 
$Range1[2] = $Highest
$Range1[3] = $Lowest 

For $i=1 To 6
        $Range2[1] = $array[$i][0] - $array[$i][1] 
        $Range2[2] = $Range2[1] * $Pixel ;当前矩形范围值转像素 
        $Range2[3] = $high - $array[$i][0] * $Pixel  
    $Zoom = $Range1[1]/$Range2[1];缩放系数
        ;-------------
        If $array[$i][0] <> $Range1[2] Or $array[$i][1] <> $Range1[3] Then        
                $Range1[4] = $Highest-$Range1[2]     
                $xSpread = $Highest-$array[$i][0] 
                $xZoom = $xSpread * $Zoom 
                ;--------------------
                
                $Mobile = ($Range1[4]-$xSpread*$Zoom) * $Pixel  ;移动 (像素)
                
                ;问题:移动像素的计算公式反复验证也没发现问题,所以找不到方向了....
                ;现象:当前绘制的矩形(最后一根)不能完整的撑满窗口,最高值或范围变小到一定程度时更会离谱的移动矩阵
                
                ;--------------------
                
       _suofangjz($Zoom,$Mobile);缩放移动 矩阵
                
                $Range1[1] = $Range2[1] 
                $Range1[2] = $array[$i][0] 
                $Range1[3] = $array[$i][1]
    EndIf                 
        ;--------------
    _Draw($Range2[2],$Range2[3]);绘制
        _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+ 使用的资源
发表于 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);画笔对象
;------------------------------------------------------------------------
;矩形条数组,[n][0]=最大值,[n][1]=最小值; (不直接用像素,是因为原始数据为其他数值)
;要求:不论[n][0],[n][1]怎样改(范围 0-800),最后一根矩形条都能在窗口中完全显示并撑满窗口(忽略之前的)
Local $array[7][2] = [ _
                [0, 0], _
                [700, 10], _
                [720, 100], _
                [630, 50], _
                [750, 170], _
                [650, 30], _
                [800, 0]]
;----------------------------------------------------
Local $Highest = $array[1][0]
Local $Lowest = $array[1][1]
For $i = 2 To 6
        If $array[$i][0] > $Highest Then $Highest = $array[$i][0]
        If $array[$i][1] < $Lowest Then $Lowest = $array[$i][1]
Next
;----------------------------------------------------
Local $Range1[5],$Range2[4]
Local $Pixel = $High/$Highest-$Lowest ;窗口y范围中单位数值的像素系数
Local $xSpread,$xZoom,$Mobile
$Range1[1] = $Highest-$Lowest
$Range1[2] = $Highest
$Range1[3] = $Lowest
Local $aColor[7] = [0, 0xFFFFFFFF, 0xFFFF0000, 0xFFFFFF00, 0xFF00FF00, 0xFF00FFFF, 0xFF0000FF]
For $i = 1 To 6
        _GDIPlus_PenSetColor($hPen, $aColor[$i])

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

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

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

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

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

                $Range1[1] = $Range2[1]
                $Range1[2] = $array[$i][0]
                $Range1[3] = $array[$i][1]
        EndIf

        ;--------------
    _Draw($Range2[2],$Range2[3]);绘制
    _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+ 使用的资源
发表于 2013-8-12 10:07:47 | 显示全部楼层
最简单方法,先把原来尺寸的图画好
再用  _GDIPlus_GraphicsDrawImageRectRect画到指定大小的矩形中

无需计算缩放因子
 楼主| 发表于 2013-8-12 10:29:03 | 显示全部楼层
回复 3# Duvet


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

我先移动后缩放也试过几次,可惜都不得要领......
 楼主| 发表于 2013-8-12 10:31:28 | 显示全部楼层
回复 4# seniors

谢谢回复,不过我这个是依次动态添加不同大小图形的,所以不能一次绘制
发表于 2013-8-12 10:32:47 | 显示全部楼层
真正的高人在4樓
 楼主| 发表于 2013-8-12 10:36:27 | 显示全部楼层
本帖最后由 sd23 于 2013-8-12 10:38 编辑

回复 7# Duvet

是吗 看来是我太肤浅了,必须好好琢磨琢磨seniors的意思,谢谢!!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-19 14:05 , Processed in 0.086588 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表