- Сообщения
- 7,790
- Репутация
- 2,322
В продолжение темы Извлечение и конвертация иконок, их объединение хочу показать, как можно использовать на различных элементах окна кадры из одной большой картинки.
Две функции - получение одного кадра и получение массива кадров.
Код работает в версиях AutoIt 3.3.8.1 и 3.3.12.0.
В прикрепленном архиве картинки, используемые в примерах.
Для того, чтобы можно было использовать картинки из ресурсов, можно заменить в обеих функциях _GDIPlus_ImageLoadFromFile на функцию Yashied`а _LoadResourceImage, код которой здесь: Картинки
Две функции - получение одного кадра и получение массива кадров.
Код работает в версиях AutoIt 3.3.8.1 и 3.3.12.0.
Код:
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <GuiImageList.au3>;only examples _Example_3(), _Example_4()
#include <GuiListView.au3>;only _Example_4()
#include <GuiComboBoxEx.au3>;only _Example_3()
Opt('MustDeclareVars', 1)
Global Const $__STM_SETIMAGE = 0x0172
Global Const $__STM_GETIMAGE = 0x0173
_Example_1()
_Example_2()
_Example_3()
_Example_4()
_Example_5();кликайте по картинке
Func _Example_1()
Local $sImageFile = @ScriptDir & '\Example_1.png', $iFrame = 9, $iWidth = 16, $iHeight = 13, $hGui, $iPic, $hHBitmap
;~ Example_1.png кадры 4х3
$hHBitmap = _Get_Frame_HBitmap_From_ImageFile($sImageFile, $iFrame, $iWidth, $iHeight)
If @error Then Return ConsoleWrite('error: ' & @error & @LF)
$hGui = GUICreate('1', 150, 53)
$iPic = GUICtrlCreatePic('', 67, 20, $iWidth, $iHeight)
GUICtrlSendMsg($iPic, $__STM_SETIMAGE, 0, $hHBitmap)
GUISetState()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
_WinAPI_DeleteObject($hHBitmap)
GUIDelete()
EndFunc ;==>_Example_1
Func _Example_2()
Local $sImageFile = @ScriptDir & '\Example_2.png', $iSize = 16, $hGui, $ahFrame, _
$aCountry[12] = ['Australia', 'Belarus', 'Canada', 'Finland', 'France', 'Germany', 'Poland', _
'Romania', 'Russian Federation', 'Ukraine', 'United Kingdom', 'United States'], $aiPic[12]
;~ Example_2.png кадры 4х3
$ahFrame = _Get_Array_Frame_HBitmap_From_ImageFile($sImageFile, $iSize)
If @error Then Return ConsoleWrite('error: ' & @error & @LF)
$hGui = GUICreate('2', 322, 56)
For $i = 0 To UBound($ahFrame) - 1
$aiPic[$i] = GUICtrlCreatePic('', 10 + $i * ($iSize + 10), 20, $iSize, $iSize)
GUICtrlSetTip(-1, $aCountry[$i])
GUICtrlSendMsg(-1, $__STM_SETIMAGE, 0, $ahFrame[$i])
Next
GUISetState()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
For $i = 0 To UBound($ahFrame) - 1
_WinAPI_DeleteObject($ahFrame[$i])
Next
GUIDelete()
EndFunc ;==>_Example_2
Func _Example_3()
Local $sImageFile = @ScriptDir & '\Example_3.png', $iSize = 16, $hGui, $hImage, $hCombo, $hFrame, _
$aCountry[12] = ['Australia', 'Belarus', 'Canada', 'Finland', 'France', 'Germany', 'Poland', _
'Romania', 'Russian Federation', 'Ukraine', 'United Kingdom', 'United States']
;~ Example_3.png - полоса кадров в один ряд
$hFrame = _Get_Frame_HBitmap_From_ImageFile($sImageFile, 1, $iSize * UBound($aCountry), $iSize)
If @error Then Return ConsoleWrite('error: ' & @error & @LF)
$hImage = _GUIImageList_Create($iSize, $iSize, 5, 4)
_GUIImageList_Add($hImage, $hFrame)
_WinAPI_DeleteObject($hFrame)
$hFrame = 0
$hGui = GUICreate('3', 250, 250)
GUICtrlCreateLabel(UBound($aCountry) & ' - Country', 10, 5)
$hCombo = _GUICtrlComboBoxEx_Create($hGui, '', 10, 30, 230, 210)
_GUICtrlComboBoxEx_SetImageList($hCombo, $hImage)
For $i = 0 To UBound($aCountry) - 1
_GUICtrlComboBoxEx_AddString($hCombo, $aCountry[$i], $i, $i, 1)
Next
_GUICtrlComboBoxEx_SetCurSel($hCombo, Random(0, UBound($aCountry) - 1, 1))
GUISetState()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
_GUIImageList_Destroy($hImage)
GUIDelete()
EndFunc ;==>_Example_3
Func _Example_4()
Local $sImageFile = @ScriptDir & '\Example_4.png', $iSize = 16, $hGui, $hImage, $hListView, $ahFrame, _
$aCountry[231] = ['Afghanistan', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antigua and Barbuda', _
'Argentina', 'Armenia', 'Aruba', 'Australia', 'Austria', 'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh', 'Barbados', _
'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana', 'Brazil', _
'British Indian Ocean Territory', 'British Virgin Islands', 'Brunei Darussalam', 'Bulgaria', 'Burkina Faso', 'Burma', 'Burundi', _
'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Cayman Islands', 'Central African Republic', 'Chad', 'Chile', 'China', _
'Colombia', 'Comoros', 'Congo Democratic Republic', 'Congo Republic', 'Cook Islands', 'Costa Rica', 'Cote Divoire', 'Croatia', _
'Cuba', 'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica', 'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', _
'El Salvador', 'England', 'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Falkland Islands', 'Faroe Islands', 'Fiji', _
'Finland', 'France', 'French Polynesia', 'Gabon', 'Gambia', 'Georgia', 'Germany', 'Ghana', 'Gibraltar', 'Greece', 'Greenland', _
'Grenada', 'Guam', 'Guatemala', 'Guernsey', 'Guinea Bissau', 'Guinea', 'Guyana', 'Haiti', 'Honduras', 'Hong Kong', 'Hungary', _
'Iceland', 'India', 'Indonesia', 'Iran, Islamic Republic of', 'Iraq', 'Ireland', 'Isle Of Man', 'Israel', 'Italy', 'Jamaica', _
'Japan', 'Jersey', 'Jordan', 'Kazakstan', 'Kenya', 'Kiribati', 'Korea, Republic of', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', _
'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein', 'Lithuania', 'Luxembourg', 'Macau', 'Macedonia', 'Madagascar', _
'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta', 'Marshall Islands', 'Martinique', 'Mauritania', 'Mauritius', 'Mexico', _
'Micronesia', 'Moldova, Republic of', 'Monaco', 'Mongolia', 'Montserrat', 'Morocco', 'Mozambique', 'Namibia', 'Nauru', _
'Nepal', 'Netherlands Antilles', 'Netherlands', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'Niue', 'Norfolk Island', _
'North Korea', 'Northern Mariana Islands', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Panama', 'Papua New Guinea', 'Paraguay', _
'Peru', 'Philippines', 'Pitcairn Islands', 'Poland', 'Portugal', 'Puerto Rico', 'Qatar', 'Romania', 'Russian Federation', _
'Rwanda', 'Saint Helena', 'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Pierre and Miquelon', 'Saint Vincent and the Grenadines', _
'Samoa', 'San Marino', 'Sao Tome and Principe', 'Saudi Arabia', 'Scotland', 'Senegal', 'Serbia and Montenegro', 'Seychelles', _
'Sierra Leone', 'Singapore', 'Slovakia', 'Slovenia', 'Solomon Islands', 'Somalia', 'South Africa', 'South Georgia', 'Spain', _
'Sri Lanka', 'Sudan', 'Suriname', 'Swaziland', 'Sweden', 'Switzerland', 'Syrian Arab Republic', 'Taiwan', 'Tajikistan', _
'Tanzania, United Republic of', 'Thailand', 'Tibet', 'Togo', 'Tonga', 'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan', _
'Turks and Caicos Islands', 'Tuvalu', 'Uganda', 'Ukraine', 'United Arab Emirates', 'United Kingdom', 'United States', 'Uruguay', _
'Uzbekistan', 'Vanuatu', 'Vatican City', 'Venezuela', 'Vietnam', 'Virgin Islands', 'Wales', 'Wallis and Futuna', 'Yemen', _
'Zambia', 'Zimbabwe', 'Unknown']
;~ Example_4.png - кадров 21х11
$ahFrame = _Get_Array_Frame_HBitmap_From_ImageFile($sImageFile, $iSize * 21, $iSize)
If @error Then Return ConsoleWrite('error: ' & @error & @LF)
$hImage = _GUIImageList_Create($iSize, $iSize, 5, 4)
For $i = 0 To UBound($ahFrame) - 1
_GUIImageList_Add($hImage, $ahFrame[$i])
_WinAPI_DeleteObject($ahFrame[$i])
Next
$ahFrame = 0
$hGui = GUICreate('4', 250, 250)
$hListView = GUICtrlCreateListView('', 10, 10, 230, 230)
_GUICtrlListView_SetImageList($hListView, $hImage, 1)
_GUICtrlListView_AddColumn($hListView, UBound($aCountry) & ' - Country', 200)
For $i = 0 To UBound($aCountry) - 1
_GUICtrlListView_AddItem($hListView, $aCountry[$i], $i)
Next
GUISetState()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
_GUIImageList_Destroy($hImage)
GUIDelete()
EndFunc ;==>_Example_4
Func _Example_5()
Local $sImageFile = @ScriptDir & '\Example_5.png', $ahFrame[2] = [12, 9], $iSize = 16, $hGui, _
$iPic, $iFlag, $asText[2][2] = [['USA', 'Click here'],['Рус', 'Нажмите здесь']]
;~ Example_5.png кадры 1х12
$ahFrame = _Get_Array_Frame_HBitmap_From_ImageFile($sImageFile, $iSize, $iSize, $ahFrame)
If @error Then Return ConsoleWrite('error: ' & @error & @LF)
$hGui = GUICreate($asText[$iFlag][0], 150, 56)
$iPic = GUICtrlCreatePic('', 67, 20, $iSize, $iSize)
GUICtrlSetCursor($iPic, 0)
GUICtrlSetTip($iPic, $asText[$iFlag][1])
GUICtrlSendMsg($iPic, $__STM_SETIMAGE, 0, $ahFrame[$iFlag])
GUISetState()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case $iPic
$iFlag = Not $iFlag
_WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $__STM_GETIMAGE, 0, 0))
GUICtrlSendMsg($iPic, $__STM_SETIMAGE, 0, $ahFrame[$iFlag])
GUICtrlSetTip($iPic, $asText[$iFlag][1])
WinSetTitle($hGui, '', $asText[$iFlag][0])
_WinAPI_RedrawWindow($hGui)
EndSwitch
WEnd
For $i = 0 To UBound($ahFrame) - 1
_WinAPI_DeleteObject($ahFrame[$i])
Next
GUIDelete()
EndFunc ;==>_Example_5
; #FUNCTION# ====================================================================================================
; Name...........: _Get_Num_Frame_HBitmap_From_Bitmap
; Description....: Возвращает HBitmap кадра из файла изображения заданных размеров по номеру кадра для использования в окнах (GUICreate).
; Все кадры должны быть одинаковых размеров.
; Syntax.........: _Get_Frame_HBitmap_From_ImageFile($s_ImageFile, $i_Frame, $i_Width, [$i_Height = $i_Width])
; Parameters.....: $s_ImageFile - полный путь к файлу изображения.
; $i_Frame - номер кадра (начинается с 1). Порядок расчета расположения кадров:
; или 1 2 3 4 или 1 2 3 4 5 6 или 1
; 5 6 7 8 2
; 9 10 11 12 3
; $i_Width - ширина кадра.
; $i_Height - высота кадра. По умолчанию равна ширине (квадрат).
; Return values..: Success - HBitmap кадра флаг @error = 0.
; Failure - 0 и флаг @error = 1:
; 1 - отсутстует файл изображения;
; 2 - абсолютное значение одного из размеров $i_Frame, $i_Width, $i_Height равно 0;
; 3 - ошибка получения GDI Bitmap`a из файла изображения;
; 4 - ошибка получения размеров GDI Bitmap`a;
; 5 - ширина кадра не кратна ширине GDI Bitmap`a или высота кадра не кратна ширине GDI Bitmap`a;
; 6 - номер кадра больше количества кадров в GDI Bitmap`е;
; 7 - ошибка клонирования GDI Bitmap`a кадра из GDI Bitmap`a;
; 8 - ошибка создания HBitmap`a из GDI Bitmap`a кадра
;
; Remarks .......: После окончания использования полученного кадра необходимо освободить ресурсы (_WinAPI_DeleteObject).
; Author.........: madmasles
; Link...........: http://autoit-script.ru/index.php/topic,17061.0.html
; Example........: Есть
; ===============================================================================================================
Func _Get_Frame_HBitmap_From_ImageFile($s_ImageFile, $i_Frame, $i_Width, $i_Height = $i_Width)
Local $h_Image, $ai_Size, $i_Row, $i_Column, $i_Count, $h_Frame, $h_HBitmap, $i_Error = 1
If Not FileExists($s_ImageFile) Then Return SetError($i_Error, 0, 0);1
$i_Error += 1
$i_Frame = Abs(Int($i_Frame))
If Not $i_Frame Then Return SetError($i_Error, 0, 0);2
$i_Width = Abs(Int($i_Width))
If Not $i_Width Then Return SetError($i_Error, 0, 0);2
$i_Height = Abs(Int($i_Height))
If Not $i_Height Then Return SetError($i_Error, 0, 0);2
$i_Error += 1
_GDIPlus_Startup()
Do
$h_Image = _GDIPlus_ImageLoadFromFile($s_ImageFile)
If (@error) Or (Not $h_Image) Then ExitLoop;3
$i_Error += 1
$ai_Size = _GDIPlus_ImageGetDimension($h_Image)
If @error Then ExitLoop;4
$i_Error += 1
If Mod($ai_Size[0], $i_Width) Or Mod($ai_Size[1], $i_Height) Then ExitLoop;5
$i_Error += 1
$i_Row = $ai_Size[1] / $i_Height
$i_Column = $ai_Size[0] / $i_Width
Switch $i_Frame
Case 1 To $i_Row * $i_Column
Case Else
ExitLoop;6
EndSwitch
$i_Error += 1
For $i_Y = 0 To $i_Row - 1
For $i_X = 0 To $i_Column - 1
$i_Count += 1
If $i_Count = $i_Frame Then
$h_Frame = _GDIPlus_BitmapCloneArea($h_Image, $i_X * $i_Width, $i_Y * $i_Height, $i_Width, $i_Height, $GDIP_PXF32ARGB)
ExitLoop 2
EndIf
Next
Next
If Not $h_Frame Then ExitLoop;7
_GDIPlus_ImageDispose($h_Image)
$h_Image = 0
$i_Error += 1
$h_HBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($h_Frame)
If Not $h_HBitmap Then ExitLoop;8
_GDIPlus_ImageDispose($h_Frame)
$h_Frame = 0
$i_Error = 0
Until 1
If $h_Frame Then _GDIPlus_ImageDispose($h_Frame)
If $h_Image Then _GDIPlus_ImageDispose($h_Image)
_GDIPlus_Shutdown()
Return SetError($i_Error, 0, $h_HBitmap)
EndFunc ;==>_Get_Frame_HBitmap_From_ImageFile
; #FUNCTION# ====================================================================================================
; Name...........: _Get_Array_Frame_HBitmap_From_ImageFile
; Description....: Возвращает одномерный массив HBitmap кадров из файла изображения заданных размеров по номерам кадров
; для использования в окнах (GUICreate). Все кадры должны быть одинаковых размеров.
; Syntax.........: _Get_Array_Frame_HBitmap_From_ImageFile($s_ImageFile, $i_Width, [$i_Height = $i_Width], [$ai_Frame = 0])
; Parameters.....: $s_ImageFile - полный путь к файлу изображения.
; $i_Width - ширина кадра.
; $i_Height - высота кадра. По умолчанию равна ширине (квадрат).
; $ai_Frame - одномерный массив с номерами кадров(номера начинается с 1). Номера в массиве могут идти не по порядку,
; пример массива: [9, 11, 3]. Если не $i_Frame не одномерный массив, то вернет все имеющиеся кадры
; по порядку. Порядок расчета расположения кадров:
; или 1 2 3 4 или 1 2 3 4 5 6 или 1
; 5 6 7 8 2
; 9 10 11 12 3
; Если количество элементов массива больше полного количества кадров, то конец массива будет обрезан.
; По умолчанию 0 (не одномерный массив).
; Return values..: Success - HBitmap кадра флаг @error = 0.
; Failure - 0 и флаг @error:
; 1 - отсутстует файл изображения;
; 2 - абсолютное значение одного из размеров $i_Width или $i_Height равно 0;
; 3 - ошибка получения GDI Bitmap`a из файла изображения;
; 4 - ошибка получения размеров изображения;
; 5 - ширина кадра не кратна ширине изображения или высота кадра не кратна высоте изображения;
; 6 - один из номеров кадра больше количества кадров в изображении;
; 7 - ошибка клонирования GDI Bitmap`a кадра из GDI Bitmap`a;
; 8 - ошибка создания HBitmap`a из GDI Bitmap`a кадра.
;
; Remarks .......: После окончания использования полученных кадров необходимо освободить ресурсы (_WinAPI_DeleteObject).
; Author.........: madmasles
; Link...........: http://autoit-script.ru/index.php/topic,17061.0.html
; Example........: Есть
; ===============================================================================================================
Func _Get_Array_Frame_HBitmap_From_ImageFile($s_ImageFile, $i_Width, $i_Height = $i_Width, $ai_Frame = 0)
Local $h_Image, $ai_Size, $i_Row, $i_Column, $ai_FrameNum[1], $i_Count, $i_Ub, $h_Frame, $ah_HBitmap[1], $i_Error = 1
If Not FileExists($s_ImageFile) Then Return SetError($i_Error, 0, 0);1
$i_Error += 1
$i_Width = Abs(Int($i_Width))
If Not $i_Width Then Return SetError($i_Error, 0, 0);2
$i_Height = Abs(Int($i_Height))
If Not $i_Height Then Return SetError($i_Error, 0, 0);2
$i_Error += 1
_GDIPlus_Startup()
Do
$h_Image = _GDIPlus_ImageLoadFromFile($s_ImageFile)
If (@error) Or (Not $h_Image) Then ExitLoop;3
$i_Error += 1
$ai_Size = _GDIPlus_ImageGetDimension($h_Image)
If @error Then ExitLoop;4
$i_Error += 1
If Mod($ai_Size[0], $i_Width) Or Mod($ai_Size[1], $i_Height) Then ExitLoop;5
$i_Error += 1
$i_Row = $ai_Size[1] / $i_Height
$i_Column = $ai_Size[0] / $i_Width
$i_Count = $i_Row * $i_Column
Switch UBound($ai_Frame, 0)
Case 1
$i_Ub = UBound($ai_Frame)
If $i_Ub > $i_Count Then $i_Ub = $i_Count
ReDim $ai_FrameNum[$i_Ub + 1]
For $i = 0 To $i_Ub - 1
$ai_Frame[$i] = Abs(Int($ai_Frame[$i]))
Switch $ai_Frame[$i]
Case 1 To $i_Count
$ai_FrameNum[$i + 1] = $ai_Frame[$i]
Case Else
ExitLoop 2;6
EndSwitch
Next
Case Else
ReDim $ai_FrameNum[$i_Count + 1]
For $i = 1 To $i_Count
$ai_FrameNum[$i] = $i
Next
$i_Ub = $i_Count
EndSwitch
$ai_FrameNum[0] = $i_Ub
ReDim $ah_HBitmap[$i_Ub]
$i_Ub = 0
$i_Error += 1
For $i = 1 To $ai_FrameNum[0]
$i_Count = 0
For $i_Y = 0 To $i_Row - 1
For $i_X = 0 To $i_Column - 1
$i_Count += 1
If $i_Count = $ai_FrameNum[$i] Then
$h_Frame = _GDIPlus_BitmapCloneArea($h_Image, $i_X * $i_Width, $i_Y * $i_Height, $i_Width, $i_Height, $GDIP_PXF32ARGB)
If Not $h_Frame Then ExitLoop 4;7
$ah_HBitmap[$i_Ub] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($h_Frame)
_GDIPlus_ImageDispose($h_Frame)
$h_Frame = 0
If Not $ah_HBitmap[$i_Ub] Then
$i_Error += 1
ExitLoop 4;8
EndIf
$i_Ub += 1
If $i_Ub = $ai_FrameNum[0] Then ExitLoop 3
EndIf
Next
Next
Next
_GDIPlus_ImageDispose($h_Image)
$h_Image = 0
$i_Error = 0
Until 1
If $h_Image Then _GDIPlus_ImageDispose($h_Image)
_GDIPlus_Shutdown()
If $i_Error Then
For $i = 0 To $ai_FrameNum[0] - 1
If $ah_HBitmap[$i] Then _WinAPI_DeleteObject($ah_HBitmap[$i])
Next
Return SetError($i_Error, 0, 0)
EndIf
Return $ah_HBitmap
EndFunc ;==>_Get_Array_Frame_HBitmap_From_ImageFile
;~ функция из GDIP.au3
Func _GDIPlus_ImageGetDimension($hImage)
Local $aSize[2], $aResult
$aResult = DllCall('gdiplus.dll', 'uint', 'GdipGetImageDimension', 'hwnd', $hImage, 'float*', 0, 'float*', 0)
If @error Then
Return SetError(1, 0, 0)
Else
If $aResult[0] Then
Return SetError($aResult[0], 0, 0)
EndIf
EndIf
$aSize[0] = $aResult[2]
$aSize[1] = $aResult[3]
Return $aSize
EndFunc ;==>_GDIPlus_ImageGetDimension
Для того, чтобы можно было использовать картинки из ресурсов, можно заменить в обеих функциях _GDIPlus_ImageLoadFromFile на функцию Yashied`а _LoadResourceImage, код которой здесь: Картинки