Jump to content
Sign in to follow this  
Maurice

Output 2D-Array to image

Recommended Posts

Maurice

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
    Next
Next

$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
dantay9

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
Malkey

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
    Next
Next
$matrix[5][5] = 0x000000FF ; Colour format is 0xBBGGRRAA

$begin = TimerInit()

_FileArrayToImage($sFilename, $matrix)

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


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)
    _GDIPlus_Startup()
    $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)
        Next
    Next

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

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

    _GDIPlus_ImageDispose($hImage1)
    _WinAPI_DeleteObject($hBMP)
    _GDIPlus_Shutdown()
    Return
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
AdmiralAlkex

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

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

_SDL_Init($_SDL_INIT_VIDEO)

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?)
    Next
Next
$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])
        Next
    Next

    $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)
    _SDL_FreeSurface($pSurface)
EndFunc

The difference? The file is saved as bmp.

Edited by AdmiralAlkex

Share this post


Link to post
Share on other sites
Maurice

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.