[gelöst] 24-Bit in Graustufen wandeln

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

[gelöst] 24-Bit in Graustufen wandeln

Beitrag von Sebastian »

Hallo!
Wie kann man ein 24bit Farbbild in ein Graustufenbild wandeln? Geht das auch in Echtzeit?
Zuletzt geändert von Sebastian am 30.11.2007 20:47, insgesamt 1-mal geändert.
(Win 11 64-bit, PB 6.04 und 6.10)
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: 24-Bit in Graustufen wandeln

Beitrag von Kiffi »

Sebastian hat geschrieben:Wie kann man ein 24bit Farbbild in ein Graustufenbild wandeln?
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

Beitrag von Sebastian »

Hallo Kiffi!
Vielen Dank für Deine schnelle Antwort! Ja, auf die Idee bin ich natürlich auch gekommen. Jedoch wird hier jeder Pixel ausgelesen und dann einzeln wieder geschrieben. Für Echtzeit-Anwendung einfach zu langsam. Gibt es noch ne andere Möglichkeit, die eventuell schneller ist?
(Win 11 64-bit, PB 6.04 und 6.10)
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Wenn du den Code da oben so umprogrammierst, dass er mit Memory statt Sprites arbeitet, dann müsste die Geschwindigkeit für Echtzeit ausreichen.
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

Beitrag von Sebastian »

Achtung: Anfänger-Board!
Also: Ich lade ein Sprite in den Speicher. Das habe ich ja getan, sobald ich loadsprite() eingegeben habe. Und dann soll ich direkt auf diesen Speicher zugreifen und kann dann Operationen durchführen? Wie geht das? Und dann muss ich das Ganze ja auch noch wieder ausgeben. Dann kann ich aber ja nicht displaysprite() verwenden, oder?
(Win 11 64-bit, PB 6.04 und 6.10)
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Beitrag von Rings »

Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Beitrag von Rings »

Fürn ganzen Screen isses allerdings immer noch recht langsam.
da kann man sicherlich bessern.

Code: Alles auswählen

;
If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Can't open DirectX 7 Or later", 0)
  End
EndIf

If InitSprite3D() = 0
  MessageRequester("Error", "Direct3D system can't be initialized correctly", 0)
  End
EndIf


Procedure ScreenGray(xOffset,yOffset,IW,IH)
;xOffset=0
;yOffset=0
;grays a screen
 StartDrawing(ScreenOutput())
 
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 *pxData1.LONG
 PixelFormat=DrawingBufferPixelFormat()
 
 Select PixelFormat
  Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
   ByteOffset=1
  Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
   ByteOffset=3
  Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
   ByteOffset=3
  Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
   ByteOffset=4
  Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
   ByteOffset=4
 EndSelect

 For Lines=xOffset To IH-1
  *pxData1 = Buffer + (Lines*pitch) + (yOffset*Byteoffset)
  
  For t=yOffset To IW-1
   m=*pxData1\l
 
   Select Pixelformat
    Case #PB_PixelFormat_16Bits

    Case #PB_PixelFormat_24Bits_BGR,#PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
     
   ;  p=m >> 24 & $FF ;the additive alpha
     r= m >> 16 & $FF
     g= m >> 8 & $FF
     b= m  & $FF
     gray=((r*29)+(g*58)+(b*11))/100
     m=   gray | gray << 8 | gray << 16 ;| p << 24

    Case #PB_PixelFormat_24Bits_RGB,#PB_PixelFormat_32Bits_RGB
     ;p=m >> 24 & $FF ;the additive alpha
     b= m >> 16 & $FF
     g= m >> 8 & $FF
     r= m  & $FF
     gray=((r*29)+(g*58)+(b*11))/100
     m=   gray | gray << 8 | gray << 16 ;| p << 24

   EndSelect
     
   *pxData1\l=m
   *pxData1 + ByteOffset
  Next
 Next
 StopDrawing()
 
EndProcedure 


