24 Bit BMP nach Farbe dursuchen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Tompazi
Beiträge: 211
Registriert: 22.09.2007 15:38

24 Bit BMP nach Farbe dursuchen

Beitrag von Tompazi »

Ich will in meinem screen nach einer bestimmten Farbe suchen und die X und Y Koordinate des ersten Pixels dieser Farbe haben.
Mit hilfe von Wikipedia hab ich mir diesen Code zusammengereimt.
Ich bekomme aber immer "0|0" zurück egal mit welcher Farbe.
http://de.wikipedia.org/wiki/Windows_Bitmap

Code: Alles auswählen

Procedure.s FindColorInScreen(Color)
 Structure Pixel
   x.l
   y.l
   r.c
   b.c
   g.c
  EndStructure
  NewList Pixel.Pixel()

;ScreenShot 
CreateImage(0,GetSystemMetrics_(#SM_CXSCREEN),GetSystemMetrics_(#SM_CYSCREEN)) 
 HDC = StartDrawing(ImageOutput(0)) 
 BitBlt_(HDC,0,0,ImageWidth(0),ImageHeight(0),GetDC_(GetDesktopWindow_()),0,0,#SRCCOPY ) 
 SaveImage(0,"temp.bmp")
 OpenFile(0,"temp.bmp")
 FreeImage(0)
 For a = 0 To 53 ;Header
  ReadByte(0)
 Next a

  ReadByte(0) ;überflüssiges Byte o.O
 
;BGR!! Blue Green Red? wtf
 Repeat
  AddElement(Pixel())
   b = ReadByte(0)
   If b = 0 ;Next line?
    y = y + 1
    b = ReadByte(0)
   ElseIf b = 1 ;EndofBitmap?
    Break
   EndIf
   Pixel()\b = b
   Pixel()\g = ReadByte(0)
   Pixel()\r = ReadByte(0)
   Pixel()\x = x
   Pixel()\y = y
   x + 1
  Until Not ReadByte(0)

  CloseFile(0)
  DeleteFile("temp.bmp")

  ForEach Pixel()
   PixelColor = RGB(Pixel()\r,Pixel()\g,Pixel()\b)
   If PixelColor = Color
    Break
   EndIf
  Next

  ProcedureReturn Str(Pixel()\x) + "|" + Str(Pixel()\y)

 EndProcedure
 Debug FindColorInScreen(RGB(255,255,223))

MfG Tompazi

ps: bin mir nicht sicher ob das hier reingehört wenn nicht, bitte verschieben.

//EDIT
Einige Fehler gefunden er gibt mir zwar vernünftige Koordinaten zurück aber die stimmen eindeutig nicht.

Code: Alles auswählen

 Procedure.s FindColorInScreen(Color)
 Structure Pixel
   x.l
   y.l
   r.c
   b.c
   g.c
  EndStructure
  NewList Pixel.Pixel()

;ScreenShot
CreateImage(0,GetSystemMetrics_(#SM_CXSCREEN),GetSystemMetrics_(#SM_CYSCREEN))
 HDC = StartDrawing(ImageOutput(0))
 BitBlt_(HDC,0,0,ImageWidth(0),ImageHeight(0),GetDC_(GetDesktopWindow_()),0,0,#SRCCOPY )
 SaveImage(0,"temp.bmp")
 FreeImage(0)

 OpenFile(0,"temp.bmp")
 
 For a = 0 To 16 ;Header
  ReadByte(0)
 Next a
  Width = ReadByte(0)
  Width = Width + (16 * ReadByte(0))
  Width = Width + (256 * ReadByte(0))
  Width = Width + (4096 * ReadByte(0))
  Height = ReadByte(0)
  Height = Height + (16 * ReadByte(0))
  Height = Height + (256 * ReadByte(0))
  Height = Height + (4096 * ReadByte(0))
  Debug Width
  Debug Height
  y = Height
  
 For a = 26 To 53 ;Header
  ReadByte(0)
 Next a
 
;BGR!! Blue Green Red? wtf
 For ky = 0 To Height
  For kx = 0 To Width
  AddElement(Pixel())
   Pixel()\b = b = ReadByte(0)
   Pixel()\g = ReadByte(0)
   Pixel()\r = ReadByte(0)
   Pixel()\x = x
   Pixel()\y = y
   x + 1
  Next kx
  x = 0
  y = y - 1
 Next ky

  CloseFile(0)
  DeleteFile("temp.bmp")

  ForEach Pixel()
   PixelColor = RGB(Pixel()\r,Pixel()\g,Pixel()\b)
   If PixelColor = Color
    Break
   EndIf
   
  Next

  ProcedureReturn Str(Pixel()\x) + "|" + Str(Pixel()\y)

 EndProcedure
 Debug FindColorInScreen(RGB(255,0,0))
MfG Tompazi
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8835
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Wieso lädst du das Bild nicht mit 'LoadImage()' und rennst mit 'Point()' über das Bild?
Sahrin
Beiträge: 10
Registriert: 24.11.2008 20:12
Wohnort: Rostock
Kontaktdaten:

Beitrag von Sahrin »

Hmm ich hab zwar nix grade hier (Firmanerechner) um den Code zu überprüfen und bin noch recht neu hier..

Aber könnts vlt hier dran liegen:

Code: Alles auswählen

y = Height     ;<--- Hier Oben sezt du Y auf Height
 
 For a = 26 To 53 ;Header
  ReadByte(0)
 Next a 

 For ky = 0 To Height   <----- Du fängst hier in der ersten auf der ersten linie an also oben,
  For kx = 0 To Width
  AddElement(Pixel())
   Pixel()\b = b = ReadByte(0)
   Pixel()\g = ReadByte(0)
   Pixel()\r = ReadByte(0)
   Pixel()\x = x
   Pixel()\y = y <--- Dein Y ist hier aber noch ganz unten also Hieght?
   x + 1
  Next kx
  x = 0
  y = y - 1    <---- Hier unten Ziehst du von Y Ab Welches oben Auf Height gesezt wurde..
 Next ky 
Rein von der Optik des Codes würd ich sagen du liest das Bild von oben nach unten aber deine Y wert geht von unten nach oben?

Vlt klapts so besser :

Code: Alles auswählen

 For ky = 1 To Height   
  For kx = 1 To Width
  AddElement(Pixel())
   Pixel()\b = b = ReadByte(0)
   Pixel()\g = ReadByte(0)
   Pixel()\r = ReadByte(0)
   Pixel()\x = kx
   Pixel()\y = ky
   
  Next kx   
 Next ky 
Mag sein Das ich mich dabei auch Irre, wie gesagt setz mich erst seit kurzem damit auseinader.. Aber wenn ich was durchforsten will bzw zuweisen mach ich es auf diese Art.

MfG Sahrin alias Jan
Nichts schührt Hass wie die Warheit

PB Version - 3.30
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

Ich versteh denn Sinn auch nicht wirklich ... du erstelltst dir zu beginn
doch sogar ein Image und führst StartDrawing() aus ... was hält dich nun
davon ab, mit Point() durch das Image zu wandern?

Mal davon abgesehen verwendest du "kx" und "ky" zum durchlaufen, aber
du ließt von "x" und "y" aus, die aber nicht verändert werden :wink:

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten