Sign in to follow this  
Followers 0
LeeRekka

I need help with tile viewer

13 posts in this topic

#1 ·  Posted (edited)

how i draw in window a image rgb binary without header without being pixel by pixel

I tried with gdi more it didn't work :)

Edited by LeeRekka

Share this post


Link to post
Share on other sites



#include <GDIPlus.au3>
#Include <WinAPI.au3>

Opt('GUIOnEventMode', 1)

$MainWindow = GUICreate("Test Draw", 320, 240, -1, -1)
GUISetOnEvent(-3, "CLOSEClicked",$MainWindow)
GUISetState(@SW_SHOW)

$Button0001 = GUICtrlCreateButton(" Open dracula.bin ",0,200,100,20)
GUICtrlSetOnEvent($Button0001, "Button0001")

While 1
    Sleep(1)
WEnd

Func Button0001()
    $hDC = _WinAPI_GetDC($mainwindow)
    $hGDI32 = DllOpen("gdi32.dll")
    $Image0001_Address = 0
        For $i2 = 0 To 111 Step 1 ; Height
            For $i3 = 0 To 95 Step 1 ; Width
                $Pixel0001 = FileReadHex0001(".\dracula.bin",$Image0001_Address,3)
                DllCall($hGDI32, "long", "SetPixel", "long", $hDC, "long", $i3, "long", $i2, "long", "0x" & StringMid($Pixel0001, 7, 2) & StringMid($Pixel0001, 5, 2) & StringMid($Pixel0001, 3, 2))
                $Image0001_Address += 3
            Next
        Next
        
    DllClose($hGDI32)
    _WinAPI_ReleaseDC($mainwindow, $hDC)
EndFunc
    
Func FileReadHex0001($FF_File,$FF_Address,$FF_Bytes) ; by LeeRekka
    $FF_FileSize = FileGetSize($FF_File)
    If $FF_Address > $FF_FileSize Or $FF_Bytes = 0 Then Return ""
    Local $hFile, $sData, $tData, $iRead
    If $FF_Address + $FF_Bytes > $FF_FileSize Then $FF_Bytes -= $FF_Address + $FF_Bytes - $FF_FileSize
    $tData = DllStructCreate('byte[' & $FF_Bytes & ']')
    $hFile = _WinAPI_CreateFile($FF_File, 2, 2, 2)
    _WinAPI_SetFilePointer($hFile, $FF_Address)
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tData), $FF_Bytes, $iRead)
    _WinAPI_CloseHandle($hFile)
    Return DllStructGetData($tData, 1)
EndFunc

Func CLOSEClicked()
  ;Note: at this point @GUI_CTRLID would equal $GUI_EVENT_CLOSE,
  ;@GUI_WINHANDLE will be either $mainwindow or $dummywindow
    If @GUI_WINHANDLE = $MainWindow Then 
        Exit
    Else
        GUIDelete(@GUI_WINHANDLE)
    EndIf
EndFunc

..slow.

Share this post


Link to post
Share on other sites

not of the to draw all binary at once without the loop :)

Share this post


Link to post
Share on other sites

Local $begin1 = TimerInit()

$BMP = _BMPCreateMod(95, 111) ;Creates customize bitmap handle (suitable for BMP.au3 UDF only.)

_BMPWrite($BMP, @ScriptDir & "\MyBMP.bmp");Closes the BMP to a file

ConsoleWrite("TOTAL TIME = " & TimerDiff($begin1) & @CRLF)

GUICreate("BMP Example", $BMP[1] + 20, $BMP[2] + 20)
GUICtrlCreatePic(@ScriptDir & "\MyBMP.bmp", 10, 10, $BMP[1], $BMP[2])
GUISetState()

Do
    $msg = GUIGetMsg()
Until $msg = -3;$GUI_EVENT_CLOSE


