Что нового

Сохранить GUI в JPG

Latoid

Знающий
Сообщения
95
Репутация
11
Здравствуйте.
Есть функция (не моя), что генерирует штриховой код в GUI. Стоит задача сохранить GUI в JPG, чтобы потом вставить в PDF документ.
Про то, что можно сделать скриншот и сохранить его, знаю, но может есть какой-либо более грамотный способ?
В идеале JPG должен сохраняться с заданной шириной и высотой, и совсем хорошо, если эти параметры можно было указать в сантиметрах, а не пикселях.

Код:
#AutoIt3Wrapper_Run_AU3Check=n

#include <Array.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <GDIPlus.au3>

Global $Width = 1344
Global $Height = 1050

$iThicknessOfLabel = 4 ; в настройки
_CreateBarCode ("Hello world")

Func _CreateBarCode ($sfStringForBarCode)
	$Barcode = _IdentifyCodeSwitches($sfStringForBarCode)
	$ifLenghtOfBarcode = StringLen($Barcode)

	$ifGUIWidth = $iThicknessOfLabel*$ifLenghtOfBarcode
	$ifGUIHeight = $ifGUIWidth / 6.6

	Local $BarCodeWindow = GUICreate ("", $ifGUIWidth, 1.5*$ifGUIHeight, -1, -1, $WS_POPUP)
	GUISetBkColor (0xFFFFFF)
	WinSetOnTop ($BarCodeWindow, "", 1)
	GUISetState(@SW_SHOW, $BarCodeWindow)

	Dim $L[$ifLenghtOfBarcode + 1]
	$i = 1
	While $i <= $ifLenghtOfBarcode
		$col = StringMid($barcode, $i, 1)
		$L[$i] = GUICtrlCreateLabel("", 0 + ($i * $iThicknessOfLabel), 0, $iThicknessOfLabel, $ifGUIHeight)
		if $col = 1 Then
			GUICtrlSetBkColor(-1,0x000000)
		Else
			GUICtrlSetBkColor(-1,0xFFFFFF)
		EndIf
		$i += 1
	WEnd
	GUICtrlCreateLabel ($sfStringForBarCode, 0, $ifGUIHeight*1.13, $ifGUIWidth, $ifGUIHeight/4, BitOR ($SS_CENTER, $SS_CENTERIMAGE))
	GUICtrlSetFont (-1, $iThicknessOfLabel*6, 0, 0, "Arial", 4+5)

	While 1
		$msg = GUIGetMsg ()
		Switch $msg
			Case $GUI_EVENT_CLOSE
				ExitLoop
		EndSwitch
	WEnd
EndFunc ; _CreateBarCode

