lJoel Posted May 12, 2010 Share Posted May 12, 2010 Hi Is there a fast way to get the number of different pixel / colors from this code: Func CompareBitmaps($bm1, $bm2) $Bm1W = _GDIPlus_ImageGetWidth($bm1) $Bm1H = _GDIPlus_ImageGetHeight($bm1) $BitmapData1 = _GDIPlus_BitmapLockBits($bm1, 0, 0, $Bm1W, $Bm1H, $GDIP_ILMREAD, $GDIP_PXF32RGB) $Stride = DllStructGetData($BitmapData1, "Stride") $Scan0 = DllStructGetData($BitmapData1, "Scan0") $ptr1 = $Scan0 $size1 = ($Bm1H - 1) * $Stride + ($Bm1W - 1) * 4 $Bm2W = _GDIPlus_ImageGetWidth($bm2) $Bm2H = _GDIPlus_ImageGetHeight($bm2) $BitmapData2 = _GDIPlus_BitmapLockBits($bm2, 0, 0, $Bm2W, $Bm2H, $GDIP_ILMREAD, $GDIP_PXF32RGB) $Stride = DllStructGetData($BitmapData2, "Stride") $Scan0 = DllStructGetData($BitmapData2, "Scan0") $ptr2 = $Scan0 $size2 = ($Bm2H - 1) * $Stride + ($Bm2W - 1) * 4 $smallest = $size1 If $size2 < $smallest Then $smallest = $size2 $call = DllCall("msvcrt.dll", "int:cdecl", "memcmp", "ptr", $ptr1, "ptr", $ptr2, "int", $smallest) _GDIPlus_BitmapUnlockBits($bm1, $BitmapData1) _GDIPlus_BitmapUnlockBits($bm2, $BitmapData2) Return ($call[0]=0) EndFunc ;==>CompareBitmaps Cheers Joe Link to comment Share on other sites More sharing options...
junkew Posted May 16, 2010 Share Posted May 16, 2010 Whats the end goal of your comparison? The answers can be different based on your end goal Just checking if they are equal or do you want to now the locations of the differences.? Search for BITBLT in the forum or on GOOGLE for general solutions in other languages with SRCINVERT which should give you some directions. http://www.codeproject.com/KB/graphics/BitmapCompare.aspx http://www.codeproject.com/KB/GDI-plus/comparingimages.aspx http://www.allegro.cc/forums/thread/587792/616685#target Be prepared for padding issues on line(s) if you do have bitmaps of different sources. This could be especially the case as you are using memcmp to do the comparison. http://www.autoitscript.com/forum/index.php?showtopic=66545&hl=findbmp&st=0 will give you some directions including other links manipulating with bitmaps FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Malkey Posted May 18, 2010 Share Posted May 18, 2010 (edited) This example returns the number of pixels that do not have the same pixel value at corresponding coordinates of two images. Playing around with your function, CompareBitmaps(), using my script, CompareBitmaps() returned False when there was only one pixel different, and, returned True when the same image was compared in a .bmp file format and a .png file format. This means that CompareBitmaps() worked well. expandcollapse popup#include <GDIPlus.au3> #include <Array.au3> ;Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declare Local $hImage1, $iX, $iY, $hImage2, $iIW, $iIH, $bm1, $bm2 _GDIPlus_Startup() $hImage1 = _GDIPlus_ImageLoadFromFile("testplus2.bmp") $iX = _GDIPlus_ImageGetWidth($hImage1) $iY = _GDIPlus_ImageGetHeight($hImage1) $hImage2 = _GDIPlus_ImageLoadFromFile("test.bmp") $iIW = _GDIPlus_ImageGetWidth($hImage2) $iIH = _GDIPlus_ImageGetHeight($hImage2) $bm1 = _GDIPlus_BitmapCloneArea($hImage1, 0, 0, $iX, $iY, $GDIP_PXF32ARGB) $bm2 = _GDIPlus_BitmapCloneArea($hImage2, 0, 0, $iIW, $iIH, $GDIP_PXF32ARGB) MsgBox(0, "Results", "Number of different pixels is " & CompareBitmapPixels($bm1, $bm2) & @CRLF) _GDIPlus_BitmapDispose($bm1) _GDIPlus_BitmapDispose($bm2) _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_Shutdown() Func CompareBitmapPixels($bm1, $bm2) Local $Bm1W, $Bm1H, $BitmapData1, $Scan0, $Bm2W, $BitmapData2, $Bm2H Local $Scan01, $iNum = 0, $iDiff = 0, $v_BufferA, $AllPixels Local $sREResult1, $aArray, $v_BufferB, $AllPixelsB, $sREResult2, $aArray2 $Bm1W = _GDIPlus_ImageGetWidth($bm1) $Bm1H = _GDIPlus_ImageGetHeight($bm1) $BitmapData1 = _GDIPlus_BitmapLockBits($bm1, 0, 0, $Bm1W, $Bm1H, $GDIP_ILMREAD, $GDIP_PXF32RGB) $Scan0 = DllStructGetData($BitmapData1, "Scan0") $Bm2W = _GDIPlus_ImageGetWidth($bm2) $Bm2H = _GDIPlus_ImageGetHeight($bm2) $BitmapData2 = _GDIPlus_BitmapLockBits($bm2, 0, 0, $Bm2W, $Bm2H, $GDIP_ILMREAD, $GDIP_PXF32RGB) $Scan01 = DllStructGetData($BitmapData2, "Scan0") ; ============= $v_BufferA = DllStructCreate("byte[" & $Bm1H * $Bm1W * 4 & "]", $Scan0) ; Create DLL structure for all pixels $AllPixels = DllStructGetData($v_BufferA, 1) $sREResult1 = StringRegExpReplace(StringTrimLeft($AllPixels, 2), "(.{8})", "\1 ") $aArray = StringSplit(StringStripWS($sREResult1, 3), " ") $v_BufferB = DllStructCreate("byte[" & $Bm2H * $Bm2W * 4 & "]", $Scan01) ; Create DLL structure for all pixels $AllPixelsB = DllStructGetData($v_BufferB, 1) $sREResult2 = StringRegExpReplace(StringTrimLeft($AllPixelsB, 2), "(.{8})", "\1 ") $aArray2 = StringSplit(StringStripWS($sREResult2, 3), " ") $iDiff = Abs($aArray2[0] - $aArray[0]) For $i = 1 To UBound($aArray) - 1 - $iDiff If $aArray2[$i] <> $aArray[$i] Then $iNum += 1 Next ; ============= _GDIPlus_BitmapUnlockBits($bm1, $BitmapData1) _GDIPlus_BitmapUnlockBits($bm2, $BitmapData2) Return $iNum + $iDiff EndFunc ;==>CompareBitmapPixels The help with finding images to compare, I ran this script a couple of times to create slightly different image files. #include <GDIPlus.au3> ; http://www.autoitscript.com/forum/index.php?s=&showtopic=78645&view=findpost&p=567998 _GDIPlus_Startup() $h_bitmap = _WinAPI_CreateBitmap(150, 150, 1, 32) $h_image = _GDIPlus_BitmapCreateFromHBITMAP($h_bitmap) $h_graphic = _GDIPlus_ImageGetGraphicsContext($h_image) _GDIPlus_GraphicsClear($h_graphic, 0xFF808080) For $line = 20 To 40 For $col = 10 To 110 _GDIPlus_BitmapSetPixel($h_image, $col, $line, 0xFFFF0000) Next Next For $line = 60 To 80 For $col = 10 To 110 _GDIPlus_BitmapSetPixel($h_image, $col, $line, 0x00FF0000) Next Next _GDIPlus_BitmapSetPixel($h_image, 1, 1, 0xFF0000FF); _GDIPlus_BitmapSetPixel($h_image, 3, 1, 0xFFFFFFFF) _GDIPlus_ImageSaveToFile($h_image, "testPlus2.bmp") ShellExecute("testPlus2.bmp") _GDIPlus_ImageDispose($h_image) _WinAPI_DeleteObject($h_bitmap) _GDIPlus_Shutdown() Func _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iArgb) Local $aRet $aRet = DllCall($ghGDIPDll, "dword", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iArgb) Return EndFunc ;==>_GDIPlus_BitmapSetPixel Edited May 18, 2010 by Malkey 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