DTX Daten als Bild in GUI anzeigen

  • Einen Converter suchen welches das DTX in ein von Autoit unterstützes Format umwandelt.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Wenn du Photoshop hast, dann zieh dir einfach das Plugin vom gleichen Author und speichers als ein dir passenderes Format ab:D
    DTX Plugin Download


    Ich will ja, dass das Programm das selbstständig macht.


    Einen Converter suchen welches das DTX in ein von Autoit unterstützes Format umwandelt.


    Gibt's keine andere möglichkeiten in Autoit?

    Einmal editiert, zuletzt von Njahs (12. März 2012 um 18:50)

  • Wie soll Autoit ein Format verarbeiten welches es nicht kennt ;)?

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Wie soll Autoit ein Format verarbeiten welches es nicht kennt ;)?


    Gibt doch bestimmt eine möglichkeit, das in Autoit zu machen.

    Du kannst vllt mit einer Anwendung arbeiten, die das Konvertieren über Parameter beherrscht, und diese dann aus AutoIt heraus starten...?

    LG chess


    Google spuckt keine sinnvollen Sachen raus,
    nur uralte & nicht funktionierende,
    oder einfach iwas, dass nix mit DTX zu tun hat.
    Ich weiß ja, dass es irgendwie gehen muss,
    denn der DTX Viewer (Anhang...) macht's ja
    auch irgendwie.

    Einmal editiert, zuletzt von Njahs (17. März 2012 um 11:11)

  • Wenn du nicht selbst den Dekodierungsalgorithmus für das DTX Format zusammensuchen und in AutoIt umsetzen willst (was ein riesiger Haufen komplizierter Arbeit ist), oder jemanden findest der das für dich machen will (was ich bezweifle), dann gibt es keine Möglichkeit DTX Dateien per AutoIt zu lesen. Das ist keine pessimistische Aussage, sondern ein Fakt. Selbst wenn du es schaffen solltest, wäre eine Umsetzung in AutoIt ohne inline Assembler verdammt langsam...
    Daher chesstigers Idee mit dem Kommandozeilengesteuerten Konverter, was ja perfekt funktionieren würde. Aber wenn du keinen findest oder es einfach keinen gibt, dann sehe ich keine plausible Möglichkeit das in AutoIt zu machen.
    Eine weitere, wenn auch nicht so saubere Lösung wäre die Automatisierung eines Konverters mit AutoIt über die ControlClick etc. Funktionen.

  • Hi,
    hab da mal etwas zusammengebastelt, ist native AutoIt, aber zum Verstehen reichts....

    Zunächst mal habe ich mir die .DTX-Datei in Scite angeschaut, und eine "Struktur" und einen Header erkannt. Ist keine "Struktur" zu erkennen, wirds arbeitsintensiv, aber das war im vorliegenden Fall glücklicherweise nicht so ;)
    DTX in einen Hexeditor geladen, sah man den Header schon sehr deutlich, und auch die "Struktur" kam wesentlich besser raus.
    Immer 8 Bytes waren durch "FFFF00000000" getrennt, also schnell AutoIt angeworfen und folgende Zeilen eingetippt:

    [autoit]

    #include <Array.au3>
    $a=stringtobinary(fileread("beispiel.dtx"))
    $array=stringsplit($a,"FFFF000000000000",3)
    _arraydisplay($array)

    [/autoit]


    Klasse, der Header war von den Daten getrennt, und 20480 mal hatte ich 8 Bytes, das mussten die Bilddaten sein!

    Dann habe ich mir mit PushTheButton (hehe, Eigenwerbung darf sein) im DTX-Viewer mal die ersten Pixel angeschaut, sowie die Größe der Bitmap (512x512) bestimmt.

    Das Pixel oben links hat RGB 0x202220, aus der DTX-Datei (das ArrayDisplay() ) kamen die "Pixeldaten" 0x242104216AA92901
    Das hab ich mir dann mit Hilfe des Windows-Taschenrechners BITWEISE angeschaut
    0x202220 = 0010 0000 0010 0010 0010 0000 soweit sogut...
    Weiterhin erkennt man aus dem Arraydisplay(), dass die vorderen 4 Bytes sehr "regelmässig" sind und oft widederholt werden , während die hinteren 4 bytes völlig unstrukturiert sind.

    Also schaut man sich die vorderen 4 Bytes aus dem Arraydisplay mal an
    0x24210421 ergibt binär = 0010 0100 0010 0001 0000 0100 0010 0001

    Wer nun in Reverse Engeneering etwas Übung hat, "findet" nun Übereinstimmungen:
    0010 00 und
    100000 und
    00100 aus 0x202220 ist in
    0010 0100 0010 0001 0000 0100 0010 0001 enthalten ^^

    Hehe, das ist die von mir auch in Deskstream verwendete 565 Kodierung, um aus einer 32-Bit-Farbe eine 16 Bit-Farbe zu machen :thumbup:

    Also sind die ersten 4 Bytes aus dem Arraydisplay zwei "Farben RGB"
    Und die anderen 4 Bytes (32Bit)?
    Naja, die Grafik hat 512x512 Pixel also muss es zwangsläufig noch andere "Pixel" geben, das Arraydisplay zeigt ja nur 20480x2 Pixel an

    Schaut man sich die Pixelfarben im Viewer an, dann erkennt man, dass in 4x4-Pixelblöcken nur maximal 4 verschiedene Farben vorkommen....
    4x4 Pixel a nur 4 Farben, hehe, der Kenner weiss sofort, dass die 4 Zahlen 0 bis 3 binar in 2 Bit passen 8o
    Das heisst, in den 32 Bit stehen 16x2 Bit, also 16 (ist genau 4x4 Pixel^^) mal 2 Bit (4 Farben), claro?

    Die 32 Bit beschreiben also die "Farben" (wie eine Lookup-Tabelle) des 4x4 Pixelblocks.
    Aufschreiben hilft^^
    Wie erhält man 4 Farben aus 2 Farben? Naja, man interpoliert die beiden Farben "zwischen" den beiden bekannten Farben.
    Anhand der Lookup-Tabelle (den 32Bit hinter den 2x16Bit Farben im Arraydisplay) kann man nun den 4x4 Pixelblock zusammensetzen.

    So kompliziert hab ich mirs nicht gemacht, ich hab nur aus dem ersten bekannten "Pixel" (also den ersten 2 Byte=16Bit) aus dem Arraydisplay die Farbe extrahiert und in eine Grafik geschrieben^^
    Da statt 16 Pixel nur 1 Pixel gezeichnet wird, verkleinert sich natürlich die Grafik.
    Zum Erkennen reichts jedenfalls, wer die "Orginalgröße" braucht, kann entweder alle 16 Pixel in einem 4x4er Block berechnen oder einfach per "StretchBlt()" die Grafik vergrössern :D

    Die "Größe" (512x512) der Grafik holt man sich aus dem Header, woher sonst, viel Spass dabei, kompliziert ist das nicht^^

    Anzeige-Script für Beispiel.DTX:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <WinAPI.au3>
    #include <StructureConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $a = StringToBinary(FileRead("beispiel.dtx"))
    $array = StringSplit($a, "FFFF000000000000", 3)
    _ArrayDisplay($array)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;leere Bitmap erstellen
    Global $iwidth = 512 / 4, $iheight = 512 / 4, $ptr, $hbmp
    $DC_bmp = _CreateNewBmp32($iwidth, $iheight, $ptr, $hbmp)

    [/autoit] [autoit][/autoit] [autoit]

    ;struct an der Position der Bitmap im Speicher, um die "Pixel" schreiben zu können
    $struct = DllStructCreate("dword[" & $iwidth * $iheight & "]", $ptr)

    [/autoit] [autoit][/autoit] [autoit]

    ;Bitmap beschreiben mit Daten aus Arraydisplay
    For $i = 1 To UBound($array) - 1
    ;bytes in die richtige Reihenfolge bringen
    $col565_1 = StringLeft($array[$i], 2)
    $col565_2 = StringMid($array[$i], 3, 2)
    $col565 = Dec($col565_2 & $col565_1) ;16Bit-Farbe
    ;aus 16 Bit 565RGB nun 888RGB machen
    $r = Hex(BitShift(BitAND($col565, 0xF800), 8), 2)
    $g = Hex(BitShift(BitAND($col565, 0x7E0), 3), 2)
    $b = Hex(BitShift(BitAND($col565, 0x1F), -3), 2)

    [/autoit] [autoit][/autoit] [autoit]

    $col = Dec($r & $g & $b) ;32Bit-Farbe
    DllStructSetData($struct, 1, $col, $i)
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;gui
    $hgui = GUICreate("DTX-Viewer", $iwidth, $iheight)
    GUISetState()
    $DC_gui = _WinAPI_GetDC($hgui)

    [/autoit] [autoit][/autoit] [autoit]

    ;bitmap in Gui blitten, ggf stretchblt um volle grösse anzuzeigen
    _WinAPI_BitBlt($DC_gui, 0, 0, $iwidth, $iheight, $DC_bmp, 0, 0, 0xCC0020)

    [/autoit] [autoit][/autoit] [autoit]

    While GUIGetMsg() <> -3
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
    $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI, "Width", $iwidth)
    DllStructSetData($tBMI, "Height", -($iheight)) ;minus =standard = bottomup
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
    $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0) ;$DIB_RGB_COLORS = 0
    $hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    _WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
    Return $hcdc ;DC der Bitmap zurückgeben
    EndFunc ;==>_CreateNewBmp32

    [/autoit] [autoit][/autoit] [autoit]

    Func _DeleteBitmap32($DC, $ptr, $hbmp)
    _WinAPI_DeleteDC($DC)
    _WinAPI_DeleteObject($hbmp)
    $ptr = 0
    EndFunc ;==>_DeleteBitmap32

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • Nö, Augen aufgemacht und bissl geguckt^^
    "Begnadet" würde ich das nicht nennen, aber wissen, wonach man suchen muss ;)

  • Zitat

    Hätte nicht gedacht, dass sich jemand die Mühe macht.

    hehe, ich auch nicht, wobei trotz der Vorlage bestimmt noch ne Anfrage kommt, "den Arm aus der Sonne zu legen"! :rofl: Wette?


  • 8o hab zwar kaum was verstanden,
    das Script funktioniert aber (bei der Bsp.dtx).
    Könnte man es dynamisch machen, sprich,
    dass man das Script nicht für jede
    andere DTX neu machen muss?

  • Wie Andy schon in seinem Post erwähnt hat geht es nur mit der "einfachereren " Variante wenn Bitmuster offensichtlich erkennbar sind, habe auch nicht den gesamten Post verstanden aber dieses Script ist wohl nur darauf angepasst auf eine dtx die nach einem Bestimmten Muster aufgebaut ist um das ganze Dynamisch zu machen musst du glaube ich eine Menge zeit investieren..

    Gruß Marvin

  • Hi,

    Zitat von Njahs

    das Script funktioniert aber (bei der Bsp.dtx).

    Das Script funktioniert nicht nur bei der Beispieldatei, sondern bei allen dtx-files, die nach diesem Schema aufgebaut sind.
    Die Hauptarbeit ist gemacht, die Breite und Höhe der Bitmap liest man aus dem Header aus, man sollte wissen, wie 512 als Hexadezimalzahl geschrieben wird.
    Ich denke, das muss man auch von einem absoluten Newbie erwarten :D
    Wer nicht in der Lage ist, den Windows-Taschenrechner zu bedienen, der hat auch bei AutoIt nichts verloren...

    Zitat

    Könnte man es dynamisch machen, sprich,
    dass man das Script nicht für jede
    andere DTX neu machen muss?

    kapier ich nicht....ich hab das mit ca. 10 DTX-files getestet, funzt einwandfrei


    Zitat von protex

    habe auch nicht den gesamten Post verstanden

    kein Problem^^

    Zitat

    aber dieses Script ist wohl nur darauf angepasst auf eine dtx die nach einem Bestimmten Muster aufgebaut ist

    falsch s.o., wie gesagt, etwas Eigeninitiative erwarte ich einfach, um solche Kleinigkeiten wie Breite und Höhe aus einer Datei auszulesen.

    Zitat

    um das ganze Dynamisch zu machen musst du glaube ich eine Menge zeit investieren..

    hat mich insgesamt bisher eine halbe bis dreiviertel Stunde gekostet, wer das nicht investieren will/kann, der braucht auch definitiv keinen DTX-Viewer in AutoIt!