AttilaP Posted February 16 Share Posted February 16 I have the below code which generates a grid an puts a circle into each with random sizes (just for demonstrational purposes). It does the job right (more or less), but performance is not optimal. Added some monitoring to print out the elapsed time and the peak memory. Here is the output from my laptop: Quote Runtime: 0 seconds.Memory peaks 20 -> 22 MB Grid 10 - image created C:\Users\Attila\Downloads\grid10.png Runtime: 2 seconds.Memory peaks 22 -> 69 MB Grid 100 - Image created C:\Users\Attila\Downloads\grid100.png Runtime: 10 seconds.Memory peaks 69 -> 362 MB Grid 250 - Image created C:\Users\Attila\Downloads\grid250.png Runtime: 23 seconds.Memory peaks 362 -> 1310 MB Grid 450 - Image created C:\Users\Attila\Downloads\grid450.png Runtime: 45 seconds.Memory peaks 1310 -> 2480 MB Grid 500 - Image created C:\Users\Attila\Downloads\grid500.png Runtime: 97 seconds.Memory peaks 2480 -> 2480 MB Grid 500 - Image created C:\Users\Attila\Downloads\grid1000.png As you can see, memory climbs up quite quickly, generating a 500x500 grid consumes 2.4GB RAM which is not optimal, not to mention it took 45 seconds. Grid with size 1000 x 1000 was not even created, I think it is the memory limitation per application. Question is simple: how could I make this more efficient? Already checked variable scopes, disposing not used object, but that's all what I could do. Thank you in advance! expandcollapse popup#include <GDIPlus.au3> Global Const $CELL_SIZE = 30 Global Const $GRID_PADDING = 5 Global Const $MIN_CIRCLE_RADIUS = 5 Global Const $MAX_CIRCLE_RADIUS = 10 Global $START = TimerInit() Func DrawCircles($hGraphics,$GRID_SIZE) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF5050) For $i = 0 To $GRID_SIZE - 1 For $j = 0 To $GRID_SIZE - 1 Local $iRadius = Random($MIN_CIRCLE_RADIUS, $MAX_CIRCLE_RADIUS, 1) Local $iCenterX = $GRID_PADDING * 1.5 + $j * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 Local $iCenterY = $GRID_PADDING * 1.5 + $i * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 _GDIPlus_GraphicsFillEllipse($hGraphics, $iCenterX - $iRadius, $iCenterY - $iRadius, $iRadius * 2, $iRadius * 2, $hBrush) Next Next _GDIPlus_BrushDispose($hBrush) EndFunc ;==>DrawCircles Func DrawGrid($hGraphics,$GRID_SIZE) Local $hPen = _GDIPlus_PenCreate(0xFF000000, 1) For $i = 0 To $GRID_SIZE Local $iX = $i * ($CELL_SIZE + $GRID_PADDING) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $GRID_PADDING + $iX, $hPen) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING + $iX, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $hPen) Next _GDIPlus_PenDispose($hPen) EndFunc ;==>DrawGrid Func DrawGridToBitmap($GRID_SIZE) $aWS = ProcessGetStats() Local $pb = Round($aWS[1]/1024/1024) _GDIPlus_Startup() Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING + 1, $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING + 1) Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxt, 0xFFFFFFFF) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) DrawGrid($hGraphics,$GRID_SIZE) DrawCircles($hGraphics,$GRID_SIZE) Local $sFilePath = @ScriptDir & "\grid" & $GRID_SIZE & ".png" _GDIPlus_ImageSaveToFile($hBitmap, $sFilePath) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() $aWS = ProcessGetStats() Local $pa = Round($aWS[1]/1024/1024) ConsoleWrite("Runtime: " & Round(TimerDiff($START)/1000) & " seconds.Memory peaks " & $pb & " -> " & $pa & " MB" & @LF) $START = TimerInit() Return $sFilePath EndFunc ;==>DrawGridToBitmap ConsoleWrite("Grid 10 - image created " & DrawGridToBitmap(10) & @LF) ConsoleWrite("Grid 100 - Image created " & DrawGridToBitmap(100) & @LF) ConsoleWrite("Grid 250 - Image created " & DrawGridToBitmap(250) & @LF) ConsoleWrite("Grid 450 - Image created " & DrawGridToBitmap(450) & @LF) ConsoleWrite("Grid 500 - Image created " & DrawGridToBitmap(500) & @LF) ConsoleWrite("Grid 1000 - Image created " & DrawGridToBitmap(1000) & @LF) Link to comment Share on other sites More sharing options...
Nine Posted February 16 Share Posted February 16 (edited) Simple way (untested though) is to create a 100x100 grid and copy/merge it 10x10 times into a 1000x1000 grid. Out of curiosity, what is this used for ? Edited February 16 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
AttilaP Posted February 16 Author Share Posted February 16 I could even generate then one-by-one, draw the rectangle, draw the circle and then append it to the previous one. But the lack of knowledge prevents me to do this - I have no clue how to merge/attach to another image. This is used as a visualization for a CNC program. It generates a CNC (G) code from an image and also generates this image as a preview to show how the result will look like (circles - holes will be cut on the raw material on the given coordinates). SOLVE-SMART 1 Link to comment Share on other sites More sharing options...
Nine Posted February 16 Share Posted February 16 (edited) Look at _GDIPlus_GraphicsDrawImageRect example, it shows how to copy/merge 2 images. ps. no clue what CNC(G) code is Edited February 16 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
UEZ Posted February 16 Share Posted February 16 (edited) I would create a minimal grid, let say 10x10 as an image, convert it to a texture and fill the entire rectangle with the texture. I assume it would be faster then your method, assuming the pattern repeats according to the minimum grid. Look for _GDIPlus_TextureCreate() in the helpfile. Edited February 16 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Andreik Posted February 16 Share Posted February 16 (edited) expandcollapse popup#include <GDIPlus.au3> Global Const $iCellSize = 30 Global Const $iMaxRadius = 10 Global Const $iMinRadius = 5 ; Run some tests DrawGrid(10) DrawGrid(100) DrawGrid(250) DrawGrid(500) DrawGrid(1000) Func DrawGrid($iSize, $iCellBackgroundColor = 0xFFFFFFFF, $iCellBorderColor = 0xFF000000, $iCellBorderSize = 1, $iCircleColor = 0xFF800000) Local $iStartPeak = Round((ProcessGetStats())[1] / 1024 / 1024) Local $iTimer = TimerInit() Local $iRow, $iCol, $iDiameter, $iRadius, $iCalc Local $iCenter = Int($iCellSize / 2) Local $iImgSize = $iSize * $iCellSize _GDIPlus_Startup() Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iImgSize, $iImgSize) If @error Then ConsoleWrite('Grid size: ' & $iSize & ' - Error: _GDIPlus_BitmapCreateFromScan0' & @CRLF) _GDIPlus_Shutdown() Return EndIf Local $hCell = _GDIPlus_BitmapCreateFromScan0($iCellSize, $iCellSize) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hCell) Local $hPen = _GDIPlus_PenCreate($iCellBorderColor, $iCellBorderSize) _GDIPlus_GraphicsClear($hGraphics, $iCellBackgroundColor) _GDIPlus_GraphicsDrawRect($hGraphics, 0, 0, $iCellSize - 1, $iCellSize - 1, $hPen) _GDIPlus_PenDispose($hPen) _GDIPlus_GraphicsDispose($hGraphics) Local $hTexture = _GDIPlus_TextureCreate($hCell) $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsFillRect($hGraphics, 0, 0, $iImgSize, $iImgSize, $hTexture) _GDIPlus_BrushDispose($hTexture) $hTexture = _GDIPlus_BrushCreateSolid($iCircleColor) ; Draw circles For $Index = 0 To $iSize * $iSize - 1 $iRow = Int($Index / $iSize) $iCol = Mod($Index, $iSize) $iRadius = Random($iMinRadius, $iMaxRadius, 1) $iDiameter = $iRadius * 2 $iCalc = $iCenter - $iRadius _GDIPlus_GraphicsFillEllipse($hGraphics, $iCol * $iCellSize + $iCalc, $iRow * $iCellSize + $iCalc, $iDiameter, $iDiameter, $hTexture) Next _GDIPlus_BrushDispose($hTexture) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hCell) _GDIPlus_ImageSaveToFile($hBitmap, 'grid_' & $iSize & '.png') _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() Local $iDiff = TimerDiff($iTimer) Local $iEndPeak = Round((ProcessGetStats())[1] / 1024 / 1024) ConsoleWrite('Grid size: ' & $iSize & ' generated in ' & ($iDiff > 1000 ? Int($iDiff / 1000) & ' s' : Int($iDiff) & ' ms') & '. Memory peaks ' & $iStartPeak & " -> " & $iEndPeak & ' MB.' & @CRLF) EndFunc Results: Grid 10: 19.5998 ms Grid 100: 487.9959 ms Grid 250: 3 s Grid 500: 14 s Grid 1000: 43 s Last image it's not created probably due some limitations (a grid of 1000x1000 with 30 as cell size it's an image of 30000x30000 pixels) but I manage to produce an image with a cell size of 20 px. For grid I basically fill the entire image with a texture of a single cell (see @UEZ post) and for circles I use a single loop and some math (nested loops in AutoIt are really slow). Edited February 16 by Andreik Better statistics display. AttilaP 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted February 16 Moderators Share Posted February 16 15 minutes ago, Andreik said: Results: Grid 10: 19.5998 ms Grid 100: 487.9959 ms Grid 250: 3 s Grid 500: 14 s Grid 1000: 43 s I'm a little jealous, your computer speed is like 10% - 25% - 40% faster than mine depending on the loop stack! These numbers don't look like much but to me it's a huge deal 😟 Grid 10: 20.7552 ms Grid 100: 833.3427 ms Grid 250: 4 s Grid 500: 18 s Grid 1000: 46 s I need an upgrade 😔 Andreik 1 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Andreik Posted February 16 Share Posted February 16 (edited) @SmOke_N My computer it's pretty old now. It's a Intel Core i7-8750H CPU @ 2.20GHz with 16 GB RAM. I got it like 5 years ago but it's still running good so I don't intend to get a new one soon. Edited February 16 by Andreik When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Werty Posted February 16 Share Posted February 16 Why am I getting this error... Quote Grid size: 10 generated in 14 ms. Memory peaks 17 -> 19 MB. Grid size: 100 generated in 331 ms. Memory peaks 19 -> 53 MB. Grid size: 250 generated in 2 s. Memory peaks 53 -> 234 MB. Grid size: 500 generated in 8 s. Memory peaks 234 -> 877 MB. Grid size: 1000 - Error: _GDIPlus_BitmapCreateFromScan0 I use bitmapcreatefromscan0 in other scripts just fine. Some guy's script + some other guy's script = my script! Link to comment Share on other sites More sharing options...
Andreik Posted February 17 Share Posted February 17 Because the function cannot create a bitmap of 30000x30000 pixels. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Werty Posted February 17 Share Posted February 17 then how did you and smoke get that 1000 score? Some guy's script + some other guy's script = my script! Link to comment Share on other sites More sharing options...
Andreik Posted February 17 Share Posted February 17 There was no error checking and the code continue to run. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Werty Posted February 17 Share Posted February 17 lol, ok, removed it and got a score also 😛 Grid size: 10 generated in 14 ms. Grid size: 100 generated in 336 ms. Grid size: 250 generated in 2 s. Grid size: 500 generated in 8 s. Grid size: 1000 generated in 19 s. Some guy's script + some other guy's script = my script! Link to comment Share on other sites More sharing options...
Nine Posted February 17 Share Posted February 17 (edited) Merge/copy on my PC gets 2.78 sec for 500x500 on 30 px...including save On creation only < 1 sec. expandcollapse popup#include <GDIPlus.au3> Local $hTimer = TimerInit() Global Const $CELL_SIZE = 30 Global Const $MIN_CIRCLE_RADIUS = 5 Global Const $MAX_CIRCLE_RADIUS = 10 _GDIPlus_Startup() Local $iMerge = 5 Local $hBitmap = DrawGridToBitmap(100) Local $iDim = _GDIPlus_ImageGetWidth($hBitmap) Local $hImage = _GDIPlus_BitmapCreateFromScan0(($iDim - 1) * $iMerge + 1, ($iDim - 1) * $iMerge + 1) If @error Then Exit ConsoleWrite(@error & @CRLF) Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) For $i = 0 To $iMerge - 1 For $j = 0 To $iMerge - 1 _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, $i * ($iDim - ($i ? 1 : 0)), $j * ($iDim - ($j ? 1 : 0)), $iDim, $iDim) Next Next ConsoleWrite("Creation = " & TimerDiff($hTimer) & @CRLF) _GDIPlus_ImageSaveToFile($hImage, "Test.jpg") _GDIPlus_ImageDispose($hBitmap) _GDIPlus_ImageDispose($hImage) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() ConsoleWrite("Final = " & TimerDiff($hTimer) & @CRLF) Func DrawCircles($hGraphics, $GRID_SIZE) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF5050) For $i = 0 To $GRID_SIZE - 1 For $j = 0 To $GRID_SIZE - 1 Local $iRadius = Random($MIN_CIRCLE_RADIUS, $MAX_CIRCLE_RADIUS, 1) Local $iCenterX = $j * $CELL_SIZE + $CELL_SIZE / 2 Local $iCenterY = $i * $CELL_SIZE + $CELL_SIZE / 2 _GDIPlus_GraphicsFillEllipse($hGraphics, $iCenterX - $iRadius, $iCenterY - $iRadius, $iRadius * 2, $iRadius * 2, $hBrush) Next Next _GDIPlus_BrushDispose($hBrush) EndFunc ;==>DrawCircles Func DrawGrid($hGraphics, $GRID_SIZE) Local $hPen = _GDIPlus_PenCreate(0xFF000000, 1) For $i = 0 To $GRID_SIZE _GDIPlus_GraphicsDrawLine($hGraphics, 0, $i * $CELL_SIZE, $GRID_SIZE * $CELL_SIZE, $i * $CELL_SIZE, $hPen) _GDIPlus_GraphicsDrawLine($hGraphics, $i * $CELL_SIZE, 0, $i * $CELL_SIZE, $GRID_SIZE * $CELL_SIZE, $hPen) Next _GDIPlus_PenDispose($hPen) EndFunc ;==>DrawGrid Func DrawGridToBitmap($GRID_SIZE) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($GRID_SIZE * $CELL_SIZE + 1, $GRID_SIZE * $CELL_SIZE + 1) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF) DrawGrid($hGraphics, $GRID_SIZE) DrawCircles($hGraphics, $GRID_SIZE) _GDIPlus_GraphicsDispose($hGraphics) Return $hBitmap EndFunc ;==>DrawGridToBitmap Edited February 17 by Nine solve issue of size AttilaP 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted February 17 Moderators Share Posted February 17 2 hours ago, Andreik said: @SmOke_N My computer it's pretty old now. It's a Intel Core i7-8750H CPU @ 2.20GHz with 16 GB RAM. I got it like 5 years ago but it's still running good so I don't intend to get a new one soon. Mine i7-7500U CPU @ 2.70GHz but only 8gb ram, so that makes sense to me, and my computer not optimized because my dell doesn't like my charger so I have to cheat with throttlestop app (to bypass dell bios lock (stingy bastages)) to even get it to run like yours around 2.3ghz. And no, didn't error check, I read what you wrote before running it and didn't care lol. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Andreik Posted February 17 Share Posted February 17 38 minutes ago, Nine said: Merge/copy on my PC gets 2.78 sec for 500x500 on 30 px...including save On creation only < 1 sec. expandcollapse popup#include <GDIPlus.au3> Global Const $CELL_SIZE = 30 Global Const $GRID_PADDING = 0 Global Const $MIN_CIRCLE_RADIUS = 5 Global Const $MAX_CIRCLE_RADIUS = 10 _GDIPlus_Startup() Local $hTimer = TimerInit() Local $merge = 5 Local $hBitmap = DrawGridToBitmap(100) Local $iDim = _GDIPlus_ImageGetWidth($hBitmap) Local $hImage = _GDIPlus_BitmapCreateFromScan0($iDim * $merge, $iDim * $merge) If @error Then Exit ConsoleWrite(@error & @CRLF) Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) For $i = 0 To $merge - 1 For $j = 0 To $merge - 1 _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, $i * $iDim - ($i ? 2 : 0), $j * $iDim - ($j ? 2 : 0), $iDim, $iDim) Next Next ConsoleWrite("Creation = " & TimerDiff($hTimer) & @CRLF) _GDIPlus_ImageSaveToFile($hImage, "Test.jpg") _GDIPlus_ImageDispose($hBitmap) _GDIPlus_ImageDispose($hImage) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() ConsoleWrite("Final = " & TimerDiff($hTimer) & @CRLF) Func DrawCircles($hGraphics, $GRID_SIZE) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF5050) For $i = 0 To $GRID_SIZE - 1 For $j = 0 To $GRID_SIZE - 1 Local $iRadius = Random($MIN_CIRCLE_RADIUS, $MAX_CIRCLE_RADIUS, 1) Local $iCenterX = $GRID_PADDING * 1.5 + $j * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 Local $iCenterY = $GRID_PADDING * 1.5 + $i * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 _GDIPlus_GraphicsFillEllipse($hGraphics, $iCenterX - $iRadius, $iCenterY - $iRadius, $iRadius * 2, $iRadius * 2, $hBrush) Next Next _GDIPlus_BrushDispose($hBrush) EndFunc ;==>DrawCircles Func DrawGrid($hGraphics, $GRID_SIZE) Local $hPen = _GDIPlus_PenCreate(0xFF000000, 1) For $i = 0 To $GRID_SIZE Local $iX = $i * ($CELL_SIZE + $GRID_PADDING) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $GRID_PADDING + $iX, $hPen) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING + $iX, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $hPen) Next _GDIPlus_PenDispose($hPen) EndFunc ;==>DrawGrid Func DrawGridToBitmap($GRID_SIZE) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2 * $GRID_PADDING + 1, $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2 * $GRID_PADDING + 1) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF) DrawGrid($hGraphics, $GRID_SIZE) DrawCircles($hGraphics, $GRID_SIZE) _GDIPlus_GraphicsDispose($hGraphics) Return $hBitmap EndFunc ;==>DrawGridToBitmap I assume he will use some real data for/instead of these circles and it's not interested to repeat a pattern. Also you have some minor issue with the output file, it's 15005x15005 px. AttilaP 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Nine Posted February 17 Share Posted February 17 Lets OP decide what he/she prefers. Importance, is that OP has different options. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
junkew Posted February 17 Share Posted February 17 Maybe generate an svg file which just would be plain text and very fast generated. FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
UEZ Posted February 17 Share Posted February 17 (edited) I meant something like this here (proof of concept): expandcollapse popup#include <GDIPlus.au3> Global Const $CELL_SIZE = 30 Global Const $GRID_PADDING = 5 Global Const $MIN_CIRCLE_RADIUS = 5 Global Const $MAX_CIRCLE_RADIUS = 10 Global $START = TimerInit() Func DrawCircles($hGraphics,$GRID_SIZE) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF5050) For $i = 0 To $GRID_SIZE - 1 For $j = 0 To $GRID_SIZE - 1 Local $iRadius = Random($MIN_CIRCLE_RADIUS, $MAX_CIRCLE_RADIUS, 1) Local $iCenterX = $GRID_PADDING * 1.5 + $j * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 Local $iCenterY = $GRID_PADDING * 1.5 + $i * ($CELL_SIZE + $GRID_PADDING) + $CELL_SIZE / 2 _GDIPlus_GraphicsFillEllipse($hGraphics, $iCenterX - $iRadius, $iCenterY - $iRadius, $iRadius * 2, $iRadius * 2, $hBrush) Next Next _GDIPlus_BrushDispose($hBrush) EndFunc ;==>DrawCircles Func DrawGrid($hGraphics,$GRID_SIZE) Local $hPen = _GDIPlus_PenCreate(0xFF000000, 1) For $i = 0 To $GRID_SIZE Local $iX = $i * ($CELL_SIZE + $GRID_PADDING) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $GRID_PADDING + $iX, $hPen) _GDIPlus_GraphicsDrawLine($hGraphics, $GRID_PADDING + $iX, $GRID_PADDING, $GRID_PADDING + $iX, $GRID_PADDING + $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING), $hPen) Next _GDIPlus_PenDispose($hPen) EndFunc ;==>DrawGrid Func DrawGridToBitmap($GRID_SIZE) $aWS = ProcessGetStats() Local $pb = Round($aWS[1]/1024/1024) _GDIPlus_Startup() Local $iW = $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING + 1, $iH = $GRID_SIZE * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING + 1 ;~ ConsoleWrite($iW & " x " & $iH & @CRLF) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsClear($hBmpCtxt, 0xFFFFFFFF) If $GRID_SIZE > 10 Then Local $iW2 = 10 * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING - 1, $iH2 = 10 * ($CELL_SIZE + $GRID_PADDING) + 2*$GRID_PADDING - 1 Local $hBitmap2 = _GDIPlus_BitmapCreateFromScan0($iW2, $iH2), $hBmpCtxt2 = _GDIPlus_ImageGetGraphicsContext($hBitmap2) _GDIPlus_GraphicsClear($hBmpCtxt2, 0xFFFFFFFF) _GDIPlus_GraphicsSetSmoothingMode($hBmpCtxt2, $GDIP_SMOOTHINGMODE_HIGHQUALITY) DrawGrid($hBmpCtxt2,10) DrawCircles($hBmpCtxt2,10) Local $hTexture = _GDIPlus_TextureCreate2($hBitmap2, 5, 5, $iW2 - 9, $iH2 - 9) DllCall($__g_hGDIPDll, "int", "GdipTranslateTextureTransform", "handle", $hTexture, "float", 5, "float", 5, "int", 0) _GDIPlus_GraphicsFillRect($hBmpCtxt, 5, 5, $iW - 11, $iH - 11, $hTexture) _GDIPlus_GraphicsDispose($hBmpCtxt2) _GDIPlus_BitmapDispose($hBitmap2) _GDIPlus_BrushDispose($hTexture) Else DrawGrid($hBmpCtxt,$GRID_SIZE) DrawCircles($hBmpCtxt,$GRID_SIZE) EndIf Local $sFilePath = @ScriptDir & "\grid" & $GRID_SIZE & ".png" _GDIPlus_ImageSaveToFile($hBitmap, $sFilePath) _GDIPlus_GraphicsDispose($hBmpCtxt) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() $aWS = ProcessGetStats() Local $pa = Round($aWS[1]/1024/1024) ConsoleWrite("Runtime: " & Round(TimerDiff($START)/1000) & " seconds.Memory peaks " & $pb & " -> " & $pa & " MB" & @LF) $START = TimerInit() Return $sFilePath EndFunc ;==>DrawGridToBitmap ConsoleWrite("Grid 10 - image created " & DrawGridToBitmap(10) & @LF) ConsoleWrite("Grid 100 - Image created " & DrawGridToBitmap(100) & @LF) ConsoleWrite("Grid 250 - Image created " & DrawGridToBitmap(250) & @LF) ConsoleWrite("Grid 450 - Image created " & DrawGridToBitmap(450) & @LF) ConsoleWrite("Grid 500 - Image created " & DrawGridToBitmap(500) & @LF) ConsoleWrite("Grid 1000 - Image created " & DrawGridToBitmap(1000) & @LF) Edited February 17 by UEZ small update AttilaP and Danyfirex 2 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
AttilaP Posted February 19 Author Share Posted February 19 Thanks everyone for the feedback. Using texture might not be a proper solution, as it does not have a specific pattern, it is always different. I gave a try for each version posted, here are the results from my laptop: Quote @Andreik Grid size: 10 generated in 36 ms. Memory peaks 20 -> 22 MB. Grid size: 100 generated in 909 ms. Memory peaks 22 -> 56 MB. Grid size: 250 generated in 4 s. Memory peaks 56 -> 236 MB. Grid size: 500 generated in 17 s. Memory peaks 236 -> 880 MB. Grid size: 1000 - Error: _GDIPlus_BitmapCreateFromScan0 @Nine Creation = 2855.1627 Final = 7668.4703 Memory peak: 948 @UEZ Runtime: 0 seconds.Memory peaks 20 -> 22 MB Grid 10 - image created C:\Users\Attila\Downloads\grid10.png Runtime: 0 seconds.Memory peaks 22 -> 69 MB Grid 100 - Image created C:\Users\Attila\Downloads\grid100.png Runtime: 2 seconds.Memory peaks 69 -> 315 MB Grid 250 - Image created C:\Users\Attila\Downloads\grid250.png Runtime: 5 seconds.Memory peaks 315 -> 970 MB Grid 450 - Image created C:\Users\Attila\Downloads\grid450.png Runtime: 6 seconds.Memory peaks 970 -> 1192 MB Grid 500 - Image created C:\Users\Attila\Downloads\grid500.png Runtime: 0 seconds.Memory peaks 1192 -> 1192 MB Grid 1000 - Image created C:\Users\Attila\Downloads\grid1000.png My main concern is still the memory usage, each version consumes more than 800Mb memory which is not optimal Is that possible to somehow use the texture, e.g. generate 1 grid for each diameter in the given range, and when generating the complete image just by appending each grid cell next to each other? But without keeping them in memory, dumping that into a file instead. Maybe I should also using a different image type as suggested by @junkew? I have no clue where to start Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now