Myicq Posted February 3, 2014 Share Posted February 3, 2014 (edited) I have an (binary B/W) image that I need to convert to a more compact format. The principle is as follows: Image is always an integer of 32 pixel both X and Y. Other sizes will be padded. That part is simple. Only 2 colors, always BMP source What I would like to do is to read the image pixel data from upper left to lower right, each time 8 pixel. The pixel data will be bits in each byte, so that the bottom pixel is highest bit value. Example, for the lower right corner: ........o ........o ........o ........o ........o ........o ........X ........X In the example, there is 2 pixel black of 8. The white ones symbolized by "o". This means that the reading would be from start 11000000 (binary) ==> 0xC0 in final file. My thoughts so far: I could probably read each pixel value and add bits. But I fear it would be a slow process. Another strategy I could think of is to convert to pbm P1 format, and make an array of 0 and 1. Thereby simply getting binary strings. If anyone have ideas, I would be more than happy to receive them. Edited February 3, 2014 by Myicq I am just a hobby programmer, and nothing great to publish right now. Link to comment Share on other sites More sharing options...
TheBytemaster Posted February 3, 2014 Share Posted February 3, 2014 (edited) I could probably read each pixel value and add bits. But I fear it would be a slow process. Well, I'm no expert, but it looks like using >this might help you out with any slowness. Particularly this bit; - For even more performance, you can capture the content of a screen memory (SnapShot, takes about the same time as or PixelSearch PixelGetColor) then do all the research you want in this snapshots (very fast functions : nearly 1000 times as fast as the native PixelGetColor). Edited February 3, 2014 by TheBytemaster Link to comment Share on other sites More sharing options...
Myicq Posted February 4, 2014 Author Share Posted February 4, 2014 Well, I'm no expert, but it looks like using >this might help you out with any slowness. Particularly this bit; Isn't this for working with images from screen ? I don't want to take images from screen, or even display them. I have some files on a drive, made with a graphis software like PhotoShop. But I will look over the resource anyway. Thanks I am just a hobby programmer, and nothing great to publish right now. Link to comment Share on other sites More sharing options...
Myicq Posted February 4, 2014 Author Share Posted February 4, 2014 (edited) I have made a test where I read each pixel, but it's painfully slow. ; Initialize GDI+ library _GDIPlus_Startup() ; Load screen capture bitmap from file $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\template.bmp") ; get size $iH = _GDIPlus_ImageGetHeight($hImage) $iW = _GDIPlus_ImageGetWidth($hImage) MemoWrite("Height of image : " & $iH ) MemoWrite("Width: " & $iW ) ; not sure how to get from hImage to hBitmap.. so do this instead. ; takes around .22 msec to create from file. $hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\template.bmp") ; this is the slow part. $t = TimerInit() for $myCol = 0 to $iW-1 for $myRow = 0 to $iH -1 $pixcol = _GDIPlus_BitmapGetPixel($hBitmap, $myCol, $myRow) Next Next memowrite ("Width = " & $iw & " x Height = " & $iH & " took " & TimerDiff($t) & " msec") A picture of 32x32 pixel takes 14 msec. This is ok. But an image sized 1152x3680 takes over 60 seconds. The original program I would like to mimic uses scanlines. But I don't know how to work with these. Edit: attached template with sample image 1152 x 3680 template.zip Edited February 4, 2014 by Myicq I am just a hobby programmer, and nothing great to publish right now. Link to comment Share on other sites More sharing options...
Myicq Posted February 4, 2014 Author Share Posted February 4, 2014 I have something what works, a modified example from help file. But is this the fastest way to get pixel values ? My template from before is now read in around 11-13 seconds, compared to 60 seconds with getPixel(x,y) expandcollapse popup #include <Constants.au3> #include <GUIConstantsEx.au3> #include <GDIPlus.au3> Example() Func Example() Local $sFile = @ScriptDir & "\template.bmp" _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile($sFile) ;create an image object based on a file Local $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) ;get width and height of the image ; what is difference between bitmap and image ? Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile) Local $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local $iScan0 = DllStructGetData($tBitmapData, "Scan0") ;get scan0 (pixel data) from locked bitmap ; the struct must match the format of pixel data... Local $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iPixel, $iRowOffset Local $out = "" $t = TimerInit() ; this should be 4 x (w * H) because we use int[ ] = 32 bit. ConsoleWrite("Struct size " & DllStructGetSize($tPixel) & @LF) ; ============================================================================ ; Read vertically... ; go over each column For $myColumn = 1 To $iH ; then for each row For $myRow = 1 To $iW ; index starts at 1 ; pixel at col 1, row 2 is at 1 + iW $pixelIndex = ($myRow - 1) * $iW + $myColumn ;~ ConsoleWrite("col =" & $myColumn & ", row = " & $myrow & " : " & $pixelIndex & @LF) ; USE: DllStructGetData ( Struct, Element [, index = Default] $iPixel = DllStructGetData($tPixel, 1, $pixelIndex) ;get pixel color $out &=hex($iPixel)& @CRLF Next Next ConsoleWrite("Reading vertically ==> " & TimerDiff($t) & @LF) ;~ $out2 = "" ;~ For $iY = 0 To $iH - 1 ;~ $iRowOffset = $iY * $iW + 1 ;~ For $iX = 0 To $iW - 1 ;get each pixel in each line and row ;~ ConsoleWrite("Rowoffset : " & $iRowOffset & " iY: " & $iY & " iX" & $iX & " i: " & $iRowOffset + $iX & @LF) ;~ $iPixel = DllStructGetData($tPixel, 1, $iRowOffset + $iX) ;get pixel color ;~ $out2 &= $iPixel & @CRLF ;~ Next ;~ Next ;~ ConsoleWrite("Reading horizontally ==> " & TimerDiff($t) & @LF) _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData) ;unlocks a portion of a bitmap that was locked by _GDIPlus_BitmapLockBits FileDelete(@ScriptDir & "\pixels.txt") FileWrite(@ScriptDir & "\pixels.txt", $out) ;~ FileDelete(@ScriptDir & "\pixels2.txt") ;~ FileWrite(@ScriptDir & "\pixels2.txt", $out2) ;cleanup resources _GDIPlus_ImageDispose($hImage) ;~ _GDIPlus_GraphicsDispose($hContext) _GDIPlus_BitmapDispose($hBitmap) ;~ _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() ;~ GUIDelete($hGUI) EndFunc ;==>Example I am just a hobby programmer, and nothing great to publish right now. Link to comment Share on other sites More sharing options...
TheBytemaster Posted February 4, 2014 Share Posted February 4, 2014 Isn't this for working with images from screen ? I don't want to take images from screen, or even display them. I have some files on a drive, made with a graphis software like PhotoShop. But I will look over the resource anyway. Thanks Er. Derp, I misread what you had said in the OP. My bad. I was hoping that I would find a way to load bitmaps into memory for use with that library, but so far I can't see anything like that. I'm actually working on a script that will deal with a very complicated and time-sensitive array of screenshots over time, processing a bit from each screen in memory and combining them into one image, so I'll likely be looking around in that wrapper quite a bit. I'll let you know if I come across a solution to your problem. 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