VB6 Zugriff auf BMP

Hallo,
wie kann ich von einem BMP auf der Festplatte die RGB Werte von einzelnen Pixeln auslesen?

Ich habe es mal hinbekommen in dem ich das Bild in eine Picturebox geladen haben und per .POINT die Werte für R, G, B extrahiert habe…

Ich benötige aber etwas schnelleres… besser wäre es also direkt auf das BMP als Datei zugreifen zu können…

Hallo,

wie kann ich von einem BMP auf der Festplatte die RGB Werte
von einzelnen Pixeln auslesen?

Bedingt ja, aber das ist sehr aufwändig. Du musst zunächst den Header analysieren und erst mal feststellen, wie das Bild in der datei steht, denn das ist nicht immer gleich. Wenn Du dann ermittelst, daß die Bytes mit einem Integer adressierbar sind, kannst Du darauf zugreifen, sonst mußt Du so oder so die ganze Datei lesen.

Wie der Header aufgebaut ist und wie Du da lesen kannst, wie die Struktur der Datei aussieht findest Du bei Wikipedia.

http://de.wikipedia.org/wiki/Windows_Bitmap

Ich wollte das auch mal versuchen, hab’s aber aufgegeben.

Ich habe es mal hinbekommen in dem ich das Bild in eine
Picturebox geladen haben und per .POINT die Werte für R, G, B
extrahiert habe…

Ich benötige aber etwas schnelleres… besser wäre es also
direkt auf das BMP als Datei zugreifen zu können…

OK, Point ist natürlich sehr langsam.
Ich würde die Datei wirklich in ein Bitmap laden und das mit GetBitmapBits in ein Bytearray laden. Auf die Bytes dieses Arrays zugreifen geht sehr viel schneller als die Pixel mit Point zu lesen.

Ein Beispielcode aus APIGuide:

'Create a new project, add a command button and a picture box to the project, load a picture into the picture box.
'Paste this code into Form1

Private Type BITMAP
 bmType As Long
 bmWidth As Long
 bmHeight As Long
 bmWidthBytes As Long
 bmPlanes As Integer
 bmBitsPixel As Integer
 bmBits As Long
End Type
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Dim PicBits() As Byte, PicInfo As BITMAP
Dim Cnt As Long, BytesPerLine as Long
Private Sub Command1\_Click()
 'KPD-Team 1999
 'URL: http://www.allapi.net/
 'E-Mail: [email protected]
 'Get information (such as height and width) about the picturebox
 GetObject Picture1.Image, Len(PicInfo), PicInfo
 'reallocate storage space
 BytesPerLine = (PicInfo.bmWidth \* 3 + 3) And &HFFFFFFFC
 ReDim PicBits(1 To BytesPerLine \* PicInfo.bmHeight \* 3) As Byte
 'Copy the bitmapbits to the array
 GetBitmapBits Picture1.Image, UBound(PicBits), PicBits(1)
 'Invert the bits
 For Cnt = 1 To UBound(PicBits)
 PicBits(Cnt) = 255 - PicBits(Cnt)
 Next Cnt
 'Set the bits back to the picture
 SetBitmapBits Picture1.Image, UBound(PicBits), PicBits(1)
 'refresh
 Picture1.Refresh
End Sub

Gruß Rainer

Ok, danke. Das schau ich mir mal an.

Es sollen hinterher zwei Frames, von mir codieren Videos, auf Unterschiede vergleichen werden, bzw. eine Differenzbild erstellt werden.

Hab das schon mal für „SD Video“ gemacht, da passen ja auch zwei PixBoxen mit 720x576 in die Form, mit zwei mal 1920x1080… naja. Der große Knackpunkt war halt noch der Speed der .point Funktion.

Muss mir das mal in Ruhe reinziehen…

Falls Du nicht das ganze Bild brauchst, sondern nur ein Ausschnitt ausgewertet werden soll, schrumpft die Datenmenge und es wird schneller.

 Picture2.PaintPicture Picture1.Picture, 0, 0, \_
 Picture1.ScaleWidth / 2, Picture1.ScaleHeight / 2, 0, 0, \_
 Picture1.ScaleWidth / 2, Picture1.ScaleHeight / 2

Das Bild in Picture2 hat nur noch ein Viertel so viel Pixel wie Picture1. :smile:

Gruß Rainer

Hi,

Es sollen hinterher zwei Frames, von mir codieren Videos, auf
Unterschiede vergleichen werden, bzw. eine Differenzbild
erstellt werden.

Da ist mir noch etwas durch den Kopf gegangen.
Um ein Differenzbild zu bekommen, musst Du doch nichts selbst rechnen …

Sieh Dir das mal an:

Option Explicit

Private Sub Command1\_Click()
 Picture2.PaintPicture Picture1.Picture, 0, 0, \_
 Picture1.ScaleWidth / 2, Picture1.ScaleHeight / 2, 0, 0, \_
 Picture1.ScaleWidth / 2, Picture1.ScaleHeight / 2
End Sub

Private Sub Command2\_Click()
 Picture2.PaintPicture Picture1.Picture, 0, 0, \_
 Picture1.ScaleWidth / 2, Picture1.ScaleHeight / 2, 0, 0, \_
 Picture1.ScaleWidth / 2, Picture1.ScaleHeight / 2, vbSrcInvert
End Sub

Weil hier die Quellen identisch sind, wird das Bild schwarz, alle Bits sind Null. Das kann man natürlich auch noch invgertieren, dann wird die Fläche weiß. Bei fast identischen Bildern bleiben nur die Differenzen übrig.

Gruß Rainer