;
; Now, open a 640*480 - 16 bits (65000 colours) screen
;
IW=640
IH=480
Depth=32

If OpenScreen(IW, IH, Depth, "Sprite")

  ; Load our 16 bit sprite (which is a 24 bit picture in fact, as BMP doesn't support 16 bit format)
  ; 
  LoadSprite(0, "Data\Geebee2.bmp", #PB_Sprite_Texture)
  CreateSprite3D(0, 0)
  CreateSprite3D(1, 0)
  CreateSprite3D(2, 0)
  
  Sprite3DQuality(1)
  
  TransparentSpriteColor(0, RGB(255, 0, 255)) ; Our pink is transparent :)

  Repeat
    
    ; Inverse the buffers (the back become the front (visible)... And we can do the rendering on the back)
    
    ;StartSpecialFX()
    
    ScreenGray(70,70,400,300)
    ;StopSpecialFX()
    
    FlipBuffers()
    
    ClearScreen(RGB(0,50,128))
    
    ; Draw our sprite
    ;
    If Start3D()
      DisplaySprite3D(0, 0, 30)
      DisplaySprite3D(0, x+100, 100, x)
      DisplaySprite3D(0, x*2, 100, x)

      ; Zoom..
      ;
      ZoomSprite3D(1, x, x)
      RotateSprite3D(1, x, 0)
      DisplaySprite3D  (1, 0, 100, x/2)
      DisplaySprite3D  (1, x*2, 100, x)
      DisplaySprite3D  (1, 0, 100, x/2)
      DisplaySprite3D  (1, x*2, 200+x, x)
      
      Stop3D()
    EndIf
    
    ExamineKeyboard()
    
    x+1
  Until x > 500 Or KeyboardPushed(#PB_Key_Escape)
  
Else
  MessageRequester("Error", "Can't open a 640*480 - 16 bit screen !", 0)
EndIf

End   
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

Beitrag von Sebastian »

Ich habe mir das Beispiel angesehen und versucht zu verstehen. Wenn ich es richtig sehe, dann wird auf den Videospeicher zugegriffen und die Farben in Graustufen umgewandelt. Das ist super, denn genau das will ich -> ABER ich will nicht, dass die ursprüngliche Grafik verändert wird, sie soll nur in Graustufen wiedergegeben werden, auf dem selben Bildschirm soll sie aber an anderer Stelle in Farbe zu sehen sein. Desweiteren wird die Grafik bei jedem Aufruf der Funktion nochmals abgearbeitet, so dass sie nach kurzer Zeit einfach nur schwarz ist. Auch dies ist nicht gewünscht!
(Win 11 64-bit, PB 6.04 und 6.10)
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Beitrag von Rings »

Sebastian hat geschrieben:Ich habe mir das Beispiel angesehen und versucht zu verstehen. Wenn ich es richtig sehe, dann wird auf den Videospeicher zugegriffen und die Farben in Graustufen umgewandelt. Das ist super, denn genau das will ich -> ABER ich will nicht, dass die ursprüngliche Grafik verändert wird, sie soll nur in Graustufen wiedergegeben werden, auf dem selben Bildschirm soll sie aber an anderer Stelle in Farbe zu sehen sein. Desweiteren wird die Grafik bei jedem Aufruf der Funktion nochmals abgearbeitet, so dass sie nach kurzer Zeit einfach nur schwarz ist. Auch dies ist nicht gewünscht!
na denn wünsch ich dir mal viel spass beim tüfteln.
und schau dir alles einmal richtig an.
evtl. gehen dir dann deine Augen auf und du siehst nimmer
nur Schwarz&weiß ;)
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

Beitrag von Sebastian »

Ich verstehe nicht worauf Du hinaus willst. Vieleicht magst Du das ein oder andere zum Quellcode sagen? Ich möchte die Grafik auch nicht doppelt im Videoram haben, deshalb wollte ich ja direkt bei der Ausgabe ansetzen.
(Win 11 64-bit, PB 6.04 und 6.10)
Antworten