Jump to content

Convert $hBMP to GrayScale


Recommended Posts

#include <WinAPISysWin.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPIGdi.au3>
#include <ScreenCapture.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$zzz = WinGetHandle("Windows Media Player")
GrayCapture($zzz)

Func GrayCapture($HWnd)
    if Not WinExists($HWnd) Then Return 0
    _GDIPlus_Startup()
    Local $w = _WinAPI_GetWindowWidth($HWnd), $h = _WinAPI_GetWindowHeight($HWnd)
    Local $hDDC = _WinAPI_GetDC($HWnd)
    Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $w, $h)
    Local $filename = @ScriptDir&"\ScreenShot\"&@YEAR&@MON&@MDAY&"-"&@HOUR&@MIN&@SEC&@MSEC&".bmp"

    _WinAPI_SelectObject($hCDC, $hBMP)
    _WinAPI_BitBlt($hCDC, 0, 0, $w, $h, $hDDC, 0, 0, $SRCCOPY)
    _WinAPI_ReleaseDC($HWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    ;..........
    _WinAPI_SaveHBITMAPToFile($filename, $hBMP)
    _WinAPI_DeleteObject($hBMP)
    _GDIPlus_Shutdown()
    Run('mspaint.exe "' & $filename&'"')
EndFunc

Hi. Everyone

Help me convert "$hBMP" to be grayscale 

Thank 

 

Link to comment
Share on other sites

You can easily find the equation for converting pixel from RGB to grayscale (E.g this Tutorial Spoint)

Quote

New grayscale image = ( (0.3 * R) + (0.59 * G) + (0.11 * B ).

According to this equation, Red has contributed 30%, Green has contributed 59% which is greater in all three colors and Blue has contributed 11%.

 
 

Now your job is iterating through the image, then edit the R, G, B value of every pixel into the newly calculated grayscale value.

 

Edited by LukeLe
delete typo
Link to comment
Share on other sites

This modified version of the _GDIPlus_ColorMatrixCreateGrayScale function's example in the AutoIt Help file, saves the grayscale bitmap to a file.

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <WinAPIHObj.au3>

Example()

Func Example()
    _GDIPlus_Startup() ;initialize GDI+
    Local Const $iWidth = 600, $iHeight = 600

    Local $hGUI = GUICreate("GDI+ Example (" & @ScriptName & ")", $iWidth, $iHeight) ;create a test GUI
    GUISetState(@SW_SHOW)

    Local $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle

    Local $hIA = _GDIPlus_ImageAttributesCreate() ;create an ImageAttribute object
    Local $tColorMatrix = _GDIPlus_ColorMatrixCreateGrayScale() ;create greyscale color matrix
    _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $tColorMatrix) ;set greyscale color matrix

    Local $hHBmp = _ScreenCapture_Capture("", 0, 0, $iWidth, $iHeight) ;create a GDI bitmap by capturing an area on desktop
    Local $hBitmapGUI = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ;convert GDI to GDI+ bitmap
    Local $hBitmapBM = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ;convert GDI to GDI+ bitmap
    Local $hGraphicBM = _GDIPlus_ImageGetGraphicsContext($hBitmapBM)
    _WinAPI_DeleteObject($hHBmp) ;release GDI bitmap resource because not needed anymore

    _GDIPlus_GraphicsDrawImageRectRect($hGraphicBM, $hBitmapBM, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, $hIA) ;draw the bitmap while applying the color adjustment

    _GDIPlus_ImageSaveToFile($hBitmapBM, @ScriptDir & "\" & @YEAR & @MON & @MDAY & "-" & @HOUR & @MIN & @SEC & @MSEC & ".bmp")

    Do
        _GDIPlus_GraphicsDrawImageRectRect($hGraphicGUI, $hBitmapGUI, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, $hIA) ;draw the bitmap while applying the color adjustment
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ;cleanup GDI+ resources
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _GDIPlus_GraphicsDispose($hGraphicBM)
    _GDIPlus_BitmapDispose($hBitmapGUI)
    _GDIPlus_BitmapDispose($hBitmapBM)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
EndFunc   ;==>Example

 

Link to comment
Share on other sites

Enhanced version with image capture :

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <WinAPIHObj.au3>

Example()

Func Example()
  _GDIPlus_Startup() ;initialize GDI+
  Local $hWnd = WinGetHandle("[CLASS:Photo_Lightweight_Viewer]")
  WinActivate($hWnd)
  Local $hCtrl = ControlGetHandle($hWnd, "", "[CLASS:Photos_PhotoCanvas; INSTANCE:1]")
  Local $aPos = WinGetPos($hCtrl)

  Local Const $iWidth = $aPos[2], $iHeight = $aPos[3]
  Local $hGUI = GUICreate("GDI+", $iWidth, $iHeight) ;create a test GUI

  Local $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle
  Local $hIA = _GDIPlus_ImageAttributesCreate() ;create an ImageAttribute object

  Local $tColorMatrix = _GDIPlus_ColorMatrixCreateGrayScale() ;create greyscale color matrix

  _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $tColorMatrix) ;set greyscale color matrix

  Local $hHBmp = _ScreenCapture_CaptureWnd("", $hCtrl, 0, 0, $iWidth, $iHeight, False)
  Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ;convert GDI to GDI+ bitmap
  Local $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
  _WinAPI_DeleteObject($hHBmp) ;release GDI bitmap resource because not needed anymore
  _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, $hIA)
  _GDIPlus_ImageSaveToFile($hBitmap, @YEAR & @MON & @MDAY & "-" & @HOUR & @MIN & @SEC & @MSEC & ".bmp")

  GUISetState(@SW_SHOW)

  Do
    _GDIPlus_GraphicsDrawImageRectRect($hGraphicGUI, $hBitmap, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, $hIA)
  Until GUIGetMsg() = $GUI_EVENT_CLOSE

  ;cleanup GDI+ resources
  _GDIPlus_ImageAttributesDispose($hIA)
  _GDIPlus_GraphicsDispose($hGraphicGUI)
  _GDIPlus_GraphicsDispose($hGraphic)
  _GDIPlus_BitmapDispose($hBitmap)
  _GDIPlus_Shutdown()
  GUIDelete($hGUI)
