Jump to content
jvds

Xor and image, problem rebuilding image

Recommended Posts

Posted (edited)
#include <Memory.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
AutoItSetOption("GUIOnEventMode", 1)

;~ $BitCount = 4
$BitCount = 8
;~ $BitCount = 16

$Width = 500
$Height = 500
Local $ptrbmp, $DibHandle, $DibPre_Obj
$BitmapBB1 = _CreateNewDIB_Bitmap($Width, $Height, $BitCount, $ptrbmp, $DibHandle, $DibPre_Obj)
Local $ptrbmp2, $DibHandle2, $DibPre_Obj2
$BitmapBB2 = _CreateNewDIB_Bitmap($Width, $Height, $BitCount, $ptrbmp2, $DibHandle2, $DibPre_Obj2)
Local $ptrbmp3, $DibHandle3, $DibPre_Obj3
$BitmapBB3 = _CreateNewDIB_Bitmap($Width, $Height, $BitCount, $ptrbmp3, $DibHandle3, $DibPre_Obj3)

$Form = GUICreate("GUI", $Width, $Height, -1, -1)
$Pic = GUICtrlCreatePic("", 5, 5, $Width, $Height)
GUICtrlSetResizing($Pic, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
GUISetState(@SW_SHOW)

GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

Local $hWnd = _WinAPI_GetDesktopWindow()
Local $hDDC = _WinAPI_GetDC($hWnd)

$hCtrl = GUICtrlGetHandle($Pic)
$hGUI_DC = _WinAPI_GetDC($hCtrl)
_GDIPlus_Startup()
While 1

    _WinAPI_BitBlt($BitmapBB2, 0, 0, $Width, $Height, $BitmapBB1, 0, 0, $SRCCOPY) ;buffer of olf image to xor from
    _WinAPI_BitBlt($BitmapBB1, 0, 0, $Width, $Height, $hDDC, 0, 0, $SRCCOPY) ;get the mew image
    _WinAPI_BitBlt($BitmapBB2, 0, 0, $Width, $Height, $BitmapBB1, 0, 0, $SRCINVERT);Xor Old and New image

    ;save image to stream or file as png format
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($DibHandle2)
    If @error Then ConsoleWrite('_GDIPlus_BitmapCreateFromHBITMAP Failed')
    $BitmapStream = _GDIPlus_StreamImage2BinaryString($hBitmap, "PNG",100)
    If @error Then ConsoleWrite('_GDIPlus_StreamImage2BinaryString Failed')
    _GDIPlus_BitmapDispose($hBitmap)

    ;#########################################################################################

    ;Load image from stream or file
    Local $hHBITMAP
    $hHBITMAP = _GDIPlus_BitmapCreateFromMemory($BitmapStream, True)
    If @error Then ConsoleWrite('_GDIPlus_BitmapCreateFromMemory Failed')
    Local $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hGUI_DC)
    Local $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBITMAP)

    _WinAPI_BitBlt($BitmapBB3, 0, 0, $Width, $Height, $hDC_backbuffer, 0, 0, $SRCINVERT) ;xor image existing image

    _WinAPI_SelectObject($hDC_backbuffer, $DC_obj)
    _WinAPI_DeleteDC($hDC_backbuffer)
    _WinAPI_DeleteObject($hHBITMAP)

    sleep(100)

;~  _WinAPI_BitBlt($hGUI_DC, 0, 0, $Width, $Height, $BitmapBB2, 0, 0, $SRCCOPY) ;see Xored img before saved to file or stream
;~  _WinAPI_BitBlt($hGUI_DC, 0, 0, $Width, $Height, $BitmapBB1, 0, 0, $SRCCOPY) ;see New image before it is xored and saved
    _WinAPI_BitBlt($hGUI_DC, 0, 0, $Width, $Height, $BitmapBB3, 0, 0, $SRCCOPY) ;image xor chain?

WEnd
Func _Exit()
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>_Exit



Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 80, $bSave = False, $sFilename = @ScriptDir & "\Converted.jpg") ;coded by UEZ 2013 build 2014-01-25; based on the code by Andreik
    $lastfunc = '_GDIPlus_StreamImage2BinaryString'
    Local $sImgCLSID, $tGUID, $tParams, $tData
    Switch $sFormat
        Case "JPG"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
            $tData = DllStructCreate("int Quality")
            DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
            Local $pData = DllStructGetPtr($tData)
            $tParams = _GDIPlus_ParamInit(1)
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
        Case "PNG", "BMP", "GIF", "TIF"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch
    Local $hStream = _WinAPI_CreateStreamOnHGlobal() ;http://msdn.microsoft.com/en-us/library/ms864401.aspx
    If @error Then Return SetError(2, 0, 0)
    _GDIPlus_ImageSaveToStream($hBitmap, $hStream, DllStructGetPtr($tGUID), DllStructGetPtr($tParams))
    If @error Then Return SetError(3, 0, 0)

    Local $hMemory = _WinAPI_GetHGlobalFromStream($hStream) ;http://msdn.microsoft.com/en-us/library/aa911736.aspx
    If @error Then Return SetError(4, 0, 0)
    Local $iMemSize = _MemGlobalSize($hMemory)
    If Not $iMemSize Then Return SetError(5, 0, 0)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    _WinAPI_ReleaseStream($hStream) ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85).aspx
    _MemGlobalFree($hMemory)
    If $bSave Then
        Local $hFile = FileOpen($sFilename, 18)
        If @error Then Return SetError(6, 0, $bData)
        FileWrite($hFile, $bData)
        FileClose($hFile)
    EndIf
    Return $bData
