Что нового

Изменение размера картинки

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Есть маленькая проблемка, я вывожу картинку на форму через GDIPlus и рисую текст на этой картинке, но при попытке изменить размер картинки с помощью функции _WinAPI_ResizeBitmap() картинка получается не корректной, то есть когда я рисую текст, то беру оригинальные размеры картинки, после того как текст напечатан на картинке, пытаюсь изменить её размер, но получается так что картинка на форме обрезана с правой стороны и с низу, то есть, изменить размер картинки нужно до того как будет печататься текст на ней, но как зделать?

Код:
Func ___SetBitmap($iPic, $hText, $hSize, $hColor, $hFonts, $hAttrib, $sPNGFile)
	Local $Width, $Hight, $hArea, $hGraphic, $hFamily, $hFont, $tLayout, $hFormat, $hBrush, $aData, $hBitmap
	
	If Not IsHWnd($iPic) Then $iPic = GUICtrlGetHandle($iPic)
	
    _GDIPlus_Startup()
	Local $hImage = _GDIPlus_ImageLoadFromFile($sPNGFile)
    $Width = _GDIPlus_ImageGetWidth($hImage)
	$Hight = _GDIPlus_ImageGetHeight($hImage)
	$hArea = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $Width, $Hight, $GDIP_PXF32ARGB)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hArea)
    $hFamily = _GDIPlus_FontFamilyCreate($hFonts)
    $hFont = _GDIPlus_FontCreate($hFamily, $hSize, $hAttrib, 2)
    $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    $hFormat = _GDIPlus_StringFormatCreate()
    $hBrush = _GDIPlus_BrushCreateSolid($hColor)	
	DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "ptr", $hGraphic, "int", 3)
    $aData = _GDIPlus_GraphicsMeasureString($hGraphic, $hText, $hFont, $tLayout, $hFormat)
    $tLayout = $aData[0]
    DllStructSetData($tLayout, 1, ($Width - DllStructGetData($tLayout, 3)) / 2)
    DllStructSetData($tLayout, 2, ($Hight - DllStructGetData($tLayout, 4)) / 2)
    _GDIPlus_GraphicsDrawStringEx($hGraphic, $hText, $hFont, $aData[0], $hFormat, $hBrush)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hArea)
	_SendMessage($iPic, 0x172, 0, "")
    _WinAPI_DeleteObject(_SendMessage($iPic, 0x172, 0, $hBitmap))
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_ImageDispose($hArea)
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc



Добавлено:
Сообщение автоматически объединено:

Всё, разобрался.

Код:
Func ___SetBitmap($iPic, $hText, $hSize, $hColor, $hFonts, $hAttrib, $Width, $Height, $sPNGFile)
	Local $hArea, $hGraphic, $hFamily, $hFont, $tLayout, $hFormat, $hBrush, $aData, $hBitmap
	
	If Not IsHWnd($iPic) Then $iPic = GUICtrlGetHandle($iPic)
	
    _GDIPlus_Startup()
	Local $hImage = _GDIPlus_ImageLoadFromFile($sPNGFile)	
	$hThumb = _GDIPlus_GetImageThumbnail($hImage, $Width, $Height)
	$hArea = _GDIPlus_BitmapCloneArea($hThumb, 0, 0, $Width, $Height, $GDIP_PXF32ARGB)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hArea)
    $hFamily = _GDIPlus_FontFamilyCreate($hFonts)
    $hFont = _GDIPlus_FontCreate($hFamily, $hSize, $hAttrib, 2)
    $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0)
    $hFormat = _GDIPlus_StringFormatCreate()
    $hBrush = _GDIPlus_BrushCreateSolid($hColor)	
	DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "ptr", $hGraphic, "int", 3)
    $aData = _GDIPlus_GraphicsMeasureString($hGraphic, $hText, $hFont, $tLayout, $hFormat)
    $tLayout = $aData[0]
    DllStructSetData($tLayout, 1, ($Width - DllStructGetData($tLayout, 3)) / 2)
    DllStructSetData($tLayout, 2, ($Height - DllStructGetData($tLayout, 4)) / 2)
    _GDIPlus_GraphicsDrawStringEx($hGraphic, $hText, $hFont, $aData[0], $hFormat, $hBrush)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hArea)
	_SendMessage($iPic, 0x172, 0, "")
    _WinAPI_DeleteObject(_SendMessage($iPic, 0x172, 0, $hBitmap))
    _GDIPlus_GraphicsDispose($hGraphic)
	_GDIPlus_ImageDispose($hThumb)	
    _GDIPlus_StringFormatDispose($hFormat)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_ImageDispose($hArea)
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc

Func _GDIPlus_GetImageThumbnail($hImage, $iWidth, $iHeight)

    Local $Ret = DllCall($ghGDIPDll, 'int', 'GdipGetImageThumbnail', 'ptr', $hImage, 'int', $iWidth, 'int', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)

    If (@error) Or ($Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[4]
EndFunc   ;==>_GDIPlus_GetImageThumbnail
 

agikon

Знающий
Сообщения
789
Репутация
16
я не понял.
что рисуете в скрипте, или в паинте?
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Я с помощью GDIplus пишу текст прямо на картинке и вывожу в форму
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
А про размеры control'а вы не забыли? Он сам не подстраивается под картинку.


Добавлено:
Сообщение автоматически объединено:

А еще у вас возникнет утечка память при вставке картинки...
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Про контрол не забыл,а что за утечка памяти?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
Viktor1703 сказал(а):
...а что за утечка памяти?
Читать очень внимательно Important (в самом низу).

P.S

Также имейте ввиду, что при удалении GUI/Pic control'а, AutoIt уничтожает хендлы только тех bitmap'ов, находящихся в Pic, которые были созданы с помощью GUICtrlCreatePic() и GUICtrlSetImage(). Если картинка была вставлена с помощью STM_SETIMAGE, вы должны вызвать _WinAPI_DeleteObject() после удаления control'а Pic или всего GUI, в котором он содержится.
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
То есть если не использовать в конце скрипта _WinAPI_DeleteObject() то при закрытии окна или удалении контрола в ячейки памяти останутся данные?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
Viktor1703 сказал(а):
То есть если не использовать в конце скрипта _WinAPI_DeleteObject() то при закрытии окна или удалении контрола в ячейки памяти останутся данные?
Да, но это вторая проблема.


Добавлено:
Сообщение автоматически объединено:

Разумеется, память будет занята только до окончания процесса.
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Спасибо за подсказки, ещё один вопрос, а если использовать такую конструкцию....

Код:
OnAutoItExitRegister("__Destroy")

;~=============================

Func __Destroy()
	For $i = 1 To $ControlData[0][0]
		GUICtrlDelete($ControlData[$i][5])
		For $j = 0 To 2
			_WinAPI_DeleteObject($ControlData[$i][$j])
		Next
	Next
	ReDim $ControlData[1][UBound($ControlData, 2)]
	For $i = 0 To 4
		$ControlData[0][$i] = 0
	Next
EndFunc


Проблем не будет с утечкой?
 
Верх