GUICtrlCreateIcon kann man auf eine ico- oder bmp-Datei anwenden.
Was kann ich ein Icon mit einer png-Datei erzeugen?
Recht vielen Dank schon einmal für eine Antwort.
GUICtrlCreateIcon kann man auf eine ico- oder bmp-Datei anwenden.
Was kann ich ein Icon mit einer png-Datei erzeugen?
Recht vielen Dank schon einmal für eine Antwort.
Ich weiß nicht, wie du das meinst.
Es geht mir darum, ein Control zu erzeugen, welches ein Handel zurückgibt, auf das ich mich später beziehen kann. Z.B. durch anklicken mit der Maus.
Ich glaube oh-ha meint damit, dass du aus der .png ein .ico machen sollst. Eigentlich willst du ja aber die .png so wie sie ist in einem Ctrl verwenden.
Ich vermute, dass UEZ dafür eine Funktion hat (wahrscheinlich sogar 5 verschiedene für jeden nur erdenklicken Ctrltyp + GUIs). Habe auch etwas gegoogelt, aber nicht die richtige gefunden (nur eine die das komplette Fenster benutzt um eine .png anzuzeigen). Ich bin leider nicht fit mit Winapi & Sendmessage, sonst würde ich die 3 Zeilen selbst aufschreiben...
lg
M
Schau mal hier: _GuiCtrlSetImageEx
Vielen Dank für eure Antworten!!!
oh-ha
IrfanView habe ich auch installiert und habe jetzt kapiert, wie du das meinst.
Mir würde nur nicht gefallen, eine andere Software in mein Problem einzubinden. Würde wahrscheinlich auch verlangsamen.
Aber wenn alles andere nicht geht, müsste ich das wohl so machen.
Mars
Es muss nicht sein, dass ich "die .png so wie sie ist", verwenden muss.
Winapi ist leider auch nicht so mein Ding.
Bitnugger
Die Funktion _GuiCtrlSetImageEx ist mir beim Googeln auch schon über den Weg gelaufen. Blos in meinem Autoit3.3.8.1 gibt es sie nicht. Ich hatte früher auch schon Autoit3.3.12.0 installiert, musste das aber wieder verwerfen, weil dort der Befehl FileRead so verändert wurde, dass man beispielsweise eine Bitmap-Datei nicht mehr einlesen konnte - so wie sie ist. Sie wird in Hex-Zeichen umgewandelt. Aber von dem Ordner "C:\Program Files (x86)\AutoIt3" hatte ich mir damals einen Backup zurückbehalten. Aber _GuiCtrlSetImageEx ist dort auch nicht enthalten.
Aber Dein Link zu _GuiCtrlSetImageEx hat mir insofern geholfen, als dort im Beispiel GuiCtrlSetImageEx.au3 die Funktion _GuiCtrlSetImageEx explizit ausgewiesen ist.
Damit werde ich nun erst einmal weiterexperimentieren.
Ich werde mich dann wieder zurückmelden.
Nochmals vielen Dank euch allen.
Gruß Dieter
Jetzt sehe ich es erst:
_GuiCtrlSetImageEx hat ja Oscar selbst geschrieben
Ich komme nicht weiter. Wen ich das Example unter
abarbeiten möchte, kommt diese STDOUT:
>"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "D:\Programmdaten\Desktop\CreateIcon\Example.au3" /UserParams
+>16:59:14 Starting AutoIt3Wrapper v.16.612.1119.0 SciTE v.3.6.6.0 Keyboard:00000407 OS:WIN_81/ CPU:X64 OS:X64 Environment(Language:0407) CodePage:0 utf8.auto.check:4
+> SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE UserDir => C:\Users\ffff\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper SCITE_USERHOME => C:\Users\ffff\AppData\Local\AutoIt v3\SciTE
>Running AU3Check (3.3.10.2) from:C:\Program Files (x86)\AutoIt3 input:D:\Programmdaten\Desktop\CreateIcon\Example.au3
! Au3check doesn't support input files encoded as UTF8 with BOM: D:\Programmdaten\Desktop\CreateIcon\Example.au3
D:\Programmdaten\Desktop\CreateIcon\Example.au3 - 1 error(s), 0 warning(s)
!>16:59:14 AU3Check ended. Press F4 to jump to next error.rc:2
+>16:59:14 AutoIt3Wrapper Finished.
>Exit code: 2 Time: 0.5582
Mit
Au3check doesn't support input files encoded as UTF8 with BOM
weiß ich nichts anzufangen.
Sorry, aber Uralt-Versionen von AutoIt werde ich nicht supporten.
AutoIt:
3.3.14.0 (10th July, 2015) (Release)
Au3Check:
Fazit: Dein AutoIt (Au3Check) ist zu alt... also entweder eine aktuellere Version installieren, oder die Datei (das Example) als UTF-8 ohne BOM speichern.
Siehe auch hier: BOM
musste das aber wieder verwerfen, weil dort der Befehl FileRead so verändert wurde, dass man beispielsweise eine Bitmap-Datei nicht mehr einlesen konnte - so wie sie ist. Sie wird in Hex-Zeichen umgewandelt.
Wie sieht denn deiner Meinung nach eine (Bitmap)-Datei aus, so wie sie ist
Meinst du den Schwachsinn, den ein (zum Lesen von Text-Dateien gedachter) Editor ausspuckt, weil dieser krampfhaft versucht eine binäre Datei als Text zu interpretieren?
Kannst du doch haben:
Local $p = "C:\Users\BugFix\Pictures\flowers24x24.png"
Local $fh = FileOpen($p, 16) ; $FO_BINARY (16)
Local $read = BinaryToString(FileRead($fh))
FileClose($fh)
; Datei enthält mit Sicherheit Chr(0)-Werte, die würden als Stringende interpretiert werden - also umwandeln
$read = StringReplace($read, Chr(0), '[NULL]')
; Vielleicht möchtest du CR und LF auch als Zeilenumbrüche anzeigen (Edit verlangt normal CRLF):
; dazu alle bereits vorhandenen CR, LF, CRLF in ein Ersatzzeichen umwandeln und dann dieses mit CRLF ersetzen
Local $tmp = '%%µµ%%'
$read = StringReplace(StringReplace(StringReplace($read, @CRLF, $tmp), @LF, $tmp), @CR, $tmp)
$read = StringReplace($read, $tmp, @CRLF)
GUICreate('Anzeigen BinaryToString', @DesktopWidth-90, @DesktopHeight-60)
GUISetFont(14, 400, Default, 'Courier New')
GUICtrlCreateButton('', -10, -10, 1, 1) ; catch focus
GUICtrlCreateEdit($read, 10, 10, @DesktopWidth-100, @DesktopHeight-70, BitOR(0x0800,0x0040,0x0080,0x0004,0x00100000,0x00200000))
GUICtrlSetColor(-1, 0x00D02B)
GUICtrlSetBkColor(-1, 0x001D45)
GUISetState()
Do
Until GUIGetMsg() = -3
Alles anzeigen
Wenn du bestimmte Aufgaben mit FileRead vorhast, ist primär wichtig, die Datei im entsprechenden Modus zu öffnen! Dazu sollte man einfach mal einen Blick auf die Parameterbeschreibungen der Funktion werfen.
Deine obige Aussage zu FileRead ist definitiv falsch.
Wie sieht denn deiner Meinung nach eine (Bitmap)-Datei aus, so wie sie ist
Jedes Zeichen ( 8 Bit) in der Datei sollte, wenn es eingelesen ist, auch wieder als ein Zeichen mit den gleichen Bits erscheinen.
Beispielsweise soll also des Zeichen 10001111 hexadezimal als 0x8F erscheinen und nicht (wie bei Autoit3.3.12.0) als zwei Zeichen 0x3846 ("8F").
Ich werde als nächstes das neuste Autoit installieren und dann weitersehen.
Im Sommer arbeite ich viel im Garten, deshalb entschuldgt bitte, wenn meine Reaktionrn nur zögerlich erfolgen.
Ich melde mich wieder.
Dank und Gruß an euch alle
Dieter
Ich habe jetzt die neuste Version von Autoit installiert.
Nun habe ich wieder das gleiche Problem: Wie kann ich eine Bitmap-Datei einlesen?
Ich habe beispielsweise die Datei
und möchte sie mit dem Programm
einlesen. Die Datei besitzt eine Länge von 306 Bytes und genau dies 306 Bytes will ich so einlesen. Eingelesen werden aber 614 Zeichen. Jedes Byte wird nämlich in Form von zwei Hexadezimal-Ziffern ins Textformat konvertiert.
Was kann ich tun?
Wie bereits gesagt, klappte das unter Autoit 3.3.8.1 noch einwandfrei. Wen es interessiert: ich habe noch einen Backup der Setup-Datei von Autoit 3.3.8.1 und kann diesen zur Verfügung stellen.
FileOpen im BinaryMode. Sowohl beim lesen als auch beim speichern.
Alles andere ist sowieso unsinnig.
Es macht auch gar keinen Sinn, eine Datei mit binären Daten in einem Texteditor anzeigen zu lassen.
Im besten Fall versucht der Editor die Daten irgendwie als Zeichen darzustellen. Im schlechtesten Fall bricht er die Darstellung beim Nullbyte ab.
Also wenn eine Darstellung, dann in einem Programm, dass die Daten als Bytefolge darstellen kann, meist im Hexadezimalformat (z.B. HxD "https://mh-nexus.de/de/"). Man kann aber auch AutoIt dafür verwenden:
#include <EditConstants.au3>
#include <FileConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$sSource = "rot.bmp"
$iSize = FileGetSize($sSource)
$hFile = FileOpen($sSource, $FO_BINARY)
$dData = FileRead($hFile)
FileClose($hFile)
$iLen = BinaryLen($dData)
MsgBox(0, "", "Datenlänge: " & $iLen & @CRLF & "Dateilänge: " & $iSize)
_HexView($dData)
;~ $sDest = "anzeige.bmp"
;~ $hFile = FileOpen($sDest, $FO_OVERWRITE + $FO_BINARY)
;~ FileWrite($hFile, $dData)
;~ FileClose($hFile)
Func _HexView(ByRef $dData)
Local Const $CRYPT_STRING_HEXASCIIADDR = 0x0000000B
Local $hGui = GUICreate('HexView', 800, 600, -1, -1, BitOR($WS_POPUPWINDOW, $WS_CAPTION))
GUISetBkColor(0xCCCCCC)
GUICtrlCreateLabel('Offset', 10, 10, 100, 20)
GUICtrlSetFont(-1, 12, 400, 0, 'Courier New', 5)
For $i = 0 To 15
GUICtrlCreateLabel(Hex($i, 2), 90 + $i * 30 + (($i > 7) * 10), 10, 20, 20)
GUICtrlSetFont(-1, 12, 400, 0, 'Courier New', 5)
Next
GUICtrlCreateLabel('ASCII Chars', 600, 10, 190, 20)
GUICtrlSetFont(-1, 12, 400, 0, 'Courier New', 5)
Local $idHexView = GUICtrlCreateEdit('', 5, 30, 790, 560, BitOr($WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY))
GUICtrlSetFont(-1, 12, 400, 0, 'Courier New', 5)
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetLimit(-1, 2 ^ 32)
GUISetState()
GUICtrlSetData($idHexView, _WinAPI_CryptBinaryToString($dData, $CRYPT_STRING_HEXASCIIADDR))
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete($hGui)
EndFunc
; Author: Kleiner (www.autoit.de)
Func _WinAPI_CryptBinaryToString($vString, $Flag)
Local $Struc = DllStructCreate('byte[' & BinaryLen($vString) & ']')
DllStructSetData($Struc, 1, $vString)
Local $Call = DllCall('crypt32.dll', 'int', 'CryptBinaryToString', _
'ptr', DllStructGetPtr($Struc), _
'dword', DllStructGetSize($Struc), _
'dword', $Flag, _
'ptr', 0, _
'dword*', 0)
If @error Or Not $Call[0] Then Return SetError(1, 0, '')
Local $iSize = $Call[5]
Local $Struc_1 = DllStructCreate('char[' & $iSize & ']')
$Call = DllCall('crypt32.dll', 'int', 'CryptBinaryToString', _
'ptr', DllStructGetPtr($Struc), _
'dword', DllStructGetSize($Struc), _
'dword', $Flag, _
'ptr', DllStructGetPtr($Struc_1), _
'dword*', $iSize)
If @error Or Not $Call[0] Then Return SetError(2, 0, '')
Return SetError(0, 0, DllStructGetData($Struc_1, 1))
EndFunc ;==>_WinAPI_CryptBinaryToString
Alles anzeigen
Hallo Oscar,
vielen Dank dafür, dass du dir so viel Mühe mit mir gibst.
Ich habe jedoch Schwierigkeiten dein Beispiel zu verstehen.
Ich kenne mich leider mit Strukturen und DLL-Aufrufen nicht aus.
Deshal habe ich die Information nicht gefunden, wie die im Feld "ASCII Chars" stehenden Zeichen ermittelt wurden.
In deinem Beispiel hattest du di Funktion BinaryLen verwendet. Das hat mich auf die Idee gebracht nach weiteren Binary-Funktionen zu suchen und ich habe die Funktion BinaryToString gefunden, die meine Wünsche erfüllt . Sie ist auch sehr schell und benötigt z. B für einen 1920 X 1080 - Screenschot nur 12 Millisekunden. Ich werde sie in meine Bitmap-Programme nach dem FileRead einfügen und dann wird alles wieder funktionieren.
Übrignes hatte Andy unter
im Beitrag #8
im Jahre 2016 ein Programm eingestellt, das sich mit der Auswertung einer Bitmap-Datei unter den bedingungen von Autoit 3.3.8.1 befasste. Wie ich festelle hat er das - ebenfalls unter Verwendung von Strukture - inzwischen auf die neuen Autoit-Versionen angepasst. Es stellt nun wieder fest, dass die Datei rot.bmp aus 81 Rot-Pixeln besteht.
Nochmasl recht vielen Dank
Gruß
Dieter
ich habe die Funktion BinaryToString gefunden, die meine Wünsche erfüllt .
Was genau willst Du damit erreichen?
Was macht es für einen Sinn, die Binärdaten von einem Bild in ein String umzuwandeln?
Jedes Pixel eines Bildes besteht ja aus den drei Farben blau, grün und rot. In der Bitmapdatei wird entsprechend jedes Pixel durch drei Bytes beschrieben, welche die Werte 0 bis 255 annehmen können. Und diese Werte benötige ich, wenn ich Pixel bearbeiten möchte.
Beispiel:
Die Datei
soll mit demProgramm
bearbeitet werden.
Die Bitmapdatei rot1.bmp sieht 8-fach gezoomt so aus:
Jede Bitmap-Datei hat am Anfang einen 54 Bytes langen Header:
Danach folgen je drei Byte für jedes Pixel (blau grün rot). Das erste Pixel ist das in der linken unteren Ecke.
Das Programm Test.au3 ersetzt das 5. Pixel durch die Farbe weiß und gibt die veränderte Datei als rot2.bmp aus.
Die Bitmapdatei rot2.bmp sieht 8-fach gezoomt so aus:
Sollen in einer großen Bitmap-Datei viele Pixel bearbeitet werden, dann muss man dazu Assembler-Befehle verwenden. Sonst dauert es ewig.
Ich hoffe, dass ich deine Frage richtig interpretiert habe.
Ich habe Dir mal ein Script geschrieben, wie ich das angehen würde:
#include <Array.au3>
#include <WinAPIFiles.au3>
#include <WinAPIHObj.au3>
#include <WinAPIInternals.au3>
Global $sFilename = @ScriptDir & '\rot1.bmp'
Global $aPixel = _ReadPixel($sFilename)
_ArrayDisplay($aPixel)
Func _ReadPixel($sFilename)
Local $tOffset = DllStructCreate('ulong offset')
Local $tDim = DllStructCreate('ulong width; ulong height')
Local $tBPP = DllStructCreate('ushort bpp')
Local $nBytes, $iPad, $iPixelCount, $iBGR, $iOffset = 1
Local $hFile = _WinAPI_CreateFile($sFilename, 2, 2) ; Datei zum lesen oeffnen
If Not $hFile Then Return SetError(1)
_WinAPI_SetFilePointer($hFile, 0x0A) ; 0x0A = Offset auf die Pixeldaten
_WinAPI_ReadFile($hFile, $tOffset, 4, $nBytes) ; 4 Bytes aus der Datei lesen
ConsoleWrite('Offset = ' & $tOffset.offset & @CRLF) ; nur zum debuggen
_WinAPI_SetFilePointer($hFile, 0x12) ; 0x12 = Anfang von Width und Height
_WinAPI_ReadFile($hFile, $tDim, 8, $nBytes) ; 8 Bytes aus der Datei lesen
ConsoleWrite('Width = ' & $tDim.width & @CRLF) ; nur zum debuggen
ConsoleWrite('Height = ' & $tDim.height & @CRLF) ; nur zum debuggen
_WinAPI_SetFilePointer($hFile, 0x1C) ; 0x1C = Bits per Pixel
_WinAPI_ReadFile($hFile, $tBPP, 2, $nBytes) ; 2 Bytes aus der Datei lesen
ConsoleWrite('BPP = ' & $tBPP.bpp & @CRLF) ; nur zum debuggen
$iPad = Ceiling($tDim.width * 3 / 4) * 4 - $tDim.width * 3 ; das Padding pro Scanzeile ausrechnen
$iPixelCount = ($tBPP.bpp / 8) * $tDim.width * $tDim.height + $iPad * $tDim.height ; wie viele Pixel
Local $tPixel = DllStructCreate('byte[' & $iPixelCount & ']') ; Struktur mit den Bytes erstellen
_WinAPI_SetFilePointer($hFile, $tOffset.offset) ; Filepointer auf den Offset der Pixeldaten setzen
_WinAPI_ReadFile($hFile, $tPixel, $iPixelCount, $nBytes) ; alle Pixeldaten einlesen
_WinAPI_CloseHandle($hFile) ; Datei schliessen
Local $aOut[$tDim.width * $tDim.height], $iCount = 0 ; Ausgabe-Array
For $iY = 0 To $tDim.height - 1 ; Zeilen-Schleife
For $iX = 0 To $tDim.width - 1 ; Spalten-Schleife
$iBGR = 0
For $i = 0 To 2 ; Schleife fuer B, G, R
$iBGR = BitOR($iBGR, BitShift(DllStructGetData($tPixel, 1, $iOffset), -(16 - $i * 8)))
$iOffset += 1
Next
ConsoleWrite('0x' & Hex($iBGR, 6) & ', ') ; nur zum debuggen
$aOut[$iCount] = '0x' & Hex($iBGR, 6)
$iCount += 1
Next
$iOffset += $iPad ; nach jeder Scanzeile werden Padding-Bytes eingefuegt (0-3)
ConsoleWrite(@CRLF) ; nur zum debuggen
Next
Return $aOut
EndFunc
Alles anzeigen
Du könntest ja auch, wie wohl dein voriges Programm arbeitete, die Datei in einzelnen Bytes einlesen. Das ganze in einem 1-basiertem Array und du kannst zielgenau zugreifen.
Wobei ich ein Arbeiten mit FileSetPos / Read / Write / Flush bevorzugen würde, da dann in einem Aufwasch gelesen und geschrieben werden kann.