PictureBox Fabeinstellung auslesen...

  • VB.NET
  • .NET (FX) 1.0–2.0

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    PictureBox Fabeinstellung auslesen...

    Moin! :)
    Ich möchte gerne aus einer PictureBox1 die Farbe auslesen, ob diese Schwarzweiß oder mit Farbe ist.
    Weiß jemand wie dies möglich ist?
    Habe leider noch keine Lösung gefunden!
    Freue mich auf eure Hilfe!
    BIG THX

    Pseudocode:

    VB.NET-Quellcode

    1. If Me.PictureBox1.FarbEinstellung = Schwarzweis Then
    2. ' Bild ist Schwarzweiß..
    3. Else
    4. ' Bild ist Farbe...
    5. End If
    Visual Basic.NET 8o
    MS-SQL
    8o
    Wusste gar nicht, dass man sowas bei der PicBox einstellen kann. Ich wär alle Pixel des Bildes durchgegangen und hätte geschaut, ob mindestens ein Buntpixel dabei ist.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    eine Picturebox hat keine Farbeinstellung. Mal wieder werden Controls und Daten durcheinandergebracht. Es ist die Bitmap, wo die Farben definiert sind. Guck dir die PixelFormat-Property an, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale ist zB ein ausgewiesenes Schwarzweiss-Format.

    (aber natürlich kann man auch alle anneren Formate als Schwarzweiss nutzen - dann muss man halt doch die Pixel alle angucken)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Du musst, denk ich, das Bild was in der PictureBox angezeigt wird auslesen!

    Das kann man mit GetPixel machen!

    Hab Dir hier mal was gebastelt, hoffe es ist das was Du suchst!

    Haupt-Klasse:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim _bmp As Bitmap
    3. Dim _col As Color
    4. Dim _color As Boolean = False
    5. Dim _gray As Boolean = False
    6. Dim _sw As Boolean = False
    7. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    8. If OpenFileDialog1.ShowDialog() = DialogResult.OK Then
    9. If IsValidImage(OpenFileDialog1.FileName) Then
    10. _bmp = New Bitmap(OpenFileDialog1.FileName)
    11. PictureBox1.Image = _bmp
    12. End If
    13. End If
    14. End Sub
    15. Function IsValidImage(filename As String) As Boolean
    16. Try
    17. Dim img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
    18. img.Dispose() ' Removes file-lock of IIS
    19. Catch generatedExceptionName As OutOfMemoryException
    20. ' Image.FromFile throws an OutOfMemoryException
    21. ' if the file does not have a valid image format or
    22. ' GDI+ does not support the pixel format of the file.
    23. Return False
    24. End Try
    25. Return True
    26. End Function
    27. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    28. If _bmp IsNot Nothing Then
    29. Label1.Text = _colorLookup(_bmp).ToString
    30. End If
    31. End Sub
    32. Public Enum IMGType
    33. BlackAndWhite = 0
    34. Grayscale = 1
    35. Color = 2
    36. End Enum
    37. Private Function _colorLookup(ByVal _bild As Bitmap) As IMGType
    38. Dim _lb As New LockBits(_bmp)
    39. For x = 0 To _lb.Width - 1
    40. For y = 0 To _lb.Height - 1
    41. Application.DoEvents()
    42. _col = _lb.Pixel(x, y)
    43. If Not (_col.R = _col.B And _col.B = _col.G) Then
    44. _color = True
    45. _sw = False
    46. _gray = False
    47. ElseIf (_col.R = 0 AndAlso _col.G = 0 AndAlso _col.B = 0) Or (_col.R = 1 AndAlso _col.G = 1 AndAlso _col.B = 1) Or
    48. (_col.R = 255 AndAlso _col.G = 255 AndAlso _col.B = 255) Or (_col.R = 254 AndAlso _col.G = 254 AndAlso _col.B = 254) Then
    49. _sw = True
    50. _gray = False
    51. _color = False
    52. Else
    53. _gray = True
    54. _color = False
    55. _sw = False
    56. End If
    57. Next
    58. Next
    59. ' Debug.WriteLine("Color= " & _color & " / SW= " & _sw & " / Gray= " & _gray)
    60. _lb.Dispose()
    61. If _color = True Then Return IMGType.Color
    62. If _sw = True Then Return IMGType.BlackAndWhite
    63. If _gray = True Then Return IMGType.Grayscale
    64. Return Nothing
    65. End Function
    66. End Class


    LockBits-Klasse:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Drawing.Imaging
    2. Imports System.Runtime.InteropServices
    3. Public Class LockBits : Implements IDisposable
    4. Public ReadOnly Bitmap As Bitmap = Nothing
    5. Private ReadOnly Iptr As IntPtr = IntPtr.Zero
    6. Private ReadOnly _BitmapData As BitmapData = Nothing
    7. Public ReadOnly BytesPerPixel As Integer
    8. Public ReadOnly Width As Integer
    9. Public ReadOnly Height As Integer
    10. Private _Pixels As Byte()
    11. Public ReadOnly Property Pixels() As Byte()
    12. Get
    13. Return _Pixels
    14. End Get
    15. End Property
    16. Public Sub New(source As Bitmap)
    17. Bitmap = source
    18. Try
    19. ' Get width and height of bitmap
    20. Width = source.Width
    21. Height = source.Height
    22. ' get total locked pixels count
    23. Dim PixelCount As Integer = Width * Height
    24. ' Create rectangle to lock
    25. Dim rect As New Rectangle(0, 0, Width, Height)
    26. ' get source bitmap pixel format size
    27. Dim Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat)
    28. BytesPerPixel = Depth \ 8
    29. ' Check if bpp (Bits Per Pixel) is 8, 24, or 32
    30. If Depth <> 8 AndAlso Depth <> 24 AndAlso Depth <> 32 Then
    31. Throw New ArgumentException("Only 8, 24 and 32 bpp images are supported.")
    32. End If
    33. ' Lock bitmap and return bitmap data
    34. _BitmapData = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat)
    35. 'Debug.WriteLine(bitmapData.Stride)
    36. ' create byte array to copy pixel values
    37. Dim [step] As Integer = Depth \ 8
    38. _Pixels = New Byte(PixelCount * [step] - 1) {}
    39. Iptr = _BitmapData.Scan0
    40. ' Copy data from pointer to array
    41. Marshal.Copy(Iptr, Pixels, 0, Pixels.Length)
    42. Catch ex As Exception
    43. Debug.WriteLine(ex.Message)
    44. End Try
    45. End Sub
    46. Public Property Pixel(x As Integer, y As Integer) As Color
    47. Get
    48. Dim i As Integer = ((y * Width) + x) * BytesPerPixel
    49. Select Case BytesPerPixel
    50. Case 4
    51. ' For 32 bpp get Red, Green, Blue and Alpha
    52. Dim b As Byte = Pixels(i)
    53. Dim g As Byte = Pixels(i + 1)
    54. Dim r As Byte = Pixels(i + 2)
    55. Dim a As Byte = Pixels(i + 3)
    56. Return Color.FromArgb(a, r, g, b)
    57. Case 3
    58. Dim b As Byte = Pixels(i)
    59. Dim g As Byte = Pixels(i + 1)
    60. Dim r As Byte = Pixels(i + 2)
    61. Return Color.FromArgb(r, g, b)
    62. Case 1
    63. Dim c As Byte = Pixels(i)
    64. Return Color.FromArgb(c, c, c)
    65. End Select
    66. Throw New InvalidOperationException(String.Concat(BytesPerPixel, " BytesPerPixel of is not supported"))
    67. End Get
    68. Set(value As Color)
    69. Dim i As Integer = ((y * Width) + x) * BytesPerPixel
    70. Select Case BytesPerPixel
    71. Case 4
    72. ' For 32 bpp get Red, Green, Blue and Alpha
    73. Pixels(i) = value.B
    74. Pixels(i + 1) = value.G
    75. Pixels(i + 2) = value.R
    76. Pixels(i + 3) = value.A
    77. Case 3
    78. ' For 24 bpp set Red, Green and Blue
    79. Pixels(i) = value.B
    80. Pixels(i + 1) = value.G
    81. Pixels(i + 2) = value.R
    82. Case 1
    83. ' For 8 bpp set color value (Red, Green and Blue values are the same)
    84. Pixels(i) = value.B
    85. End Select
    86. End Set
    87. End Property
    88. Protected Overridable Sub Dispose(disposing As Boolean)
    89. If _Pixels Is Nothing Then Return
    90. If disposing Then
    91. Marshal.Copy(Pixels, 0, Iptr, Pixels.Length)
    92. End If
    93. ' TODO: Nicht verwaltete Ressourcen (nicht verwaltete Objekte) freigeben und Finalize() unten überschreiben.
    94. Bitmap.UnlockBits(_BitmapData)
    95. ' TODO: Große Felder auf NULL festlegen.
    96. _Pixels = Nothing
    97. End Sub
    98. ' Dieser Code wird von Visual Basic hinzugefügt, um das Dispose-Muster richtig zu implementieren.
    99. Public Sub Dispose() Implements IDisposable.Dispose
    100. ' Ändern Sie diesen Code nicht. Fügen Sie oben in Dispose(disposing As Boolean) Bereinigungscode ein.
    101. Dispose(True)
    102. GC.SuppressFinalize(Me)
    103. End Sub
    104. End Class


    Also wenn die R/G/B Werte alle gleich sind kann es kein Farbbild sein, sondern nur S/W oder Graustufen!
    Wenn dann die R/G/B nur die Werte 254-255 bzw. 0-1 betragen ist es ein S/W-Bild! ;)
    Dateien
    • GetImageColor.zip

      (59,31 kB, 99 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Morrison“ ()

    Cheffboss schrieb:

    Schwarzweiß oder mit Farbe
    Meinst Du, ob Du ein monochromes oder ein farbiges Bild anzeigst?
    Das kannst das Pixelformat abfragen:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Label1.Text = Me.PictureBox1.Image.PixelFormat.ToString
    3. Label2.Text = Me.PictureBox2.Image.PixelFormat.ToString
    4. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    NoIde schrieb:

    Und was bei einem 32bpp schwarz-weissen Bild?
    Da muss @Cheffboss zunächst die Aufgabenstellung präzisieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Morrison
    1. sollte sich zunächst @Cheffboss präzise äußern, bevor wir hier den Annahmologen-Kongress mit Spekulatius eröffnen.
    2. ist es bei einem 8BPP-Bild einfacher, die Palette zu analysieren als die Pixel.
    3. kann man bei einem 24- oder 32-BPP-Bild mit hoher Wahrscheinlichkeit davon ausgehen, dass es sich um ein Farbbild handelt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @an alle
    Vielen Dank, für eure Hilfe. :)
    Ich könnte das Problem jetzt lösen!

    @Morrison
    Vielen Dank, für diesen Quellcode. :)
    Der Code läuft gut, aber leider bei größeren Bilder sehr langsam.
    Aber egal.
    Visual Basic.NET 8o
    MS-SQL
    8o
    @Cheffboss was ist denn das eigentliche Problem?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe in meiner Anwendung ein Fenster, mit einer PictureBox1.
    Wenn ein Schwarzweisbild geladen wird, sollte der Button zum Farbe werden verschwinden.
    Weil das Bild Schwarzweiß ist, und keine Farbe hat.

    Visual Basic.NET 8o
    MS-SQL
    8o
    _colorLookup() ist tw. sehr unwirtschaftlich.
    allererstes wäre, das Application.DoEvents in die äussere Schleife zu verelegen - dann wirds schoma ca. 300-fach seltener aufgerufen - und das reicht immer noch dicke.

    Dann müsste man hirnen, unter welchen Bedingungen die Schleife abgebrochen werden kann - ich würd sagen: Sobald ein farbiges Pixel gefunden ist ist alles geklärt.
    Das wird zumindest bei FarbBildern Faktor 10000 bringen - annere müssen nachwievor durchsucht werden.

    Zu überlegen wäre auch Nebenläufigkeit, um vom .DoEvents ganz wegzukommen, aber da würde man noch bisserl mehr umbauen.

    Ups - übersehen:

    Cheffboss schrieb:

    Aber egal.



    Cheffboss schrieb:

    Weil das Bild Schwarzweiß ist, und keine Farbe hat.
    Sind das 24- oder 32-BPP monochrome Bilder?
    Bei 8-BPP ist das Durchmustern der Palette bei weitem schneller.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Cheffboss Was der IrfanView da sagt ist nicht unbedingt richtig, gugst Du hier. Bilddatei mit 32 Bit per Pixel erzeugen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!