Hello,
I made this script to set pictures to greyscale but leave one color original.
Can anyone help me to get the better and faster picture effect?
Here is the code, test it with small pictures:
Thanks for any help!
I made this script to set pictures to greyscale but leave one color original.
Can anyone help me to get the better and faster picture effect?
Here is the code, test it with small pictures:
[ autoit ]
#include <GDIPlus.au3> #include <WindowsConstants.au3> #include <Color.au3> #include <WinAPI.au3> #include <Array.au3> Opt("GUIOnEventMode", 1) Global $sPath = FileOpenDialog("Choose Picture", @ScriptDir, "Pictures (*.bmp;*.jpg;*.png)", 1) If @error Then Exit Global $iCol = -1 _GDIPlus_Startup() Global $hImage = _GDIPlus_ImageLoadFromFile($sPath) Global $iWidth = _GDIPlus_ImageGetWidth($hImage) Global $iHeight = _GDIPlus_ImageGetHeight($hImage) _GDIPlus_ImageDispose($hImage) Global $hGui = GUICreate("Color effect - Click to choose color", $iWidth, $iHeight);, -1, -1, 0x80000000) Global $nPic = GUICtrlCreatePic($sPath, 0, 0, $iWidth, $iHeight) GUICtrlSetOnEvent(-1, "_GetColor") GUISetState(@SW_SHOW, $hGui) Do Until $iCol <> -1 Opt("GUIOnEventMode", 0) WinSetTitle("Color effect", "", "Color effect - Please wait") Global $hBitmap = _GDIPlus_BitmapCreateFromFile($sPath) Global $tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD + $GDIP_ILMWRITE, $GDIP_PXF32RGB) ;Stride - Offset, in bytes, between consecutive scan lines of the bitmap. ;If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. Global $iStride = DllStructGetData($tBitmapData, "Stride") ;Pixel format - Integer that specifies the pixel format of the bitmap Global $iPixelFormat = DllStructGetData($tBitmapData, "Format") ;Scan0 - Pointer to the first (index 0) scan line of the bitmap. Global $pScan0 = DllStructGetData($tBitmapData, "Scan0") Global $tPixel Global $iColPixel, $aCol[3], $aSetCol = _ColorGetRGB($iCol) Global $iTol = 120, $Luma For $row = 0 To $iHeight - 1 For $col = 0 To $iWidth - 1 $tPixel = DllStructCreate("dword", $pScan0 + $row * $iStride + $col * 4) $iColPixel = DllStructGetData($tPixel, 1) $aCol[0] = BitAND(BitShift($iColPixel, 16), 0xFF) $aCol[1] = BitAND(BitShift($iColPixel, 8), 0xFF) $aCol[2] = BitAND($iColPixel, 0xFF) If Not _ColorInTolerance($aSetCol, $aCol, $iTol) Then $Luma = $aCol[0] * 0.3 + $aCol[1] * 0.59 + $aCol[2] * 0.11 DllStructSetData($tPixel, 1, BitOR($Luma, BitShift($Luma, -8), BitShift($Luma, -16))) EndIf Next Next _GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData) Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _WinAPI_DeleteObject(GUICtrlSendMsg($nPic, 370, 0, $hHBitmap)) WinSetTitle("Color effect", "", "Color effect - Finished") Do Until GUIGetMsg() = -3 Global $sFileName = FileSaveDialog("Save picture", @ScriptDir, "JPG mage (*.jpg)", 16, "Bitmap_" & Hex($iCol, 6) & ".JPG") If Not @error Then If StringRight($sFileName, 4) <> ".JPG" Then $sFileName &= ".JPG" Global $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap) _GDIPlus_ImageSaveToFile($hImage, $sFileName) _WinAPI_DeleteObject($hImage) EndIf _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteObject($hHBitmap) _GDIPlus_Shutdown() Func _ColorInTolerance($aSetCol, $aCol, $iTol) Global $aTol[3] = [$iTol / 4, $iTol / 4, $iTol / 4] $aTol[_ArrayMaxIndex($aSetCol)] = $iTol If ($aSetCol[0] - $aTol[0]) < $aCol[0] And ($aSetCol[0] + $aTol[0]) > $aCol[0] And _ ($aSetCol[1] - $aTol[1]) < $aCol[1] And ($aSetCol[1] + $aTol[1]) > $aCol[1] And _ ($aSetCol[2] - $aTol[2]) < $aCol[2] And ($aSetCol[2] + $aTol[2]) > $aCol[2] Then Return 1 Else Return 0 EndIf EndFunc ;==>_ColorInTolerance Func _GetColor() $iCol = PixelGetColor(MouseGetPos(0), MouseGetPos(1)) EndFunc ;==>_GetColor
Thanks for any help!