Hallo,
meine Kamera hat den Effektfilter 'Selektive Farbe'. Ich habe nun versucht das ganze nachzubauen, bin aber noch nicht wirklich zufrieden.
Vielleicht hat jemand eine Idee, wie man das besser und schneller lösen könnte. Schneller kann ich es bestimmt mit einer DLL machen, aber vor allem sollte der Effekt besser funktionieren. Am besten erst mit kleinen Bildern probieren.
Vielen Dank für jede Hilfe von den Grafik-Profis hier!
Spoiler anzeigen
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <Color.au3>
#include <WinAPI.au3>
#include <Array.au3>
Opt("GUIOnEventMode", 1)
[/autoit] [autoit][/autoit] [autoit]Global $sPath = FileOpenDialog("Choose Picture", @ScriptDir, "Pictures (*.bmp;*.jpg;*.png)", 1)
If @error Then Exit
Global $iCol = -1
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]_GDIPlus_Startup()
Global $hImage = _GDIPlus_ImageLoadFromFile($sPath)
Global $iWidth = _GDIPlus_ImageGetWidth($hImage)
Global $iHeight = _GDIPlus_ImageGetHeight($hImage)
;~ _GDIPlus_ImageGetPixelFormat
_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")
[/autoit] [autoit][/autoit] [autoit]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
[/autoit] [autoit][/autoit] [autoit]Global $iColPixel, $aCol[3], $aSetCol = _ColorGetRGB($iCol)
Global $iTol = 80, $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)
[/autoit] [autoit][/autoit] [autoit]Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
_WinAPI_DeleteObject(GUICtrlSendMsg($nPic, 370, 0, $hHBitmap))
WinSetTitle("Color effect", "", "Color effect - Finished")
[/autoit] [autoit][/autoit] [autoit]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, $iTol, $iTol]
$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