Func _BMPCreateMod($Width, $Height)
    Local $imageData

    ;***BMP header (54bytes total)***
    Local $Header = "0x424D00000000000000003600000028000000" & _
            _Reverse8(Hex($Width, 8)) & _       ;4bytes, bitmap width
            _Reverse8(Hex($Height, 8)) & _  ;4bytes, bitmap hieght
            "0100180000000000" & _
            _Reverse8(Hex(($Height) * ($Width) * 3 + ($Height * Mod($Width, 4)), 8)) & _    ;4bytes, bitmap data size
            "00000000000000000000000000000000"

    $file = FileOpen("dracula.bin", 16)

    $imageData = StringTrimLeft(FileRead($file), 2)

    FileClose($file)

    Local $BMPHandle[4] = [Mod($Width, 4), $Width, $Height, $Header & $imageData]
    Return $BMPHandle
EndFunc ;==>_BMPCreateMod

;Copied from BMP.au3 file @ http://www.autoitscript.com/forum/index.php?showtopic=27362&view=findpost&p=193704
Func _Reverse8($inHex)
    Return StringMid($inHex, 7, 2) & StringMid($inHex, 5, 2) & StringMid($inHex, 3, 2) & StringMid($inHex, 1, 2)
EndFunc ;==>_Reverse8

;Copied from BMP.au3 file @ http://www.autoitscript.com/forum/index.php?showtopic=27362&view=findpost&p=193704
Func _BMPWrite(ByRef $BMPHandle, $Fpath, $Progress = 1)
    If IsArray($BMPHandle) = False Then Return 0
    $out = FileOpen($Fpath, 18)
    If $out = -1 Then Return -1
    FileWrite($out, $BMPHandle[3])
    FileClose($out)
    Return 1
EndFunc ;==>_BMPWrite

Faster.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

#include <GDIPlus.au3>
#Include <WinAPI.au3>
Global $sFile, $sText, $nBytes, $tBuffer
Opt('GUIOnEventMode', 1)

$MainWindow = GUICreate("Test Draw", 320, 240, -1, -1)
GUISetOnEvent(-3, "CLOSEClicked",$MainWindow)
GUISetState(@SW_SHOW)

$Button0001 = GUICtrlCreateButton(" Open dracula.bin ",0,200,100,20)
GUICtrlSetOnEvent($Button0001, "Button0001")

While 1
    Sleep(1)
WEnd

Func Button0001()
    LoadFileInMemory()
    $hDC = _WinAPI_GetDC($mainwindow)
    $hGDI32 = DllOpen("gdi32.dll")
    $Image0001_Address = 0
    $adres = 1
        For $i2 = 0 To 111 Step 1 ; Height
            For $i3 = 0 To 95 Step 1 ; Width
                $pixel = DllStructGetData($tBuffer, 1, $adres)
                DllCall($hGDI32, "long", "SetPixel", "long", $hDC, "long", $i3, "long", $i2, "long", "0x" & Hex($pixel,2))
                $adres +=3
            Next
        Next
    DllClose($hGDI32)
    _WinAPI_ReleaseDC($mainwindow, $hDC)
EndFunc

Func LoadFileInMemory()
$sFile = @ScriptDir & '\dracula.bin'
$tBuffer = DLLStructCreate("byte[" & FileGetSize($sFile) &"]")
$hFile = _WinAPI_CreateFile($sFile, 2, 2)
_WinAPI_SetFilePointer($hFile, 0)
_WinAPI_ReadFile($hFile, DLLStructGetPtr($tBuffer), FileGetSize($sFile), $nBytes)
_WinAPI_CloseHandle($hFile)
EndFunc

Func CLOSEClicked()
  ;Note: at this point @GUI_CTRLID would equal $GUI_EVENT_CLOSE,
  ;@GUI_WINHANDLE will be either $mainwindow or $dummywindow
    If @GUI_WINHANDLE = $MainWindow Then
        Exit
    Else
        GUIDelete(@GUI_WINHANDLE)
    EndIf
EndFunc

It works faster than original, because it's reads the file only ONCE instead of 10545(!) times, but i don't know why it draws only red colours, and also not understood why NEED to write $adres +=3(why "3")..

(theoretically, it will be faster(if comparing with what i wrote edited) to convert *.bin to .bmp and just update PictureBox)

Edited by Godless

_____________________________________________________________________________

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Your script, Malkey, have a similar bug with my, it draws only blue colours. :)

