Jump to content

DllStructGetData for a large amount of data


Recommended Posts

Hi guys,

I'm using Bitmap Library that use a DllStruct to store bitmap pixels informations. This library use DllStructGetData() to read the color of a pixel and DllStructSetData() to write a color to a pixel. I want to create a function to clone a bitmap area and this process is very slow if I use every time DllStructGetData() to read the pixel color from original bitmap. Is possible to extend DllStructGetData(),for example to use this function to get the pixel colors from a bitmap row?

When the words fail... music speaks.

Link to comment
Share on other sites

 I want to create a function to clone a bitmap area

  _WinAPI_BitBlt() is very fast. 

Example:

#include <WinAPI.au3>
#include <WindowsConstants.au3>

$hgui = GUICreate("Example for _WinApi_bitblt()")
$hdc_gui = _WinAPI_GetDC($hgui) ;device context of the window
GUISetState(@SW_SHOW, $hgui)

$hDC_Screen = _WinAPI_GetDC(0) ;DC of the whole screen

Do
    $x = MouseGetPos(0) ;you have to move the mouse around^^
    $y = MouseGetPos(1)
    For $height = 0 To 3 ;16 parts to blit
        For $width = 0 To 3
            _WinAPI_BitBlt($hdc_gui, 20 + $width * 60, 20 + $height * 60, 50, 50, $hDC_Screen, $x + $width * 50, $y + $height * 50, $SRCCOPY)
        Next
    Next

Until GUIGetMsg() = -3
And if you ask, "Where the f*** is the Bitmap?" ...here we are..

#include <WinAPI.au3>
#include <WindowsConstants.au3>

$hgui = GUICreate("Example for _WinApi_bitblt()",-1,-1,1,1) ;gui is only to show the bitmaps
$hdc_gui = _WinAPI_GetDC($hgui) ;device context of the window
GUISetState(@SW_SHOW, $hgui)


Global $ptr_Bitmap, $hbmp_bitmap ;$ptr is the pointer to the bitmapdata, $hbmp is the handle so you could use it with GDI+
Local $iwidth = 200, $iheight = 200 ;size of Bitmap

$hdc_Bitmap = _CreateNewBmp32($iwidth, $iheight, $ptr_Bitmap, $hbmp_bitmap) ; creates an empty Bitmap with several possibilities to act with
;_CreateNewBmp32() returns the DC, the pointer to the Bitmapdata(Pixels) and the Handle to work with GDI+
;you can fill it with everything you like
;you could fill it with some stripes of colour, using the pointer
$struct_Bitmap = DllStructCreate("dword[" & $iwidth * $iheight & "]", $ptr_Bitmap) ;creates a struct at the position of the empty bitmap
For $h = 0 To 199 ;all stripes
    $col = Random(1, 0x7FFFFFFF, 1) ;random colour
    For $w = 1 To 200 ;from left to right
        DllStructSetData($struct_Bitmap, 1, $col, $h * $iwidth + $w) ;set colour pixel in Bitmap
    Next
Next
;show bitmap
_WinAPI_BitBlt($hdc_gui, 20, 20, $iwidth, $iheight, $hdc_Bitmap, 0, 0, $SRCCOPY) ;bitmap is too big to search? lets split it...

;create a small bitmap, and copy a part of the big one into the small one
Global $ptr_Bitmap_small, $hbmp_bitmap_small ;$ptr is the pointer to the bitmapdata, $hbmp is the handle so you could use it with GDI+
Local $iwidth_small = 20, $iheight_small = 20 ;size of Bitmap
$hdc_Bitmap_small = _CreateNewBmp32($iwidth_small, $iheight_small, $ptr_Bitmap_small, $hbmp_bitmap_small) ; creates an empty Bitmap with several possibilities to act with

_WinAPI_BitBlt($hdc_Bitmap_small, 0, 0, $iwidth_small, $iheight_small, $hdc_Bitmap, 50, 70, $SRCCOPY) ;copy a part from bitmap to the small bitmap
_WinAPI_BitBlt($hdc_gui, 20, 250, $iwidth_small, $iheight_small, $hdc_Bitmap_small, 0, 0, $SRCCOPY) ;show small bitmap in GUI

