Nachdem mich mal jemand im Chat auf die Idee gebracht hat, ein Bildervergleichsprogramm zu machen, hab ich mir gedacht, dass es ganz geeignet wäre mich mal ein bisschen mit FASM auseinanderzusetzen. Das sind hier also eine meiner ersten Gehversuche mit FASM, also zerfleischt mich nicht gleich....
Das Programm vergleicht die einzelnen Farbwerte der Pixel und generiert ein Bild, auf dem die Farbunterschiede deutlich werden:
[Blockierte Grafik: http://img576.imageshack.us/img576/5130/unbenanntgcy.jpg]
Ich hab mich jetzt hierbei hauptsächlich auf den ASM Code konzentriert, also nicht wundern wenn die GUI nicht gefällt:)
Man zieht zwei Bilder, die man vergleichen möchte auf die entsprechenden Bereiche, wählt einen Farbkanal aus und kann mit einem Klick auf das Result-Bild das Bild mit dem Standard-Bildbetrachtungsprogramm öffnen.
Hier also der Code:
Spoiler anzeigen
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)
_GDIPlus_Startup()
#region +++++++++ GUI +++++++++
Global $hGui = GUICreate("Farbdifferenz | Coded by K4z", 905, 769, 214, 108, Default, $WS_EX_ACCEPTFILES)
GUISetOnEvent($GUI_EVENT_CLOSE, "_GuiEvent")
GUISetOnEvent($GUI_EVENT_DROPPED, "_GuiEvent")
Global $Bild1 = GUICtrlCreateGroup("Bild1", 5, 8, 435, 361)
Global $idPic1 = GUICtrlCreatePic("", 12, 20, 420, 340), $sPath1
Global $Bild2 = GUICtrlCreateGroup("Bild2", 460, 8, 435, 361)
Global $idPic2 = GUICtrlCreatePic("", 466, 20, 420, 340), $sPath2
Global $Result = GUICtrlCreateGroup("Result", 230, 384, 435, 361)
Global $idPic3 = GUICtrlCreatePic("", 237, 396, 420, 340), $sPath3
GUICtrlSetOnEvent(-1, "_GuiEvent")
GUICtrlCreateGroup("", -99, -99, 1, 1)
Global $idBtnRed = GUICtrlCreateRadio("Rot", 680, 536, 113, 17)
GUICtrlSetOnEvent(-1, "_GuiEvent")
Global $idBtnGreen = GUICtrlCreateRadio("Grün", 680, 561, 113, 17)
GUICtrlSetOnEvent(-1, "_GuiEvent")
Global $idBtnBlue = GUICtrlCreateRadio("Blau", 680, 587, 113, 17)
GUICtrlSetOnEvent(-1, "_GuiEvent")
GUICtrlSetState($idPic1, $GUI_DROPACCEPTED)
GUICtrlSetState($idPic2, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOW)
#endregion +++++++++ GUI +++++++++
Global $tCodeBuffer = DllStructCreate("byte[100]")
DllStructSetData($tCodeBuffer, 1,"0x8B7424048B5C24088B038946648B43048946688B530C8B4B088B46648B008B5E688B1B83FA0177107208C1E808C1EB08EB06C1E810C1EB1038D8760286C328C3B0FFC1E00888D8C1E00888D8C1E00888D88B5E648903834664048346680483E90177B6C3")
Global $tParameters = DllStructCreate("ptr scan1;ptr scan2;int size;int mode")
While 1
Sleep(50)
WEnd
Func _GuiEvent()
Switch @GUI_CtrlId
Case $GUI_EVENT_CLOSE
_GDIPlus_Shutdown()
Exit
Case $GUI_EVENT_DROPPED
GUICtrlSetImage(@GUI_DropId, @GUI_DragFile)
If StringRegExp(@GUI_DragFile, '(?i)\.jpg$') Then
If @GUI_DropId = $idPic1 Then $sPath1 = @GUI_DragFile
If @GUI_DropId = $idPic2 Then $sPath2 = @GUI_DragFile
EndIf
Case $idBtnRed
If $sPath1 <> '' And $sPath2 <> '' Then
$sPath3 = _GetColorDifference(0, $sPath1, $sPath2)
GUICtrlSetImage($idPic3, $sPath3)
EndIf
Case $idBtnGreen
If $sPath1 <> '' And $sPath2 <> '' Then
$sPath3 = _GetColorDifference(1, $sPath1, $sPath2)
GUICtrlSetImage($idPic3, $sPath3)
EndIf
Case $idBtnBlue
If $sPath1 <> '' And $sPath2 <> '' Then
$sPath3 = _GetColorDifference(2, $sPath1, $sPath2)
GUICtrlSetImage($idPic3, $sPath3)
EndIf
Case $idPic3
If $sPath3 <> '' Then ShellExecute($sPath3)
EndSwitch
EndFunc
Func _GetColorDifference($iColor, $sPath1, $sPath2)
; $iColor: --- 0=Rot --- 1=Grün --- 2=Blau ---
Local $hBitmap1, $hBitmap2, $iWidth1, $iWidth2, $iHeight1, $iHeight2
$hBitmap1 = _GDIPlus_BitmapCreateFromFile($sPath1)
$iWidth1 = _GDIPlus_ImageGetWidth($hBitmap1)
$iHeight1 = _GDIPlus_ImageGetHeight($hBitmap1)
$hBitmap2 = _GDIPlus_BitmapCreateFromFile($sPath2)
$iWidth2 = _GDIPlus_ImageGetWidth($hBitmap2)
$iHeight2 = _GDIPlus_ImageGetHeight($hBitmap2)
If ($iWidth1 <> $iWidth2) Or ($iHeight1 <> $iHeight2) Then
MsgBox(48, "Fehler", "Unterschiedliche Größen!")
Return
EndIf
Local $hBitmapData1 = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $iWidth1, $iHeight1, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32RGB)
Local $hBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $iWidth2, $iHeight2, $GDIP_ILMREAD, $GDIP_PXF32RGB)
DllStructSetData($tParameters, "scan1", DllStructGetData($hBitmapData1, "Scan0"))
DllStructSetData($tParameters, "scan2", DllStructGetData($hBitmapData2, "Scan0"))
DllStructSetData($tParameters, "size", $iWidth1 * $iHeight1)
DllStructSetData($tParameters, "mode", $iColor)
DllCall("user32.dll", "ptr", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer),"ptr", DllStructGetPtr($tCodeBuffer), "ptr", DllStructGetPtr($tParameters), "int", 0, "int", 0)
_GDIPlus_BitmapUnlockBits($hBitmap1, $hBitmapData1)
_GDIPlus_BitmapUnlockBits($hBitmap2, $hBitmapData2)
If @error Then Return
_GDIPlus_ImageSaveToFile($hBitmap1, @TempDir & "\321654r3sult.jpg")
Return @TempDir & "\321654r3sult.jpg"
EndFunc
Und hier der Teil mit dem FASM-Code:
Spoiler anzeigen
$_assembleit_flag=0
_assembleit("ptr", "_asm","int",FasmGetBasePtr($Fasm))
Func _asm()
_("use32") ; 32-Bit Assembler
_("mov esi, dword[esp+4]") ; ESI = BasePointer
_("mov ebx, dword[esp+8]") ; EBX = Pointer zum ParameterStruct
_("mov eax, dword[ebx]") ; -\
_("mov dword[esi+ptrPic1], eax") ; -/ ptrPic1 = Pointer zum ersten Bild
_("mov eax, dword[ebx+4]") ; -\
_("mov dword[esi+ptrPic2], eax") ; -/ ptrPic2 = Pointer zum zweiten Bild
_("mov edx, dword[ebx+12]") ; EDX = $iMode
_("mov ecx, dword[ebx+8]") ; ECX = PixelCount
_("_nextPixel:")
[/autoit] [autoit][/autoit] [autoit]_("mov eax, dword[esi+ptrPic1]") ; -\
_("mov eax, dword[eax]") ; -/ EAX = PixelColor Bild1
_("mov ebx, dword[esi+ptrPic2]") ; -\
_("mov ebx, dword[ebx]") ; -/ EBX = PixelColor Bild2
_("cmp edx, 1") ; -\
_("ja _ShiftEnd") ; -\
_("jb _ShiftRed") ; |
_("shr eax, 8") ; | If ($iMode=0){
_("shr ebx, 8") ; | ShiftRight(EAX, 8); ShiftRight(EBX, 8);
_("jmp _ShiftEnd") ; | } elseif ($iMode=2){
_("_ShiftRed:") ; | ShiftRight(EAX, 16); ShiftRight(EBX, 16);
_("shr eax, 16") ; | }
_("shr ebx, 16") ; |
_("_ShiftEnd:") ; -/
_("cmp al, bl") ; -\
_("jbe _IfBE1") ; -\ If (al>=bl){
_("xchg al, bl") ; AL, BL vertauschen
_("_IfBE1:") ; -/ }
_("sub bl, al") ; - BL = BL-AL (rDiff)
[/autoit] [autoit][/autoit] [autoit]_("mov al, 0xFF") ; -\
_("shl eax, 8") ; |
_("mov al, bl") ; |
_("shl eax, 8") ; | EAX = 0xFF:BL:BL:BL
_("mov al, bl") ; |
_("shl eax, 8") ; |
_("mov al, bl") ; -/
_("mov ebx, dword[esi+ptrPic1]") ; -\
_("mov dword[ebx], eax") ; -/ PixelSetColor: EAX
_("add dword[esi+ptrPic1], 4") ; - ptrPic1 += 4
_("add dword[esi+ptrPic2], 4") ; - ptrPic2 += 4
_("sub ecx, 1") ; - ECX -= 1
_("ja _nextPixel") ;
_("ret")
;-------------------------
_("ptrPic1 dd ?")
_("ptrPic2 dd ?")
EndFunc ;==>_asm
Ob das Programm jetzt wirklich sinnvoll ist, kann jeder für sich selbst entscheiden... Für mich war es jedenfalls eine gute Übung und ich wollte euch den Code nicht vorenthalten.