找回密码
 加入
搜索
查看: 239|回复: 6

[图形处理] [已解决]请问用什么函数检测JPG或BMP的颜色?DllCall方式检测颜色有BUG!

[复制链接]
发表于 2024-7-12 21:57:24 | 显示全部楼层 |阅读模式
本帖最后由 hlzxcjx 于 2024-7-16 21:26 编辑

请问有没有好用的函数检测JPG或BMP的颜色?用函数DllCall($ghGDIPDll, 'uint', 'GdipBitmapGetPixel', 'ptr', $hImage, 'int', $iX, 'int', $iY, 'ptr*', 0)检测颜色,当检测的图片达一定量的时候就会出现错误,检测不出来!

下面的源码,当检测图片数达25个时,就出现错误:




#include <gdiplus.au3>

For $i = 2 To 30
        FileCopy("1.jpg", $i & ".jpg")
Next

_GDIPlus_Startup()

For $k = 1 To 30
        $hBitmap = _GDIPlus_BitmapCreateFromFile($k & ".jpg")
        $aRet = _GDIPlus_ImageGetPixelFormat($hBitmap)

        $h = _GDIPlus_ImageGetHeight($hBitmap)
        $w = _GDIPlus_ImageGetWidth($hBitmap)

        For $j = 0 To 100
                For $i = 0 To $w - 1
                        $colour = _myBitmapGetPixel($hBitmap, $i, $j)
                        $colour2 = Dec(StringTrimLeft($colour, 4))
                        If $colour2 <> 16777215 Then
                                MsgBox(0, "颜色值=" & $colour & "--" & $colour2, "检测颜色出错!" & "第" & $k & "个图片,第" & $j & "行 第" & $i & "列")
                        EndIf
                Next
                ToolTip("第" & $k & "个图片,第" & $j & "行 第" & $i & "列")
        Next
Next

MsgBox(0, 0, "end   第" & $k & "个图片,第" & $j & "行 第" & $i & "列")

_GDIPlus_ImageDispose($hBitmap)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()


Func _myBitmapCreate($iWidth, $iHeight, $iFormat = $GDIP_PXF24RGB);创建位图方式1, 此方法效率最高, 同时与Gdiplus兼容
        Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", 0, "int", $iFormat, "ptr", 0, "int*", 0)
        If @error Then Return SetError(@error, @extended, 0)
        Return $aResult[6]
EndFunc   ;==>_myBitmapCreate

Func _myBitmapCreate2($iWidth, $iHeight, $iFormat = $GDIP_PXF32RGB);备忘: 我在2009年采用的WinApi方式创建位图方式, 只支持1,32 Bpp
        Local $hRet, $hBitmap
        Switch $iFormat
                Case $GDIP_PXF01INDEXED
                        $iFormat = 1
                Case Else
                        $iFormat = 32
        EndSwitch
        $hRet = _WinAPI_CreateBitmap($iWidth, $iHeight, 1, $iFormat)
        $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hRet)
        _WinAPI_DeleteObject($hRet)
        Return $hBitmap
EndFunc   ;==>_myBitmapCreate2

Func _myBitmapSetPixel($hImage, $iX, $iY, $iArgb)
        DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hImage, "int", $iX, "int", $iY, "dword", $iArgb)
        If @error Then Return SetError(@error, @extended, 0)
EndFunc   ;==>_myBitmapSetPixel

Func _myBitmapGetPixel($hImage, $iX, $iY)
        Local $aResult = DllCall($ghGDIPDll, 'uint', 'GdipBitmapGetPixel', 'ptr', $hImage, 'int', $iX, 'int', $iY, 'ptr*', 0)
        If @error Then
                Return SetError(@error, @extended, 0)
        Else
                Return $aResult[4]
        EndIf
EndFunc   ;==>_myBitmapGetPixel

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2024-7-14 23:19:17 | 显示全部楼层
bmp完全没问题





#include <GDIPlus.au3>

For $i = 1 To 30
        FileCopy("1.bmp", $i & ".bmp")
Next

_GDIPlus_Startup()

For $k = 1 To 30
        $hBitmap = _GDIPlus_BitmapCreateFromFile($k & ".bmp")
        $h = _GDIPlus_ImageGetHeight($hBitmap)
        $w = _GDIPlus_ImageGetWidth($hBitmap)

        For $j = 0 To $h - 1
                For $i = 0 To $w - 1
                        $colour = Dec(StringTrimLeft(Hex(_GDIPlus_BitmapGetPixel($hBitmap, $i, $j), 8), 2))
                        If $colour <> 16777215 Then
                                ConsoleWrite("颜色值=" & $colour & '  ' & "检测颜色出错!" & "第" & $k & "个图片,第" & $j & "行 第" & $i & "列" & @CRLF)
                        EndIf
                Next
        Next
Next

_GDIPlus_ImageDispose($hBitmap)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2024-7-15 14:55:38 | 显示全部楼层

首先你的附件里都没有BMP图片,只有JPG图片,测试几秒就完成?
其次测试行数不要太多,否则一个图片扫描太久,每个图片测试100行够了:For $j = 0 To 100;
虽然新版有了内置函数_GDIPlus_BitmapGetPixel,但扫描图片多了仍然会出错!
发表于 2024-7-15 15:39:17 | 显示全部楼层
jpg 你的图片 没报错

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2024-7-15 15:49:46 | 显示全部楼层
本帖最后由 hlzxcjx 于 2024-7-15 16:10 编辑
3131210 发表于 2024-7-15 15:39
jpg 你的图片 没报错

几秒完成且不出错?难道与电脑配置有关?测试100个或以上图片试试!
还是与版本有关?我用的是稳定版:v3.3.13.12, 请问你用的什么版本?
发表于 2024-7-15 18:05:35 | 显示全部楼层
我能想到的就是你内存爆了
#include <GDIPlus.au3>

Local $num = 100

For $i = 1 To $num
        FileCopy("1.jpg", $i & ".jpg")
Next

_GDIPlus_Startup()

For $k = 1 To $num
        $hBitmap = _GDIPlus_BitmapCreateFromFile($k & ".jpg")
        $h = _GDIPlus_ImageGetHeight($hBitmap)
        $w = _GDIPlus_ImageGetWidth($hBitmap)

        For $j = 0 To $h - 1
                For $i = 0 To $w - 1
                        $colour = Dec(StringTrimLeft(Hex(_GDIPlus_BitmapGetPixel($hBitmap, $i, $j), 8), 2))
                        If $colour <> 16777215 Then
                                ConsoleWrite("颜色值=" & $colour & '  ' & "检测颜色出错!" & "第" & $k & "个图片,第" & $j & "行 第" & $i & "列" & @CRLF)
                        EndIf
                Next
        Next
        _GDIPlus_ImageDispose($hBitmap)
Next
_GDIPlus_Shutdown()
 楼主| 发表于 2024-7-15 23:47:48 | 显示全部楼层
3131210 发表于 2024-7-15 18:05
我能想到的就是你内存爆了

好像与没有释放资源有关!检测每个图片后都加如下语句:
     _GDIPlus_ImageDispose($hBitmap)
似乎不出错了!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-9-8 10:02 , Processed in 0.084644 second(s), 22 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表