funkey Posted March 27, 2013 Share Posted March 27, 2013 (edited) 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: expandcollapse popup#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! Edited March 27, 2013 by funkey Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
UEZ Posted March 27, 2013 Share Posted March 27, 2013 (edited) Welcome to the cool GDI+ club Such operations can only be faster when using ext. DLLs or ASM. No chance using built-in loops. Edit: or using GDIP.au3 which has a lot of GDI+ function. Br, UEZ Edited March 27, 2013 by UEZ 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Jardz Posted March 27, 2013 Share Posted March 27, 2013 I'm sure UEZ is spot on but I was to try to achieve this I'd look at Chroma keying. _GDIPlus_ImageAttributesSetColorKeys (I think!!) If this could reliably select your colour area and make transparent, then you could greyscale the left overs and drop onto the original??! Personally I've never got this to select the right pixels for me, seems to use 'or' logic for each channel and not 'and' logic when selecting the pixels. Good luck getting a faster solution. Link to comment Share on other sites More sharing options...
funkey Posted March 27, 2013 Author Share Posted March 27, 2013 Thank you for your answers. @UEZ: I'm in the GDI+-Club since I made my 'Kurven-Spiel'. I will make a DLL, when I'm satisfied with the result. I think the effect can be better. @Jardz: Thanks, I will have a look at this function. Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
UEZ Posted March 27, 2013 Share Posted March 27, 2013 Thank you for your answers.@UEZ: I'm in the GDI+-Club since I made my 'Kurven-Spiel'. Totally forgot it... Br,UEZ 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ 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