Func _IdentifyCodeSwitches($code) ; автор andybiochem; https://www.autoitscript.com/forum/topic/72081-barcode-generator-code-128-b-c/
	Local $aCode128Patterns[104]
	$aCode128Patterns[1] = "0¬ ¬00¬11011001100"
	$aCode128Patterns[2] = "1¬!¬01¬11001101100"
	$aCode128Patterns[3] = '2¬"¬02¬11001100110'
	$aCode128Patterns[4] = "3¬#¬03¬10010011000"
	$aCode128Patterns[5] = "4¬$¬04¬10010001100"
	$aCode128Patterns[6] = "5¬%¬05¬10001001100"
	$aCode128Patterns[7] = "6¬&¬06¬10011001000"
	$aCode128Patterns[8] = "7¬'¬07¬10011000100"
	$aCode128Patterns[9] = "8¬(¬08¬10001100100"
	$aCode128Patterns[10] = "9¬)¬09¬11001001000"
	$aCode128Patterns[11] = "10¬*¬10¬11001000100"
	$aCode128Patterns[12] = "11¬+¬11¬11000100100"
	$aCode128Patterns[13] = "12¬,¬12¬10110011100"
	$aCode128Patterns[14] = "13¬-¬13¬10011011100"
	$aCode128Patterns[15] = "14¬.¬14¬10011001110"
	$aCode128Patterns[16] = "15¬/¬15¬10111001100"
	$aCode128Patterns[17] = "16¬0¬16¬10011101100"
	$aCode128Patterns[18] = "17¬1¬17¬10011100110"
	$aCode128Patterns[19] = "18¬2¬18¬11001110010"
	$aCode128Patterns[20] = "19¬3¬19¬11001011100"
	$aCode128Patterns[21] = "20¬4¬20¬11001001110"
	$aCode128Patterns[22] = "21¬5¬21¬11011100100"
	$aCode128Patterns[23] = "22¬6¬22¬11001110100"
	$aCode128Patterns[24] = "23¬7¬23¬11101101110"
	$aCode128Patterns[25] = "24¬8¬24¬11101001100"
	$aCode128Patterns[26] = "25¬9¬25¬11100101100"
	$aCode128Patterns[27] = "26¬:¬26¬11100100110"
	$aCode128Patterns[28] = "27¬;¬27¬11101100100"
	$aCode128Patterns[29] = "28¬<¬28¬11100110100"
	$aCode128Patterns[30] = "29¬=¬29¬11100110010"
	$aCode128Patterns[31] = "30¬>¬30¬11011011000"
	$aCode128Patterns[32] = "31¬?¬31¬11011000110"
	$aCode128Patterns[33] = "32¬@¬32¬11000110110"
	$aCode128Patterns[34] = "33¬A¬33¬10100011000"
	$aCode128Patterns[35] = "34¬B¬34¬10001011000"
	$aCode128Patterns[36] = "35¬C¬35¬10001000110"
	$aCode128Patterns[37] = "36¬D¬36¬10110001000"
	$aCode128Patterns[38] = "37¬E¬37¬10001101000"
	$aCode128Patterns[39] = "38¬F¬38¬10001100010"
	$aCode128Patterns[40] = "39¬G¬39¬11010001000"
	$aCode128Patterns[41] = "40¬H¬40¬11000101000"
	$aCode128Patterns[42] = "41¬I¬41¬11000100010"
	$aCode128Patterns[43] = "42¬J¬42¬10110111000"
	$aCode128Patterns[44] = "43¬K¬43¬10110001110"
	$aCode128Patterns[45] = "44¬L¬44¬10001101110"
	$aCode128Patterns[46] = "45¬M¬45¬10111011000"
	$aCode128Patterns[47] = "46¬N¬46¬10111000110"
	$aCode128Patterns[48] = "47¬O¬47¬10001110110"
	$aCode128Patterns[49] = "48¬P¬48¬11101110110"
	$aCode128Patterns[50] = "49¬Q¬49¬11010001110"
	$aCode128Patterns[51] = "50¬R¬50¬11000101110"
	$aCode128Patterns[52] = "51¬S¬51¬11011101000"
	$aCode128Patterns[53] = "52¬T¬52¬11011100010"
	$aCode128Patterns[54] = "53¬U¬53¬11011101110"
	$aCode128Patterns[55] = "54¬V¬54¬11101011000"
	$aCode128Patterns[56] = "55¬W¬55¬11101000110"
	$aCode128Patterns[57] = "56¬X¬56¬11100010110"
	$aCode128Patterns[58] = "57¬Y¬57¬11101101000"
	$aCode128Patterns[59] = "58¬Z¬58¬11101100010"
	$aCode128Patterns[60] = "59¬[¬59¬11100011010"
	$aCode128Patterns[61] = "60¬\¬60¬11101111010"
	$aCode128Patterns[62] = "61¬]¬61¬11001000010"
	$aCode128Patterns[63] = "62¬^¬62¬11110001010"
	$aCode128Patterns[64] = "63¬_¬63¬10100110000"
	$aCode128Patterns[65] = "64¬`¬64¬10100001100"
	$aCode128Patterns[66] = "65¬a¬65¬10010110000"
	$aCode128Patterns[67] = "66¬b¬66¬10010000110"
	$aCode128Patterns[68] = "67¬c¬67¬10000101100"
	$aCode128Patterns[69] = "68¬d¬68¬10000100110"
	$aCode128Patterns[70] = "69¬e¬69¬10110010000"
	$aCode128Patterns[71] = "70¬f¬70¬10110000100"
	$aCode128Patterns[72] = "71¬g¬71¬10011010000"
	$aCode128Patterns[73] = "72¬h¬72¬10011000010"
	$aCode128Patterns[74] = "73¬i¬73¬10000110100"
	$aCode128Patterns[75] = "74¬j¬74¬10000110010"
	$aCode128Patterns[76] = "75¬k¬75¬11000010010"
	$aCode128Patterns[77] = "76¬l¬76¬11001010000"
	$aCode128Patterns[78] = "77¬m¬77¬11110111010"
	$aCode128Patterns[79] = "78¬n¬78¬11000010100"
	$aCode128Patterns[80] = "79¬o¬79¬10001111010"
	$aCode128Patterns[81] = "80¬p¬80¬10100111100"
	$aCode128Patterns[82] = "81¬q¬81¬10010111100"
	$aCode128Patterns[83] = "82¬r¬82¬10010011110"
	$aCode128Patterns[84] = "83¬s¬83¬10111100100"
	$aCode128Patterns[85] = "84¬t¬84¬10011110100"
	$aCode128Patterns[86] = "85¬u¬85¬10011110010"
	$aCode128Patterns[87] = "86¬v¬86¬11110100100"
	$aCode128Patterns[88] = "87¬w¬87¬11110010100"
	$aCode128Patterns[89] = "88¬x¬88¬11110010010"
	$aCode128Patterns[90] = "89¬y¬89¬11011011110"
	$aCode128Patterns[91] = "90¬z¬90¬11011110110"
	$aCode128Patterns[92] = "91¬{¬91¬11110110110"
	$aCode128Patterns[93] = "92¬|¬92¬10101111000"
	$aCode128Patterns[94] = "93¬}¬93¬10100011110"
	$aCode128Patterns[95] = "94¬~¬94¬10001011110"
	$aCode128Patterns[96] = "95¬del¬95¬10111101000"
	$aCode128Patterns[97] = "96¬Fnc3¬96¬10111100010"
	$aCode128Patterns[98] = "97¬Fnc2¬97¬11110101000"
	$aCode128Patterns[99] = "98¬Shift¬98¬11110100010"
	$aCode128Patterns[100] = "99¬Code C¬99¬10111011110"
	$aCode128Patterns[101] = "100¬Fnc 4¬Code B¬10111101110"
	$aCode128Patterns[102] = "101¬Code A¬Code A¬11101011110"
	$aCode128Patterns[103] = "102¬Fnc 1¬Fnc 1¬11110101110"

	$i = 1
	$CodeType = "B"                     ;always start with code type B
	$len = StringLen($Code)
	While $i <= $len
		Select
			Case $CodeType = "B"
				if StringRegExp(StringMid($Code,$i,6),"([0-9][0-9]){3}") = 1 Then
					$Code = StringMid($Code,1,$i - 1) & "¬C¬" & StringMid($Code,$i)
					$CodeType = "C"
					$i += 6 + 3
				Else
					$CodeType = "B"
					$i += 1
				EndIf
			Case $CodeType = "C"
				if StringRegExp(StringMid($Code,$i,2),"([0-9][0-9])") <> 1 Then
					$Code = StringMid($Code,1,$i - 1) & "¬B¬" & StringMid($Code,$i)
					$CodeType = "B"
					$i += 2 + 3
				Else
					$CodeType = "C"
					$i += 2
				EndIf
		EndSelect
		$len = StringLen($Code)
	WEnd

