Jump to content

Recommended Posts

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
Posted

#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.

Posted

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.

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

_____________________________________________________________________________

Posted (edited)

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

Edited by Godless

_____________________________________________________________________________

Posted

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
Posted

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

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...