Image schnell schwarzweiß machen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
The_Dark_Zim-.-
Beiträge: 372
Registriert: 18.03.2008 16:53

Image schnell schwarzweiß machen

Beitrag 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 ;)
PB: 5.xx LTS x86/x64 | WIN: 10 Pro x64, Linux Mint x64
Benutzeravatar
DrShrek
Beiträge: 1970
Registriert: 08.09.2004 00:59

Re: Image schnell schwarzweiß machen

Beitrag 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 ;-)
Siehste! Geht doch....?!
PB*, *4PB, PetriDish, Movie2Image, PictureManager, TrainYourBrain, ...
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: Image schnell schwarzweiß machen

Beitrag 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
Benutzeravatar
The_Dark_Zim-.-
Beiträge: 372
Registriert: 18.03.2008 16:53

Re: Image schnell schwarzweiß machen

Beitrag 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
PB: 5.xx LTS x86/x64 | WIN: 10 Pro x64, Linux Mint x64
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Image schnell schwarzweiß machen

Beitrag 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
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Re: Image schnell schwarzweiß machen

Beitrag von Rings »

auch ich habe mal vor langer Zeit was gemacht,
siehe hier:

http://www.purebasic.fr/english/viewtop ... lit=effect
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
The_Dark_Zim-.-
Beiträge: 372
Registriert: 18.03.2008 16:53

Re: Image schnell schwarzweiß machen

Beitrag 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
PB: 5.xx LTS x86/x64 | WIN: 10 Pro x64, Linux Mint x64
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: Image schnell schwarzweiß machen

Beitrag 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
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Image schnell schwarzweiß machen

Beitrag 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 ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: Image schnell schwarzweiß machen

Beitrag von Kukulkan »

Ist aber noch für PB 4.20 und muss ggfs angepasst werden.
Volker
Antworten