if StringMid($Code,1,3) <> "¬C¬" then $Code = "¬B¬" & $Code

$CodeArray = StringSplit($code,"")

	for $i = 1 to (UBound($CodeArray) - 3)
		Select
			case $CodeArray[$i] & $CodeArray[$i+1] & $CodeArray[$i+2] = "¬B¬"
				$CodeArray[$i] = "[B]"
				$CodeArray[$i+1] = ""
				$CodeArray[$i+2] = ""
			case $CodeArray[$i] & $CodeArray[$i+1] & $CodeArray[$i+2] = "¬C¬"
				$CodeArray[$i] = "[C]"
				$CodeArray[$i+1] = ""
				$CodeArray[$i+2] = ""
		EndSelect
	Next

	for $i = (UBound($CodeArray) - 1) to 1 step -1
		if $CodeArray[$i] = "" then _ArrayDelete($CodeArray,$i)
	Next

	$i = 1
	While $i <= (UBound($CodeArray) - 1)
		if $CodeArray[$i] = "[C]" Then
			$i += 1
			do
				if $CodeArray[$i] = "" then
					$i += 1
				Else
					$CodeArray[$i] &= $CodeArray[$i + 1]
					$CodeArray[$i + 1] = ""
					$i += 1
				EndIf
			Until $i = (UBound($CodeArray) - 1) Or $CodeArray[$i] = "[B]" or $CodeArray[$i + 1] = "[B]"
		EndIf
		$i += 1
	WEnd

	for $i = (UBound($CodeArray) - 1) to 1 step -1
		if $CodeArray[$i] = "" then _ArrayDelete($CodeArray,$i)
	Next

	_ArrayDelete($CodeArray,0)      ;important

	If $CodeArray[0] = "[B]" Then
		$CodeArray[0] = "11010010000"
		$SUM = 104
		$CodeType = "[B]"
	Else
		$CodeArray[0] = "11010011100"
		$SUM = 105
		$CodeType = "[C]"
	EndIf

	for $i = 1 to (UBound($CodeArray) - 1)
		if $CodeArray[$i] = "[B]" Then
			$CodeArray[$i] = "10111101110"
			$SUM += $i * 100
			$CodeType = "[B]"
			ContinueLoop
		EndIf
		if $CodeArray[$i] = "[C]" Then
			$CodeArray[$i] = "10111011110"
			$SUM += $i * 99
			$CodeType = "[C]"
			ContinueLoop
		EndIf
		for $j = 1 to (UBound($aCode128Patterns) - 1)
			$data = StringSplit($aCode128Patterns[$j],"¬")
			Select
				case $CodeType = "[B]"
					if $CodeArray[$i] == $data[2] Then
						$CodeArray[$i] = $data[4]
						$SUM += $i * $data[1]
					EndIf
				case $CodeType = "[C]"
					if $CodeArray[$i] == $data[3] Then
						$CodeArray[$i] = $data[4]
						$SUM += $i * $data[1]
					EndIf
			EndSelect
		Next
	Next

	$ChecksumItem = Mod($SUM,103)
	$data = StringSplit($aCode128Patterns[$ChecksumItem + 1],"¬")
	_ArrayAdd($CodeArray,$data[4])
	_ArrayAdd($CodeArray,"1100011101011")
	$CodeArrayString = _ArrayToString($CodeArray,"")
	Return $CodeArrayString