Edited by Godless

_____________________________________________________________________________

Share this post


Link to post
Share on other sites

This version reverses the file, making the data look more sensible in the bitmap file format.

Another version, another image.

Local $begin1 = TimerInit()

$BMP = _BMPCreateMod(95, 111) ;Creates customize bitmap handle (suitable for BMP.au3 UDF only.)

_BMPWrite($BMP, @ScriptDir & "\MyBMP.bmp");Closes the BMP to a file

ConsoleWrite("TOTAL TIME = " & TimerDiff($begin1) & @CRLF)

GUICreate("BMP Example", $BMP[1] + 20, $BMP[2] + 20)
GUICtrlCreatePic(@ScriptDir & "\MyBMP.bmp", 10, 10, $BMP[1], $BMP[2])
GUISetState()

Do
    $msg = GUIGetMsg()
Until $msg = -3;$GUI_EVENT_CLOSE


Func _BMPCreateMod($Width, $Height)
    Local $imageData, $sReverse, $iCount

    ;***BMP header (54bytes total)***
    Local $Header = "0x424D00000000000000003600000028000000" & _
            _Reverse8(Hex($Width, 8)) & _   ;4bytes, bitmap width
            _Reverse8(Hex($Height, 8)) & _ ;4bytes, bitmap hieght
            "0100180000000000" & _
            _Reverse8(Hex(($Height) * ($Width) * 3 + ($Height * Mod($Width, 4)), 8)) & _    ;4bytes, bitmap data size
            "00000000000000000000000000000000"

    $file = FileOpen("dracula.bin", 16)
    $sString = StringTrimLeft(FileRead($file), 2)
    FileClose($file)

    ; Reverse bytes of entire file. i.e. last bytes becomes first byte.
    For $iCount = 1 To StringLen($sString) Step 2
        $imageData = StringMid($sString, $iCount, 2) & $imageData
    Next

    Local $BMPHandle[4] = [Mod($Width, 4), $Width, $Height, $Header & $imageData]
    Return $BMPHandle
EndFunc ;==>_BMPCreateMod

;Copied from BMP.au3 file @ http://www.autoitscript.com/forum/index.php?showtopic=27362&view=findpost&p=193704
Func _Reverse8($inHex)
    Return StringMid($inHex, 7, 2) & StringMid($inHex, 5, 2) & StringMid($inHex, 3, 2) & StringMid($inHex, 1, 2)
EndFunc ;==>_Reverse8

;Copied from BMP.au3 file @ http://www.autoitscript.com/forum/index.php?showtopic=27362&view=findpost&p=193704
Func _BMPWrite(ByRef $BMPHandle, $Fpath, $Progress = 1)
    If IsArray($BMPHandle) = False Then Return 0
    $out = FileOpen($Fpath, 18)
    If $out = -1 Then Return -1
    FileWrite($out, $BMPHandle[3])
    FileClose($out)
    Return 1
EndFunc ;==>_BMPWrite

Share this post


Link to post
Share on other sites

This one is faster, ability to flip horizontally and save image.

An interesting discovery is commented line #99, about the changeable cape colour.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>

Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled
Global $ApW = 95, $ApH = 111
Global $Button[2], $nPI = 3.1415926535897932384626433832795, $bFlip = False, $bSave = False

$hGui = GUICreate("GDIPlus Graphics on Picture Control - OnEvent Mode", $ApW + 40, $ApH + 40)
GUISetOnEvent(-3, "_Quit")
GUISetBkColor(0xff8080, $hGui)

$Pic = GUICtrlCreatePic("", 20, 20, $ApW, $ApH)
GUICtrlSetState(-1, $GUI_DISABLE)

$Button[0] = GUICtrlCreateButton("Flip", ($ApW - 50 + 40) / 6, $ApH + 40 - 20, 50, 20)
GUICtrlSetOnEvent($Button[0], "Flip")
GUICtrlSetBkColor(-1, 0x800000)
GUICtrlSetColor(-1, 0xBadB0B)

