问题
I have translated this code to VB.NET which is a function to check if a image is grayscale.
private static unsafe bool IsGrayScale(Image image)
{
using (var bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb))
{
using (var g = Graphics.FromImage(bmp))
{
g.DrawImage(image, 0, 0);
}
var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
var pt = (int*)data.Scan0;
var res = true;
for (var i = 0; i < data.Height * data.Width; i++)
{
var color = Color.FromArgb(pt[i]);
if (color.A != 0 && (color.R != color.G || color.G != color.B))
{
res = false;
break;
}
}
bmp.UnlockBits(data);
return res;
}
}
The C# code is working but is not doing what I need so I did a little modifications trying to make a function which checks if a image has certain RGB color but the most important part is not working:
Dim color__1 = Color.FromArgb(pt(i))
Exception:
Error 1 Expression is not an array or a method, and cannot have an argument list. C:\Visual Studio Projects\WindowsApplication9\WindowsApplication9\Form1.vb 21 47 WindowsApplication9
Here is the translated code:
Imports System.Drawing.Imaging
Public Class Form1
Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean
Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)
Using graph = Graphics.FromImage(bmp)
graph.DrawImage(image, 0, 0)
End Using
Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)
Dim pt = CType(data.Scan0, Integer)
MsgBox(pt)
Dim res As Boolean
Dim i = 0
While i < data.Height * data.Width
Dim color__1 = Color.FromArgb(pt(i))
If color__1.A <> 0 AndAlso color__1.R = R AndAlso color__1.G = G AndAlso color__1.B = B Then
res = True
Exit While
End If
System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
End While
bmp.UnlockBits(data)
Return res
End Using
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim bmp = New Bitmap("C:\Users\Administrador\Desktop\PrtScr capture_3.jpg")
MsgBox(ImageHasColor(bmp, 240, 240, 240))
End Sub
End Class
UPDATE:
Those codes works only for the first time, if I use it more than one time I get this error:
Attempted to read or write protected memory
1.
Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean
Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)
Using graph = Graphics.FromImage(bmp)
graph.DrawImage(image, 0, 0)
End Using
Dim color__1 As Color
Dim byt
Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)
Dim pt = CType(data.Scan0, Integer)
Dim res As Boolean
For i = 0 To data.Height * data.Width - 1
color__1 = Color.FromArgb(Marshal.ReadInt32(pt, i * 4))
If color__1.A <> 0 AndAlso color__1.R = R AndAlso color__1.G = G AndAlso color__1.B = B Then
res = True
Exit For
End If
'System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
Next
bmp.UnlockBits(data)
Return res
End Using
End Function
2.
Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean
Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)
Using graph = Graphics.FromImage(bmp)
graph.DrawImage(image, 0, 0)
End Using
Dim color__1 As Color
Dim byt
Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)
Dim pt = CType(data.Scan0, Integer)
Dim res As Boolean
Dim i = 0
While i < data.Height * data.Width
color__1 = Color.FromArgb(Marshal.ReadInt32(pt, i * 4))
If color__1.A <> 0 AndAlso color__1.R = R AndAlso color__1.G = G AndAlso color__1.B = B Then
res = True
Exit While
End If
System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)
End While
bmp.UnlockBits(data)
Return res
End Using
End Function
UPDATE:
This code seems to be working
Private Shared Function ImageHasColor(ByVal image As Image, ByVal R As Int32, ByVal G As Int32, ByVal B As Int32) As Boolean
Try
Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)
Using graph = Graphics.FromImage(bmp) : graph.DrawImage(image, 0, 0) : End Using
Dim Pixel_Color As Color
Dim Ditmap_Data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)
Dim pt As IntPtr = CType(Ditmap_Data.Scan0, IntPtr)
For i = 0 To Ditmap_Data.Height * Ditmap_Data.Width - 1
Pixel_Color = Color.FromArgb(Marshal.ReadInt32(pt, i * 4))
If Pixel_Color.A <> 0 AndAlso Pixel_Color.R = R AndAlso Pixel_Color.G = G AndAlso Pixel_Color.B = B Then
bmp.UnlockBits(Ditmap_Data)
Return True
End If
Next
bmp.UnlockBits(Ditmap_Data)
Return False
End Using
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
回答1:
Now you're just being contrarian. Why these UnlockBits in the loop? Do you see them in the original code? Remove them at once.
Private Shared Function HasColor(ByVal image As Image, ByVal toFind As Color) As Boolean
Using bmp = New Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)
Using graph = Graphics.FromImage(bmp)
graph.DrawImage(image, 0, 0)
End Using
Dim data = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.[ReadOnly], bmp.PixelFormat)
Dim pt = data.Scan0 'Since we can't use a pointer in VB.Net, we'll stick to IntPtr for now
Dim res As Boolean = False
For i=0 To data.Height * data.Width - 1
Dim foundColor as Int32 = Marshal.ReadInt32(pt, i*4)
If (foundColor and &HFF000000) <> 0 AndAlso ( (foundColor and &H00FFFFFF) = (toFind.ToArgb() and &H00FFFFFF) ) Then
res = True
Exit For
End If
Next
bmp.UnlockBits(data)
Return res
End Using
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim bmp = New Bitmap("C:\Users\Administrador\Desktop\PrtScr capture_3.jpg")
MsgBox(ImageHasColor(bmp, Color.FromArgb(240, 240, 240)))
End Sub
End Class
回答2:
Try declaring pt
as an IntPtr
and using the Marshal
and BitConverter
classes to read the integer there.
来源:https://stackoverflow.com/questions/16605197/cant-set-the-correct-value-in-this-while-loop