EndFunc ; _IdentifyCodeSwitches
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Latoid [?]
Про то, что можно сделать скриншот и сохранить его, знаю, но может есть какой-либо более грамотный способ?
а чем не нравится
Код:
_ScreenCapture_CaptureWnd (@ScriptDir & "\sreen.jpg", $BarCodeWindow)

?
можно задать области окна

если эти параметры можно было указать в сантиметрах, а не пикселях.
вот тут не совсем понял. это зачем? мониторы имеют разные разрешения и соответственно разное количество пикселей. а значит размеры окна в сантиметрах на разных мониторах будут разные.
 
Автор
L

Latoid

Знающий
Сообщения
95
Репутация
11
За _ScreenCapture_CaptureWnd - спасибо, не знал, как-то пропустил такую функцию.

вот тут не совсем понял. это зачем? мониторы имеют разные разрешения и соответственно разное количество пикселей. а значит размеры окна в сантиметрах на разных мониторах будут разные.

Картинка сохраняется не для демонстрации на мониторе, а для вставки в документ PDF в строго определенном месте листа А4. За пределы отведенной ей на листе области картинка не должна выползать.
 
A

Alofa

Гость
Есть такие две Функции:
Код:
_WinAPI_TwipsPerPixelX()
_WinAPI_TwipsPerPixelY()