;Change something into the small bitmap
$struct_Bitmap_small = DllStructCreate("dword[" & $iwidth_small * $iheight_small & "]", $ptr_Bitmap_small) ;creates a struct at the position of the small bitmap
For $i = 1 To $iwidth_small-2 ;3 pixel thick black line from left top to right bottom
    DllStructSetData($struct_Bitmap_small, 1, 0x00, $i + $i * $iwidth_small) ;set pixel
    DllStructSetData($struct_Bitmap_small, 1, 0x00, $i + $i * $iwidth_small + 1) ;set pixel
    DllStructSetData($struct_Bitmap_small, 1, 0x00, $i + $i * $iwidth_small + 2) ;set pixel
Next

_WinAPI_BitBlt($hdc_gui, 20, 250, $iwidth_small, $iheight_small, $hdc_Bitmap_small, 0, 0, $SRCCOPY) ;show small bitmap into GUI


msgbox(0,"","now we copy the whole line #22 into a string and copy this string into the bitmap 20 times (from line #77 to line #97)")
;to get a row of Pixels from the "big" Bitmap, you can "overwrite" the struct with an other struct
;to get the whole line number 22 into a string:
$Struct_line_bytes = DllStructCreate("byte[" & $iwidth * 4 & "]", $ptr_Bitmap + 21 * $iwidth * 4) ; create struct of bytes at beginning of line 22 with lenght=width of Bitmap  1 pixel= 4 byte
$line = DllStructGetData($Struct_line_bytes, 1) ;get the line, the whole data
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $line = ' & $line & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$String = BinaryToString($line) ;now it is possible to search something with the stringfunctions in the whole line
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $String = ' & $String & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
;bitmap32 = AABBGGRR AA=alpha BB=blue GG=green RR =red

;or write the $line into the bitmap from  line 77 to 97
;because the $struct_Bitmap is an array of dwords, we first have to create an array of bytes at the position of the array of dwords
$t=timerinit()
For $i = 77 To 97   ;fill whole line with one instruction
    $Struct_Bitmap_bytes = DllStructCreate("byte[" & $iwidth * 4 & "]", $ptr_Bitmap+$i*$iwidth*4) ; create struct of bytes from beginning of the bitmap to the end
    DllStructSetData($Struct_Bitmap_bytes, 1, $line)  ;copy every byte from $line into the bitmap
Next
$m=timerdiff($t)
_WinAPI_BitBlt($hdc_gui, 20, 20, $iwidth, $iheight, $hdc_Bitmap, 0, 0, $SRCCOPY)  ;show bitmap
msgbox(0,"",stringformat("Copy done in %.2f Milliseconds",$m))
;loop
Do
    ;show the bimaps after resizing or moving the GUI outside the screen
    _WinAPI_BitBlt($hdc_gui, 20, 20, $iwidth, $iheight, $hdc_Bitmap, 0, 0, $SRCCOPY) ; comment, if you dont resize or move the window
    _WinAPI_BitBlt($hdc_gui, 20, 250, $iwidth_small, $iheight_small, $hdc_Bitmap_small, 0, 0, $SRCCOPY) ; comment, if you dont resize or move the window
Until GUIGetMsg() = -3

_DeleteBitmap32($hdc_Bitmap, $ptr_Bitmap, $hbmp_bitmap)
_DeleteBitmap32($hdc_Bitmap_small, $ptr_Bitmap_small, $hbmp_bitmap_small)
Exit



Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
    Local $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI, "Width", $iwidth)
    DllStructSetData($tBMI, "Height", -$iheight) ;minus =standard = bottomup
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
    Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 1, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    ;_arraydisplay($adib)
    _WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
    Return $hcdc ;DC der Bitmap zurückgeben
EndFunc   ;==>_CreateNewBmp32

Func _DeleteBitmap32($DC, $ptr, $hbmp)
    _WinAPI_DeleteDC($DC)
    _WinAPI_DeleteObject($hbmp)
    $ptr = 0
EndFunc   ;==>_DeleteBitmap32

i know that blitting is not matching to the "spirit" in the "rooted in the soil"-BMP_Librarary, but sometimes things can happen...... 

ah, your question about the "fast" copy of a row....did you see how i "overwrite" the struct with an other struct to get a row of pixels?

Link to comment
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
 Share

  • Recently Browsing   0 members

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