EndFunc   ;==>Example

 

Edited by Nine
Link to comment
Share on other sites

Here's a C DLL version (attached, or compile with TCC)

#include <GDIPlus.au3>
#include <ScreenCapture.au3>

Global Static $Dll = DllOpen("GrayScaleLUMA.dll")
Global $Image, $iWidth, $iHeight, $Pixels, $Gfx, $hGui, $hBmp
_GDIPlus_Startup()

$hBmp = _ScreenCapture_Capture("", 0, 0, 640, 480)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
$iWidth = _GDIPlus_ImageGetWidth($hImage)
$iHeight = _GDIPlus_ImageGetHeight($hImage)

$hGui = GUICreate  ("GrayScale DLL", $iWidth, $iHeight, -1, -1)
       GUISetState(@SW_SHOW, $hGui)

$hGfx = _GDIPlus_GraphicsCreateFromHWND($hGui)
       _GrayScaleLUMA($hImage)
       _GDIPlus_GraphicsDrawImageRect($hGfx, $hImage, 0, 0, $iWidth, $iHeight)
       _GDIPlus_BitmapDispose($hImage)
       _GDIPlus_Shutdown()

Do
      Sleep(10)
Until GUIGetMsg() = - 3

Func _GrayScaleLUMA(ByRef $hImage)
    $Pixels  = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, BitOR($GDIP_ILMWRITE, $GDIP_ILMREAD), $GDIP_PXF32ARGB)
    DllCall($Dll, "int:cdecl", "GrayScaleLUMA", "ptr", $Pixels.Scan0, "int", $iWidth * $iHeight)
    _GDIPlus_BitmapUnlockBits($hImage, $Pixels)
    ;$Pixels = 0
 EndFunc

#cs
=======================================================================================================
C code for the DLL, compile with 'Tiny C Compiler' (TCC) https://bellard.org/tcc/

tcc -shared GrayScale.c

#include <stdlib.h>

__declspec(dllexport) int GrayScaleLUMA(int* pixel, int len) {

    int i, rgb, gray;

    for(i = 0; i < len; i++) {
         rgb=(((pixel[i]&0x00ff0000)>>16)*.3+(((pixel[i]&0x0000ff00))>>8)*.59+(pixel[i]&0x000000ff)*.11);
         pixel[i]=(pixel[i]&0xff000000)+(rgb<<16)+(rgb<<8)+rgb;
    }
return;
}
#ce

 

GrayScaleLUMA.dll

Some guy's script + some other guy's script = my script!

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