$Button[1] = GUICtrlCreateButton("Save", ($ApW - 50 + 40) * 5 / 6, $ApH + 40 - 20, 50, 20)
GUICtrlSetOnEvent($Button[1], "Save")
GUICtrlSetBkColor(-1, 0x000080)
GUICtrlSetColor(-1, 0xBadB0B)

Local $begin1 = TimerInit()
PicSetGraphics($Pic, $ApW, $ApH)
ConsoleWrite("_BMPCreate = " & TimerDiff($begin1) & @CRLF)

While 1
    Sleep(10)
WEnd

Func PicSetGraphics($cID, $iW, $iH)
    Local Const $STM_SETIMAGE = 0x0172
    Local Const $IMAGE_BITMAP = 0
    Local $hWnd, $hBitmap, $hImage, $hGraphic, $hBrush, $hBrush1, $hbmp, $aBmp
    $hWnd = GUICtrlGetHandle($cID)
    _GDIPlus_Startup()

    $hBitmap = WinAPI_CreateSolidBitmap($hGui, 0xFFFFFF, $iW, $iH)

    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)

    ;================== Rotate image 180 deg. =============================================
    If $bFlip Then
        _GDIPlus_DrawImagePoints($hGraphic, $hImage, $iW, $iH, 0, $iH, $iW, 0); cape on left
    Else
        _GDIPlus_DrawImagePoints($hGraphic, $hImage, 0, $iH, $iW, $iH, 0, 0); cape on right
    EndIf
    ;======================================================================================

    GUISetState(@SW_SHOW, $hGui)

    $hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $aBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hbmp)
    _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME))

    ; Save Graphics on picture control
    If $bSave Then
        _GDIPlus_ImageSaveToFile($hImage, @DesktopDir & "\TestWrite1.bmp")
        ShellExecute(@DesktopDir & "\TestWrite1.bmp")
    EndIf

    If $aBmp[0] <> 0 Then _WinAPI_DeleteObject($aBmp[0])
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_GraphicsDispose($hGraphic)
    _WinAPI_DeleteObject($hbmp)
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_Shutdown()
EndFunc ;==>PicSetGraphics

Func Save()
    $bSave = True
    PicSetGraphics($Pic, $ApW, $ApH)
    $bSave = False
EndFunc ;==>Save

Func Flip()
    $bFlip = Not $bFlip
    Local $begin1 = TimerInit()
    PicSetGraphics($Pic, $ApW, $ApH)
    ConsoleWrite("_BMPCreate = " & TimerDiff($begin1) & @CRLF)
EndFunc ;==>Flip

Func _Quit()
    Exit
EndFunc ;==>_Quit

Func WinAPI_CreateSolidBitmap($hWnd, $iColor, $iWidth, $iHeight)
    Local $iI, $iSize, $tBits, $tBMI, $hDC, $hbmp, $iRow, $iW = 0, $iH = 0, $imageData

    $iSize = $iWidth * $iHeight
    $tBits = DllStructCreate("byte[" & $iSize * 3 & "]")

    $file = FileOpen("dracula.bin", 16)
    $imageData = StringTrimLeft(FileRead($file), 4); If 2 cape blue; If 4 cape red; If 6 cape green.
    FileClose($file)
    DllStructSetData($tBits, 1, StringStripWS("0x" & $imageData, 8))

    $tBMI = DllStructCreate($tagBITMAPINFO)
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 24)
    DllStructSetData($tBMI, "Width", $iWidth)
    DllStructSetData($tBMI, "Height", $iHeight)
    $hDC = _WinAPI_GetDC($hWnd)
    $hbmp = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight)
    _WinAPI_SetDIBits(0, $hbmp, 0, $iHeight, DllStructGetPtr($tBits), DllStructGetPtr($tBMI))
    _WinAPI_ReleaseDC($hWnd, $hDC)
    Return $hbmp
EndFunc ;==>WinAPI_CreateSolidBitmap

Share this post


Link to post
Share on other sites

thank you for helps me :)

Share this post


Link to post
Share on other sites

help me I have more problems

1

BMP not working with width 94 height 112 and other but to open in the paint work

2

Loop to convert very slow

Help me again please

this file have my script and Dracula X file

Tile Viewer By Lee Rekka.7z

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0