EndFunc   ;==>_GDIPlus_StreamImage2BinaryString


Func _CreateNewDIB_Bitmap($Width, $Height, $BitCount, ByRef $ptrbmp, ByRef $DibHandle, ByRef $DibPre_Obj)

    Local $tBITMAPINFO = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant; dword RGBQuad[256];")
    DllStructSetData($tBITMAPINFO, 'Size', 40)
    DllStructSetData($tBITMAPINFO, 'Width', $Width)
    DllStructSetData($tBITMAPINFO, 'Height', -$Height)
    DllStructSetData($tBITMAPINFO, 'Planes', 1)
    DllStructSetData($tBITMAPINFO, 'BitCount', $BitCount)
    Local $iColorCnt = BitShift(1, -$BitCount)
    DllStructSetData($tBITMAPINFO, 'ClrUsed', $iColorCnt)
    DllStructSetData($tBITMAPINFO, 'ClrImportant', $iColorCnt)

    ;https://www.autoitscript.com/forum/topic/139174-gdi-cc-code-to-autoit-conversion/
    Switch $BitCount
        Case 1
            DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift(0xFF, -16), BitShift(0xFF, -8), 0xFF), 1)
;~      Case 4
;~          Local $aCol[16] = [8, 24, 38, 56, 72, 88, 104, 120, 136, 152, 168, 184, 210, 216, 232, 248]
;~          For $i = 0 To 15
;~              DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($aCol[$i], -16), BitShift($aCol[$i], -8), $aCol[$i]), $i + 1)
;~          Next
        Case 4
            Local $aCol[16] = [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 216, 232, 248]
            For $i = 0 To 15
                DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($aCol[$i], -16), BitShift($aCol[$i], -8), $aCol[$i]), $i + 1)
            Next
;~      Case 8
;~          ; Windows reserves first color for white,
;~          DllStructSetData($tBITMAPINFO, 'RGBQuad', 255, 1)
;~          ; and last color as black!
;~          DllStructSetData($tBITMAPINFO, 'RGBQuad', 0, 255)
;~          Local $iColor = 10
;~          For $i = 20 To $iColorCnt - 22 ;first 20 and last 20 are reserved!
;~              DllStructSetData($tBITMAPINFO, 'RGBQuad', BitOR(BitShift($i, -16), BitShift($i, -8), $i * $iColor), $i + 1)
;~          Next
        Case 8
;~          ; Windows reserves first color for white,
;~          $tBITMAPINFO.RGBQuad((0)) = 0xFFFFFF
;~          ; and last color as black!
;~          $tBITMAPINFO.RGBQuad((0xFF)) = 0x000000
            Local $iColor = 20, $iRed, $iGreen, $iBlue
            For $iRed = 0 To 255 Step 51
                For $iGreen = 0 To 255 Step 51
                    For $iBlue = 0 To 255 Step 51
                        $tBITMAPINFO.RGBQuad(($iColor)) = BitShift($iRed, -16) + BitShift($iGreen, -8) + $iBlue
                        $iColor += 1
                    Next
                Next
            Next
    EndSwitch

    Local $hDC = _WinAPI_CreateCompatibleDC(0)
    $DibHandle = _WinAPI_CreateDIBSection(0, $tBITMAPINFO, $DIB_RGB_COLORS, $ptrbmp)
    $DibPre_Obj = _WinAPI_SelectObject($hDC, $DibHandle)
    Return $hDC
EndFunc   ;==>_CreateNewDIB_Bitmap

oh great, I edited my post and messed it up. lost all i wrote before.
basically my problem is when i Xor and image with $SRCINVERT and _WinAPI_BitBlt, and save the image in stream or file, after i load or rebuild the image, i get color problems, this only happens with 8 bits, other bits work just fine. i'm not sure if the color structure i'm using is the problem, or if i need to save or rebuild the 8 bits image differently. im stuck

Edited by jvds

Share this post


Link to post
Share on other sites

What do you expect when you reduce the colors from 32-bit to 8-bit?


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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

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

×
×
  • Create New...