Jump to content
Sign in to follow this  

Output 2D-Array to image

Recommended Posts


Let's say I have the following:

dim $matrix[10][10]

for $y = 0 to 9
    for $x = 0 to 9
        $matrix[$x][$y] = 0xFFFFFFFF

$matrix[5][5] = 0xFF000000

Imagine $matrix as an image. A white background with a black dot in the center.

I want to save this image as jpg, png or whatever.

Is there a good way to do it?

I wrote a program which uses _GDIPlus_GraphicsFillRect to create a lot of 1x1 px squares, but it's really slow and unpractical.

Would be glad for any help.

Share this post

Link to post
Share on other sites

Why not just create an image outside of autoit? What is this program going to be used for? It seems a little pointless to me.

[font="Verdana"] [size="2"]"[/size][/font]Failure is not an option -- it comes packaged with Windows"[font="Verdana"][size="2"] Gecko Web Browser[/size][/font][font="Verdana"][size="2"], [/size][/font][font="Verdana"][size="2"]Yahtzee![/size][/font][font="Verdana"][size="2"], Toolbar Launcher (like RocketDock)[/size][/font][font="Verdana"][size="2"]Internet Blocker, Simple Calculator, Local Weather, Easy GDI+ GUI [/size][/font][font="Verdana"][size="2"]Triangle Solver, TCP File Transfer, [/size][/font][font="Verdana"][size="2"]Valuater's Autoit Wrappers[/size][/font][font="Verdana"][size="3"][size="2"][size="2"]OOP In AutoIt[/size][/size][/size][/font][font="Verdana"][size="2"][size="1"]Using Windows XP SP3, 1GB RAM, AMD Athlon Processor @ 2.1 GHzCheck me out at gadgets.freehostrocket.com[/size][/size][/font]

Share this post

Link to post
Share on other sites

Thanks that helped.

Share this post

Link to post
Share on other sites

Here is one method.

#include <WinAPI.au3>
#include <GDIPlus.au3>
;#include <Array.au3>

Local $sFilename, $begin, $aArr, $time, $iColor, $iW, $iH

$sFilename = @ScriptDir & "\TestWhiteBlackDot.png" ;bmp"
$iW = 10
$iH = 10

Dim $matrix[10][10]

For $y = 0 To 9
    For $x = 0 To 9
        $matrix[$x][$y] = 0xFFFFFFFF ; Colour format is 0xBBGGRRAA
$matrix[5][5] = 0x000000FF ; Colour format is 0xBBGGRRAA

$begin = TimerInit()

_FileArrayToImage($sFilename, $matrix)

ConsoleWrite("Time taken = " & Round(TimerDiff($begin) / 1000, 3) & " secs" & @CRLF)

Func _FileArrayToImage($filename, $aArr)
    Local $iW = UBound($aArr, 1), $iH = UBound($aArr, 2), $sResult = ""
    Local $hBMP, $hImage1, $Reslt, $width, $height, $stride, $format, $Scan0
    Local $sResult, $v_BufferA
    $hBMP = _WinAPI_CreateBitmap($iW, $iH, 1, 32)
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)

    $Reslt = _GDIPlus_BitmapLockBits($hImage1, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB)

    ;Get the returned values of _GDIPlus_BitmapLockBits ()
    $width = DllStructGetData($Reslt, "width")
    $height = DllStructGetData($Reslt, "height")
    $stride = DllStructGetData($Reslt, "stride")
    $format = DllStructGetData($Reslt, "format")
    $Scan0 = DllStructGetData($Reslt, "Scan0")

    $v_BufferA = DllStructCreate("byte[" & $height * $width * 4 & "]", $Scan0)
    ;$AllPixels = DllStructGetData($v_BufferA, 1)

    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            $sResult &= Hex($aArr[$x][$y], 8)

    DllStructSetData($v_BufferA, 1, "0x" & StringStripWS($sResult, 8))

    _GDIPlus_BitmapUnlockBits($hImage1, $Reslt)
    _GDIPlus_ImageSaveToFile($hImage1, $filename)

EndFunc ;==>_FileArrayToImage

Edit: Removed unnecessary DllStructGetData()'s used for debugging.

Added all variable declarations.

Edited by Malkey

Share this post

Link to post
Share on other sites

I managed to hack/build a similar example but with SDL.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#Include "SDL.au3"


Global $sFilename = @DesktopDir & "\TestWhiteBlackDot.bmp"
Local $iTimer

Global $aMatrix[1000][1000]

For $iY = 0 To 999
    For $iX = 0 To 999
        $aMatrix[$iX][$iY] = 0xFFFFFFFF ; Colour format is 0xRRGGBB(AA?)
$aMatrix[5][5] = 0 ; Colour format is 0xRRGGBB(AA?)

$iTimer = TimerInit()

_FileArrayToImage($sFilename, $aMatrix)

ConsoleWrite("Time taken = " & Round(TimerDiff($iTimer) / 1000, 3) & " secs" & @CRLF)
;~ ShellExecute($sFilename)

Func _FileArrayToImage($sFilename, $aMatrix)
    Local $iW = UBound($aMatrix, 1), $iH = UBound($aMatrix, 2), $sResult = ""

    For $iY = 0 To $iH -1
        For $iX = 0 To $iW -1
            $sResult &= Hex($aMatrix[$iX][$iY])

    $pSurface = _SDL_CreateRGBSurface($_SDL_SWSURFACE, $iW, $iH, 32, 0, 0, 0, 0)

    $Struct = DllStructCreate($tagSDL_SURFACE, $pSurface)
    $PtrStruct = DllStructGetData($Struct, "format")
    $Struct2 = DllStructCreate($tagSDL_PixelFormat, $PtrStruct)
    $Bpp = DllStructGetData($Struct2, "BytesPerPixel")
    $Pixels = DllStructGetData($Struct, "pixels")
    $Pitch = DllStructGetData($Struct, "pitch")

    $P = $Pixels + 0 * $Pitch + 0 * $Bpp

    $Struct = DllStructCreate("byte[" & $iW * $iH * $Bpp & "]", $P)
    DllStructSetData($Struct, 1, "0x" & $sResult)

    _SDL_SaveBMP($pSurface, $sFilename)

The difference? The file is saved as bmp.

Edited by AdmiralAlkex

Share this post

Link to post
Share on other sites

Thanks for all the help!!

AdmiralAlkex: Your example became incredibly slow with bigger images (even 100x100).

Malkey: That's perfect! It's really fast and does an excellent job. I can't thank you enough!

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