Ну а дальше читайте *Здесь*.

Или сразу *Сюда*.
 
Автор
L

Latoid

Знающий
Сообщения
95
Репутация
11
Alofa сказал(а):
Есть такие две Функции:
Код:
_WinAPI_TwipsPerPixelX()
_WinAPI_TwipsPerPixelY()

Ну а дальше читайте *Здесь*.

Или сразу *Сюда*.

Потестил сейчас эти функции:
Код:
#include <WinAPI.au3>

$ifPixelWidthInTwips = _WinAPI_TwipsPerPixelX()  ; Возвращает ширину пикселя, в твипах.
$ifPixelHeightInTwips = _WinAPI_TwipsPerPixelY() ; Возвращает высоту пикселя, в твипах.

ConsoleWrite (1/($ifPixelWidthInTwips/567) & @CRLF)
ConsoleWrite (1/($ifPixelHeightInTwips/567) & @CRLF)


;~ Твип равен 1/1440 дюйма (точно) или 1/567 сантиметра (приближённо).


Пробовал на 3 мониторах (ноутбучном, внешнем, телевизоре), меняя разрешения. Всегда в любом случае у меня выдает кол-во пикселей в сантиметре 37.8 Так что это не решение проблемы, к сожалению.

Погуглил сейчас, нашел вот что. Если открыть PowerShell и ввести туда:
Код:
Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams
то у меня он выдает такую картину:
Active : True
DisplayTransferCharacteristic : 120
InstanceName : DISPLAY\LEN40E2\4&83a0626&0&UID67568640_0
MaxHorizontalImageSize : 28
MaxVerticalImageSize : 16
SupportedDisplayFeatures : WmiMonitorSupportedDisplayFeatures
VideoInputType : 1
PSComputerName :

Active : True
DisplayTransferCharacteristic : 120
InstanceName : DISPLAY\PHL1E52\4&83a0626&0&UID50535168_0
MaxHorizontalImageSize : 71
MaxVerticalImageSize : 40
SupportedDisplayFeatures : WmiMonitorSupportedDisplayFeatures
VideoInputType : 1
PSComputerName :

Где MaxHorizontalImageSize и MaxVerticalImageSize - размеры монитора в сантиметрах.

Тогда возникает следующий вопрос: как узнать на какой из мониторов у меня сейчас выводится картинка? В моем примере он отображает ноутбучный монитор и подключенный по HDMI телевизор. Картинка выведена на ноутбук. Если вывожу на телевизор очередность выдачи в консоль PowerShell не меняется.
 
A

Alofa

Гость
Код:
;~ Твип равен 1/1440 дюйма (точно) или 1/567 сантиметра (приближённо).
А вы дальше этих строк читали?
Разрешение экрана и разрешение рисунка это разные вещи. Посмотрите подробные свойства какого-нибудь сохраненного рисунка.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Latoid [?]
Картинка сохраняется не для демонстрации на мониторе, а для вставки в документ PDF в строго определенном месте листа А4. За пределы отведенной ей на листе области картинка не должна выползать.
значит нужно определить размер (в пикселях) места для вставки в самом документе и потом подогнать размер скрина . и это делать каждый раз перед вставкой в документ. тогда можно избежать ненужных вычислений
 
Верх