Seite 1 von 3

Image schnell schwarzweiß machen

Verfasst: 06.05.2010 14:10
von The_Dark_Zim-.-
Hey Ho
kennt jemand eine schnelle möglichkeit ein Image schwarzweiß zu machen ?

Ich verwende im momment das hier:

Code: Alles auswählen

Procedure GrayImage() 
  If StartDrawing(ImageOutput(0))
    For y1 = 0 To ImageHeight(0)
      For x1 = 0 To ImageWidth(0)
        Farbwert.l = Point(x1, y1)
        NeuerFarbwert = Round(Red(Farbwert) * 0.56 + Green(Farbwert) * 0.33 + Blue(Farbwert) * 0.11, 0)
        Plot(x1, y1, RGB(NeuerFarbwert, NeuerFarbwert, NeuerFarbwert))
      Next x1
    Next y1
    StopDrawing()
  EndIf
EndProcedure 
Diese Verarbeitung dauert mir aber zu lange.. gibt es da nichts schnelleres ?

Gruß Zim ;)

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 14:14
von DrShrek
Sieh Dir mal das hier an: GraphicalDLL VC++ als StaticLib mit PB Wrapper:
http://www.purebasic.fr/german/viewtopi ... 6&start=30

Die Lib ist schon sehr weit...es werden nur noch ein paar Funktionen angepasst und dann sollte es soweit sein ;-)

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 14:30
von Kukulkan
Hallo,

das sollte deutlich schneller sein. Ist aber noch für PB 4.20 und muss ggfs angepasst werden. Geht auch nur unter Windows.

Code: Alles auswählen

UseJPEGImageDecoder()
UseJPEGImageEncoder()

Filename.s = "C:\Bilder\Familie\100_0620.JPG"

LoadImage(1, Filename.s); laden
BufferSize.l = ImageWidth(1) * ImageHeight(1) * 4 - 1 ; Puffergrösse berechnen
Buffer.l = AllocateMemory(BufferSize.l); speicher reservieren

GetBitmapBits_(ImageID(1), BufferSize.l, Buffer.l); Bilddaten in Speicher kopieren

; alle Bildpunkte durchgehen
For x.l = 0 To BufferSize.l Step 3
  ; alte Farbwerte auslesen
  R.l = PeekB(Buffer.l + x.l + 2) & $FF
  G.l = PeekB(Buffer.l + x.l + 1) & $FF
  B.l = PeekB(Buffer.l + x.l) & $FF
  
  Hell.l = (0.3 * R.l + 0.59 * G.l + 0.11 * B.l) ; gewichtete Helligkeit

  ; Graustufe setzen
  PokeB(Buffer.l + x.l, Hell.l)
  PokeB(Buffer.l + x.l + 1, Hell.l)
  PokeB(Buffer.l + x.l + 2, Hell.l)
  
Next

; Bilddaten in's Image zurückspeichern
SetBitmapBits_(ImageID(1), BufferSize.l, Buffer.l)

; abspeichern als jpg
SaveImage(1, Filename.s + ".conv.jpg", #PB_ImagePlugin_JPEG, 8)

End
Volker

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 14:34
von The_Dark_Zim-.-
@ DrShrek
:lol: Willst du mich umbringen
Ich will doch nur ein Image schwarzweiß machen... keine Bildbearbeitung ^^

Naja wenn keiner was anderes kennt werde ich mir das mal ansehen ;) Danke dir

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 14:42
von STARGÅTE
Hier die CustomFilterCallback-Variante:

Code: Alles auswählen

Enumeration
  #Window
  #Gadget
  #Image
EndEnumeration

Procedure ImageBrightnessCallback(x, y, TopColor, BottomColor)
  Gray = Red(TopColor)*0.56+Green(TopColor)*0.33+Blue(TopColor)*0.11
  ProcedureReturn Gray<<16+Gray<<8+Gray
EndProcedure

Procedure ImageGray(Image)
  StartDrawing(ImageOutput(Image))
    DrawingMode(#PB_2DDrawing_CustomFilter)
    CustomFilterCallback(@ImageBrightnessCallback())
    DrawImage(ImageID(Image), 0, 0)
  StopDrawing()
EndProcedure


UseJPEGImageDecoder()
UsePNGImageDecoder()

LoadImage(#Image, OpenFileRequester("", "", "", 0))
ImageGray(#Image)


OpenWindow(#Window, 0, 0, ImageWidth(#Image), ImageHeight(#Image)+20, "Image", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
  ImageGadget(#Gadget, 0, 20, ImageWidth(#Image), ImageHeight(#Image), ImageID(#Image))
  

Repeat
  Event = WaitWindowEvent()
  Select Event
   Case #PB_Event_CloseWindow
    End
  EndSelect
ForEver

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 14:44
von Rings
auch ich habe mal vor langer Zeit was gemacht,
siehe hier:

http://www.purebasic.fr/english/viewtop ... lit=effect

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 14:56
von The_Dark_Zim-.-
Ach verdammt das artet schon wieder in Arbeit aus XD Naja hilft nichts, dann muss ich wohl mal Testen was am schnellsten ist ;) Ich sag euch dann auf welches Ergebniss ich gekommen bin :P

THX

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 15:07
von Kukulkan
Hi,

meine oben gepostete Version (welche keine weitere DLL benötigt) braucht bei mir für ein 4 MegaPixel Bild (15MB Daten) schlappe 160 Millisekunden (Athlon II X4 620). [EDIT] Ein 6 MegaPixel Bild brauchte 218 Millisekunden. [/EDIT]

Gekürzte Version:

Code: Alles auswählen

Procedure GrayScale(ImageNumber.l)
  ; Wandelt das übergebene Image (die ImageNummer von zB LoadImage()) in Graustufen
  Protected BufferSize.l
  Protected Buffer.l
  Protected x.l
  Protected Hell.l
  
  BufferSize.l = ImageWidth(ImageNumber.l) * ImageHeight(ImageNumber.l) * 4 - 1 ; Puffergrösse berechnen
  Buffer.l = AllocateMemory(BufferSize.l); speicher reservieren
  
  GetBitmapBits_(ImageID(ImageNumber.l), BufferSize.l, Buffer.l); Bilddaten in Speicher kopieren
  
  For x.l = 0 To BufferSize.l Step 3
    
    R.l = PeekB(Buffer.l + x.l + 2) & $FF
    G.l = PeekB(Buffer.l + x.l + 1) & $FF
    B.l = PeekB(Buffer.l + x.l) & $FF
    
    Hell.l = (0.3 * R.l + 0.59 * G.l + 0.11 * B.l) ; 0 bis 255
    
    PokeB(Buffer.l + x.l, Hell.l)
    PokeB(Buffer.l + x.l + 1, Hell.l)
    PokeB(Buffer.l + x.l + 2, Hell.l)
    
  Next
  
  SetBitmapBits_(ImageID(ImageNumber.l), BufferSize.l, Buffer.l)

  FreeMemory(Buffer.l)
  
EndProcedure
Einfacher gehts (glaub ich) nicht mehr.

Volker

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 16:28
von STARGÅTE
Aber wieso nimmst du
PeekB(Buffer.l + x.l) & $FF

Das ist doch überflüssig:

Dafür gibs Doch PeekA(Buffer.l + x.l)
Um eine UnSign-Byte auszulesen !

Somit wäre es noch einfacher ^^

Re: Image schnell schwarzweiß machen

Verfasst: 06.05.2010 16:57
von Kukulkan
Ist aber noch für PB 4.20 und muss ggfs angepasst werden.
Volker