SetBits / GetBits gut genug?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SetBits / GetBits gut genug?

Beitrag von mk-soft »

Eigentlich sind die Drawing Funktionen von PB schon sehr schnell
und man kann mit CustomFilterCallback so einiges gut umsetzen...

Beispiel Bild im Grauton wandeln.

Update 4k Pictures

Code: Alles auswählen


;-TOP

; ***************************************************************************************

; Comment   : 
; Author    : mk-soft
; File      : 
; Version   : v1.0
; Date      : 

; ***************************************************************************************


EnableExplicit

UseJPEGImageDecoder()
UsePNGImageDecoder()

; Fenster
Enumeration
  #Main
EndEnumeration

; Gadgets
Enumeration
  #ScrollArea
  #Canvas
EndEnumeration

Global exit

Procedure ScaleGrayCallback(x, y, SourceColor, TargetColor)
  Protected light
  light = ((Red(TargetColor) * 30 + Green(TargetColor) * 59 + Blue(TargetColor) * 11) / 100)
  ProcedureReturn RGBA(light, light, light, 255)
EndProcedure

Procedure Draw(image)
  
  Protected x, y, dx, dy, time
  
  dx = GadgetWidth(#Canvas)
  dy = GadgetHeight(#Canvas)
  
  time = ElapsedMilliseconds()
  If StartDrawing(CanvasOutput(#Canvas))
    
    DrawImage(ImageID(image), 0, 0, dx, dy)
    
    DrawingMode(#PB_2DDrawing_CustomFilter)
    CustomFilterCallback(@ScaleGrayCallback())
    
    Box(0, 0, dx, dy)
    
    StopDrawing()
    
  EndIf
  time = ElapsedMilliseconds() - time
  MessageRequester("Time", "" + time + "ms")
EndProcedure

Procedure Main()
  
  Protected Event, file.s, image
  
  If OpenWindow(#Main, #PB_Any, #PB_Any, 1024, 768, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    
    file = OpenFileRequester("Picture", "", "", 0)
    If file
      image = LoadImage(#PB_Any, file)
    Else
      End
    EndIf
    
    ScrollAreaGadget(#ScrollArea, 0, 0, WindowWidth(#Main), WindowHeight(#main), 3840, 2160)
    CanvasGadget(#Canvas, 0, 0, 3840, 2160)
    CloseGadgetList()
      
    Draw(image)
    
    Repeat
      Event = WaitWindowEvent()
      
      Select Event
          
        Case #PB_Event_CloseWindow
          exit = #True
          
      EndSelect
      
    Until exit
    
  EndIf
    
EndProcedure : Main()
Zuletzt geändert von mk-soft am 28.10.2018 22:39, insgesamt 1-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

juergenkulow hat geschrieben: Noch eine Frage: Warum sind die Farben gleich gewichted? (#COLOR_DIV, #COLOR_FAC,#COLOR_SEG) Das ist irgentwie ungewöhnlich.
Gruß
Das sind nur Platzhalter für den Post, die einzelnen Farbwerte werden gewichtet.
Eine einfachere Gewichtung ist leider nicht möglich da sonst die Bildqualität bei 3 Bit Graustufen zu stark leidet.
Benutzeravatar
juergenkulow
Beiträge: 188
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: SetBits / GetBits gut genug?

Beitrag von juergenkulow »

Bei der CustomFilterCallback(@ScaleGrayCallback()) Lösung komme ich bei einem 4k Bild zwischen StartDrawing und StopDrawing auf eine Laufzeit von 3,794 Sekunden.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SetBits / GetBits gut genug?

Beitrag von mk-soft »

Habe mal mein Beispiel auf 4k Bilder umgebaut.

Ohne debugger bei mir 764ms

OS Host: MacOS
CPU: Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz
Time 764ms

OS Virtual Machine: Window 7 Pro
Time:2800ms

OS Virtual Machine: Ubuntu Budgie 18.04.1
Time: 1900ms
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

Meine Änderungen zum geposteten Code:
- Set/GetBits als Macro
- Umwandlung zu Graustufen als Macro

4K @ ~ 300 ms (ohne Debugger) ~ 5800 (mit Debugger)

Dabei wird das Bild in Graustufen umgewandelt und der 3-Bit Buffer erstellt.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SetBits / GetBits gut genug?

Beitrag von mk-soft »

Mijikai hat geschrieben:Meine Änderungen zum geposteten Code:
- Set/GetBits als Macro
- Umwandlung zu Graustufen als Macro

4K @ ~ 300 ms (ohne Debugger) ~ 5800 (mit Debugger)

Dabei wird das Bild in Graustufen umgewandelt und der 3-Bit Buffer erstellt.
Kannst du mal ein kompletten Testcode mit Ausgabe schreiben. Kannst ja mein Code als Basis nehmen.
So kann man es nicht vergleichen, denn nur das wandeln in Grauton lauter bei mir unter 300ms.
Ausserdem möchte ich mal schauen wie das Ergebnis in Grauton ist.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
juergenkulow
Beiträge: 188
Registriert: 22.12.2016 12:49
Wohnort: :D_üsseldorf-Wersten

Re: SetBits / GetBits gut genug?

Beitrag von juergenkulow »

Code: Alles auswählen

; Testumgebung CustomFilterCallback - so wie sie jetzt ist. - Auf eigene Gefahr. - experimental
UseJPEGImageDecoder()
UsePNGImageEncoder()
Structure bit64 : LowPart.l : HighPart.l : EndStructure 
Structure CPUZeitTyp : StructureUnion : Ticks.bit64 : q.q : EndStructureUnion :EndStructure
Structure RGBATyp : StructureUnion : l.l : a4.a[4] : EndStructureUnion : EndStructure
Structure mixTyp : StructureUnion : a.a : u.u : l.l : q.q : EndStructureUnion : EndStructure

Macro setBits(ptr,BitFeldIndex,Wert) ; Wert kleiner $100  Vari BitOffset, Bitptr, *p
  BitOffset=BitFeldIndex&$7
  Bitptr=BitFeldIndex>>3
  *p=ptr+Bitptr
  *p\u=*p\u | ((Wert)<<BitOffset)
EndMacro

Macro getBits(ptr,BitFeldIndex,Anzahl,Ziel) ;Anzahl <=8 Vari BitOffset, Bitptr, *p
  BitOffset=BitFeldIndex&$7
  Bitptr=BitFeldIndex>>3
  *p=ptr+Bitptr
  Ziel=(*p\u & (($ff>>(8-Anzahl))<<Bitoffset))>>Bitoffset
EndMacro 

Global *mem.mixTyp,*p.mixTyp,BitOfsset,Bitptr,Bfi=0  

DisableDebugger
Procedure ScaleGrayCallback(x, y, SourceColor, TargetColor)
  Protected light
   light = ((Red(TargetColor) * 30 + Green(TargetColor) * 59 + Blue(TargetColor) * 11) / 100)
   light = light & $E0 ; letzte 5 bit löschen.
   ProcedureReturn RGBA(light, light, light, 255)
;  ProcedureReturn $FF000000
 EndProcedure
 ; Win64 pbcompiler --commented Ausgabe:
; ; Procedure ScaleGrayCallback(x, y, SourceColor, TargetColor)
; _Procedure0:
;   MOV    qword [rsp+8],rcx
;   MOV    qword [rsp+16],rdx
;   MOV    qword [rsp+24],r8
;   MOV    qword [rsp+32],r9
;   PUSH   r15
;   PUSH   r14
;   PS0=80
;   XOr    rax,rax
;   PUSH   rax
;   PUSH   rax
;   SUB    rsp,40
; ; Protected light
; ; light = ((Red(TargetColor) * 30 + Green(TargetColor) * 59 + Blue(TargetColor) * 11) / 100)
;   PUSH   qword [rsp+PS0+24]
;   POP    rcx
;   CALL   PB_Red
;   MOV    r15,rax
;   IMUL   r15,30
;   PUSH   qword [rsp+PS0+24]
;   POP    rcx
;   CALL   PB_Green
;   MOV    r14,rax
;   IMUL   r14,59
;   ADD    r15,r14
;   PUSH   qword [rsp+PS0+24]
;   POP    rcx
;   CALL   PB_Blue
;   MOV    r14,rax
;   IMUL   r14,11
;   ADD    r15,r14
;   MOV    rax,r15
;   MOV    rcx,100
;   CQO
;   IDIV   rcx
;   MOV    r15,rax
;   MOV    qword [rsp+40],r15
; ; ProcedureReturn RGBA(light, light, light, 255)
;   PUSH   qword 255
;   PUSH   qword [rsp+48]
;   PUSH   qword [rsp+56]
;   PUSH   qword [rsp+64]
;   POP    rcx
;   POP    rdx
;   POP    r8
;   POP    r9
;   CALL   PB_RGBA
;   JMP   _EndProcedure1
; ; 
; ; EndProcedure
; _EndProcedureZero1:
;   XOr    rax,rax
; _EndProcedure1:
;   ADD    rsp,56
;   POP    r14
;   POP    r15
;   RET
 
 Procedure myScaleGrayCallback(x, y, SourceColor, TargetColor) ; Ist nötig für jede RGBA-Kombination
  Protected *TargetFarbe.RGBATyp=@TargetColor
  Protected light.a,retwert
  Protected *p_rot.Ascii=?roteFarbe+*TargetFarbe\a4[0] 
  Protected *p_gruen.Ascii=?grueneFarbe+*TargetFarbe\a4[1]
  Protected *p_blau.Ascii=?blaueFarbe+*TargetFarbe\a4[2]
  light=(*p_rot\a+*p_gruen\a+*p_blau\a) & $E0 ; nur die ersten 3 Bits 
  ; offen Bits in Speicher schreiben 
  retwert=$ff000000+light*$10101 
  setBits(*mem,Bfi,light>>5) : Bfi+3 
  ProcedureReturn retwert
EndProcedure
 ; Win64 pbcompiler --commented Ausgabe:
; Procedure myScaleGrayCallback(x, y, SourceColor, TargetColor) 
; _Procedure2:
;   MOV    qword [rsp+8],rcx
;   MOV    qword [rsp+16],rdx
;   MOV    qword [rsp+24],r8
;   MOV    qword [rsp+32],r9
;   PUSH   rbp
;   PUSH   r15
;   PUSH   r14
;   PS2=128
;   MOV    rax,7
; .ClearLoop:
;   SUB    rsp,8
;   MOV    qword [rsp],0
;   DEC    rax
;   JNZ   .ClearLoop
;   SUB    rsp,40
; ; Protected *TargetFarbe.RGBATyp=@TargetColor
;   LEA    rax,[rsp+PS2+24]
;   MOV    rax,rax
;   PUSH   rax
;   POP    rax
;   MOV    qword [rsp+40],rax
; ; Protected light.a,retwert
; ; Protected *p_rot.Ascii=?roteFarbe+*TargetFarbe\a4[0] 
;   MOV    rbp,ll_myscalegraycallback_rotefarbe
;   MOV    r15,rbp
;   MOV    rbp,qword [rsp+40]
;   PUSH   rbp
;   POP    rbp
;   MOVZX  rax,byte [rbp]
;   ADD    r15,rax
;   MOV    qword [rsp+64],r15
; ; Protected *p_gruen.Ascii=?grueneFarbe+*TargetFarbe\a4[1]
;   MOV    rbp,ll_myscalegraycallback_gruenefarbe
;   MOV    r15,rbp
;   MOV    rbp,qword [rsp+40]
;   PUSH   rbp
;   POP    rbp
;   MOVZX  rax,byte [rbp+1]
;   ADD    r15,rax
;   MOV    qword [rsp+72],r15
; ; Protected *p_blau.Ascii=?blaueFarbe+*TargetFarbe\a4[2]
;   MOV    rbp,ll_myscalegraycallback_blauefarbe
;   MOV    r15,rbp
;   MOV    rbp,qword [rsp+40]
;   PUSH   rbp
;   POP    rbp
;   MOVZX  rax,byte [rbp+2]
;   ADD    r15,rax
;   MOV    qword [rsp+80],r15
; ; light=(*p_rot\a+*p_gruen\a+*p_blau\a) & $E0 
;   MOV    rbp,qword [rsp+64]
;   MOVZX  r15,byte [rbp]
;   MOV    rbp,qword [rsp+72]
;   MOVZX  rax,byte [rbp]
;   ADD    r15,rax
;   MOV    rbp,qword [rsp+80]
;   MOVZX  rax,byte [rbp]
;   ADD    r15,rax
;   And    r15,224
;   MOV    rax,r15
;   PUSH   rax
;   POP    rax
;   MOV    byte [rsp+48],al
; ; 
; ; retwert=$ff000000+light*$10101 
;   MOVZX  r15,byte [rsp+48]
;   IMUL   r15,65793
;   MOV    rax,4278190080
;   ADD    r15,rax
;   MOV    qword [rsp+56],r15
; ; setBits(*mem,Bfi,light>>5) : Bfi+3 
;   MOV    r15,qword [v_Bfi]
;   And    r15,7
;   MOV    qword [rsp+88],r15
;   MOV    r15,qword [v_Bfi]
;   SAR    r15,3
;   MOV    qword [v_Bitptr],r15
;   MOV    r15,qword [p_mem]
;   ADD    r15,qword [v_Bitptr]
;   MOV    qword [p_p],r15
;   MOV    rbp,qword [p_p]
;   MOVZX  r15,word [rbp]
;   MOVZX  r14,byte [rsp+48]
;   SAR    r14,5
;   MOV    rcx,qword [rsp+88]
;   SAL    r14,cl
;   Or     r15,r14
;   MOV    rax,r15
;   PUSH   rax
;   MOV    rbp,qword [p_p]
;   POP    rax
;   MOV    word [rbp],ax
;   MOV    r15,qword [v_Bfi]
;   ADD    r15,3
;   MOV    qword [v_Bfi],r15
; ; ProcedureReturn retwert
;   MOV    rax,qword [rsp+56]
;   JMP   _EndProcedure3
; ; EndProcedure
; _EndProcedureZero3:
;   XOr    rax,rax
; _EndProcedure3:
;   ADD    rsp,96
;   POP    r14
;   POP    r15
;   POP    rbp
;   RET

EnableDebugger

Procedure Mainneu()
  
  Protected x, y, image, myimage, tiefe,T0.CPUZeitTyp,T1.CPUZeitTyp,RegRDX,Start
  CompilerIf #PB_OS_Windows =#PB_Compiler_OS
    Protected vm=VirtualAlloc_(#Null,4096,#MEM_COMMIT,#PAGE_EXECUTE_READWRITE)
  Protected *p.Ascii=vm
  *p\a=$C3
  CompilerEndIf
  Dateiname.s="R:\tiger.jpg"
  If FileSize(Dateiname)<=0 : Dateiname=OpenFileRequester("Bild","*.jpg","JPG *.jpg|*.jpg",0) : EndIf 
  image=LoadImage(#PB_Any,Dateiname)
  x=ImageWidth(image) 
  y=ImageHeight(image) 
  tiefe= ImageDepth(image)
  *mem=AllocateMemory(x*y*3/8+2)
  myimage=CreateImage(#PB_Any,x,y,tiefe)
  myRGBA.RGBATyp\l=RGBA(0,1,2,3)
  
  Start=ElapsedMilliseconds()
  EnableASM : DisableDebugger
  RDTSC
  MOV T0\Ticks\LowPart,eax
  MOV T0\Ticks\HighPart,edx
  If StartDrawing(ImageOutput(myimage))
    DrawImage(ImageID(image), 0, 0)    
    DrawingMode(#PB_2DDrawing_CustomFilter)
    ;CustomFilterCallback(@ScaleGrayCallback())
    ;    CustomFilterCallback(vm)
    If $3020100=myRGBA\l 
      CustomFilterCallback(@myScaleGrayCallback()) 
    Else 
      CustomFilterCallback(@ScaleGrayCallback()) 
      Debug myRGBA\l
    EndIf 
    
    Box(0, 0, x, y)
    StopDrawing()
  Else
    EnableDebugger: Debug x : Debug y: Debug myimage
    MessageRequester("FATAL","Fehler StartDrawing")
    End 
  EndIf
  DisableDebugger
  RDTSC
  MOV T1\Ticks\LowPart,eax
  MOV T1\Ticks\HighPart,edx  
  EnableDebugger
  Debug "Dauer: "+Str(T1\q-T0\q) +" "+Str(ElapsedMilliseconds()-Start)+" ms" ;6980419767
  ShowMemoryViewer(*mem,1000) 
  Dateiname=ReplaceString(Dateiname,".jpg","grau.png")
  SaveImage(myimage,Dateiname,#PB_ImagePlugin_PNG)
EndProcedure

Mainneu()

;  Procedure.a rotwert(Farbe.l)   : ProcedureReturn Int((Pow(Red  (Farbe)/255.0,2.2)*0.2126)*255.5) : EndProcedure
;  Procedure.a gruenwert(Farbe.l) : ProcedureReturn Int((Pow(Green(Farbe)/255.0,2.2)*0.7152)*255.5) : EndProcedure
;  Procedure.a blauwert(Farbe.l)  : ProcedureReturn Int((Pow(Blue (Farbe)/255.0,2.2)*0.0722)*255.5) : EndProcedure
DataSection : roteFarbe:
  Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,
  $01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$03,$03,$03,$03,$03,$03,$03,$03,$03,$04,
  $04,$04,$04,$04,$04,$04,$04,$04,$05,$05,$05,$05,$05,$05,$05,$06,$06,$06,$06,$06,$06,$06,$07,$07,$07,$07,$07,
  $07,$08,$08,$08,$08,$08,$08,$09,$09,$09,$09,$09,$09,$0A,$0A,$0A,$0A,$0A,$0B,$0B,$0B,$0B,$0B,$0C,$0C,$0C,$0C,
  $0C,$0D,$0D,$0D,$0D,$0E,$0E,$0E,$0E,$0E,$0F,$0F,$0F,$0F,$10,$10,$10,$10,$11,$11,$11,$11,$12,$12,$12,$12,$13,
  $13,$13,$14,$14,$14,$14,$15,$15,$15,$15,$16,$16,$16,$17,$17,$17,$18,$18,$18,$18,$19,$19,$19,$1A,$1A,$1A,$1B,
  $1B,$1B,$1C,$1C,$1C,$1D,$1D,$1D,$1E,$1E,$1E,$1F,$1F,$1F,$20,$20,$20,$21,$21,$21,$22,$22,$23,$23,$23,$24,$24,
  $24,$25,$25,$26,$26,$26,$27,$27,$28,$28,$28,$29,$29,$2A,$2A,$2A,$2B,$2B,$2C,$2C,$2C,$2D,$2D,$2E,$2E,$2F,$2F,
  $2F,$30,$30,$31,$31,$32,$32,$33,$33,$34,$34,$34,$35,$35,$36
  grueneFarbe:       
  Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,
  $01,$01,$01,$01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,$03,$03,$03,$03,$03,$04,$04,$04,$04,$04,$05,$05,
  $05,$05,$06,$06,$06,$06,$07,$07,$07,$07,$08,$08,$08,$09,$09,$09,$09,$0A,$0A,$0A,$0B,$0B,$0C,$0C,$0C,$0D,$0D,
  $0D,$0E,$0E,$0F,$0F,$0F,$10,$10,$11,$11,$12,$12,$12,$13,$13,$14,$14,$15,$15,$16,$16,$17,$17,$18,$18,$19,$19,
  $1A,$1B,$1B,$1C,$1C,$1D,$1D,$1E,$1F,$1F,$20,$20,$21,$22,$22,$23,$24,$24,$25,$26,$26,$27,$28,$28,$29,$2A,$2A,
  $2B,$2C,$2D,$2D,$2E,$2F,$30,$30,$31,$32,$33,$33,$34,$35,$36,$37,$38,$38,$39,$3A,$3B,$3C,$3D,$3D,$3E,$3F,$40,
  $41,$42,$43,$44,$45,$46,$47,$48,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F,$50,$51,$52,$53,$54,$55,$57,$58,$59,$5A,$5B,
  $5C,$5D,$5E,$5F,$60,$61,$63,$64,$65,$66,$67,$68,$69,$6B,$6C,$6D,$6E,$6F,$71,$72,$73,$74,$75,$77,$78,$79,$7A,
  $7C,$7D,$7E,$80,$81,$82,$84,$85,$86,$88,$89,$8A,$8C,$8D,$8E,$90,$91,$93,$94,$95,$97,$98,$9A,$9B,$9C,$9E,$9F,
  $A1,$A2,$A4,$A5,$A7,$A8,$AA,$AB,$AD,$AE,$B0,$B2,$B3,$B5,$B6
  blaueFarbe:        
  Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
  $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,
  $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,
  $02,$02,$02,$02,$02,$02,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$04,$04,$04,$04,$04,
  $04,$04,$04,$04,$04,$04,$04,$04,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$06,$06,$06,$06,$06,$06,
  $06,$06,$06,$06,$06,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$09,$09,
  $09,$09,$09,$09,$09,$09,$09,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0C,$0C,$0C,$0C,
  $0C,$0C,$0C,$0C,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$10,
  $10,$10,$10,$10,$10,$11,$11,$11,$11,$11,$11,$11,$12,$12,$12 
EndDataSection
;   Procedure.a rotwert(Farbe.l)   : ProcedureReturn (Red(Farbe) * 30) /100 : EndProcedure
;  Procedure.a gruenwert(Farbe.l) : ProcedureReturn (Green(Farbe) * 59) /100 : EndProcedure
;  Procedure.a blauwert(Farbe.l)  : ProcedureReturn (Blue(Farbe) * 11) /100 : EndProcedure  
 


; vm RET verbraucht 75 ms 
; ScaleGrayCallback Dauer: 620018005 259 ms
; myScaleGrayCallback Dauer: 428119984 178 ms ohne Bits 
; myScaleGrayCallback Dauer: 476267007 198 ms mit Bits 

; bekannt vm, auskommentiert  kann so nicht Linux und MacOS laufen
; offen Welche myRGBA's sind noch bekannt.
; Ideen RGBS's zur Laufzeit anpassen
;   myScaleGrayCallback in C, PB-InlineASM, ASM oder Hex
;   GPU 
;   Setbits im 2. Lauf 6 Pixel (3x64 bit) rein 4+2 Bytes (48 bits) raus 
Edit Compilerif

Edit by NicTheQuick: Zeilen gekürzt
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

@juergenkulow
Danke für das Beispiel :allright:
Ein Callback für die Bearbeitung der Pixel ist eine feine Sache solange die Pixel direkt manipuliert werden, sobald
jedoch ein eigener zusätzlicher Parameter übergeben werden müsste ist es eher unbrauchbar (Threads).

______________________________________________________________

@mk-soft
Momentan verwende ich die Informationen der BITMAP Struktur um an
Informationen bezüglich des Bildes zu kommen (Bits /Pitch /BitsPerPixel /...).

Die Konvertierung sieh so aus (Beispiel ohne SetBits() aber mit 0 - 7 Grauwerten -> 3 Bit Grayscale):

Code: Alles auswählen

;PureBasic v.6.52 x64

EnableExplicit

UseJPEGImageDecoder();Unterstützung für JPEG und PNG!
UseJPEG2000ImageDecoder()
UsePNGImageDecoder()

Import "nifGrayscale.lib"
  nifColorToGrayscale(*Pixel,*Index);Assembler Funktion!
EndImport

Structure BITMAP_STRUCT;Modifizierte Struktur!
  bmType.l
  bmWidth.l
  bmHeight.l
  bmWidthBytes.l
  bmPlanes.w
  bmBitsPixel.w
  Alignment.b[4]
  *bmBits
  PixelSize.i
  Bytes.i
EndStructure

Structure IMAGE_STRUCT
  Id.i
  Handle.i
  Bitmap.BITMAP_STRUCT
EndStructure

Procedure.i nifFree(*nif.IMAGE_STRUCT)
  With *nif
    If IsImage(\Id)
      FreeImage(\Id)
    EndIf
    FreeStructure(*nif)
  EndWith
EndProcedure

Procedure.i nifBitmap(*nif.IMAGE_STRUCT)
  With *nif
    If \Handle
      If GetObject_(\Handle,SizeOf(BITMAP),@\Bitmap)
        \Bitmap\PixelSize = \Bitmap\bmBitsPixel / 8
        \Bitmap\Bytes = \Bitmap\bmWidthBytes * \Bitmap\bmHeight
        ProcedureReturn #True
      EndIf
    EndIf 
  EndWith
EndProcedure

Procedure.i nifEncode(*nif.IMAGE_STRUCT)
  Protected ImageX.i
  Protected ImageY.i
  Protected *Scanline
  Protected *Pixel;.RGB_STRUCT
  Protected Index.i
  With *nif
    If \Bitmap\bmBitsPixel = 24
      For ImageY = 0 To \Bitmap\bmHeight - 1
        *Scanline = \Bitmap\bmBits +(ImageY * \Bitmap\bmWidthBytes)
        For ImageX = 0 To \Bitmap\bmWidth - 1
          *Pixel = *Scanline + (ImageX * \Bitmap\PixelSize)
          nifColorToGrayscale(*Pixel,@Index)
        Next
      Next
      ProcedureReturn #True
    Else
      ;Bild mit Alpha!
    EndIf
  EndWith
EndProcedure

Procedure.i nifHandle(*nif.IMAGE_STRUCT)
  With *nif
    ProcedureReturn \Handle
  EndWith
EndProcedure

Procedure.i nifLoadImage(File.s)
  Protected *nif.IMAGE_STRUCT
  Protected Timer.q
  *nif = AllocateStructure(IMAGE_STRUCT)
  If *nif
    With *nif
      \Id = LoadImage(#PB_Any,File)
      If \Id
        \Handle = ImageID(\Id)
        If nifBitmap(*nif)
          Timer = ElapsedMilliseconds()
          If nifEncode(*nif)
            Timer = ElapsedMilliseconds() - Timer
            MessageRequester("","Timer: " + Str(Timer))
            ProcedureReturn *nif
          EndIf
        EndIf
      EndIf
      nifFree(*nif)
    EndWith
  EndIf 
EndProcedure

Procedure.i nifSaveBitmap(*nif.IMAGE_STRUCT,File.s)
  With *nif
    ProcedureReturn SaveImage(\Id,File,#PB_ImagePlugin_BMP,#Null,\Bitmap\bmBitsPixel)
  EndWith
EndProcedure

Global Image.i
Global File.s

File = "test.bmp";<- ÄNDERN!!!
Image = nifLoadImage(File)

If Image
  ;nifSaveBitmap(Image,"converted_" + File)
  If OpenWindow(0,0,0,800,580,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
    If StartVectorDrawing(WindowVectorOutput(0))
      MovePathCursor(0,0)
      DrawVectorImage(nifHandle(Image),$FF,800,580)
    EndIf
    Repeat
    Until WaitWindowEvent() = #PB_Event_CloseWindow
    CloseWindow(0)
  EndIf
  nifFree(Image)
EndIf

End
Sollte relativ schnell sein - viel Spaß beim testen :)

Meine Lib hab ich hier hinterlegt: https://www.dropbox.com/s/nljp9xee2n0li ... e.lib?dl=0
Bin noch am Experimentieren (Assembler) was das Bit Schreiben & Grauwert Konvertierung angeht.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

Endlich hab ich auch SetBits() & GetBits() komplett in Assembly implementiert.
Als Vorlage hab ich @juergenkulow Funktionen (etwas abgewandelt) verwendet.
Nun sind es nur 8 Instruktionen für Set und 11 für GetBits(). <)
Genial wäre, wenn es einen weitere Procedure für Inline-Assembly gäbe so das mir der weg über eine Lib erspart bliebe.
-> https://www.purebasic.fr/english/viewto ... =3&t=71657
Zuletzt geändert von Mijikai am 02.11.2018 23:21, insgesamt 1-mal geändert.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: SetBits / GetBits gut genug?

Beitrag von Mijikai »

Die ersten Ergebnisse mit Dithering :)

Original :
Bild
Groß: https://i.postimg.cc/FrYzbyzF/pexels-photo-890550.jpg

Farb - Dither / 3 x 8 Farbstufen (3 x 3 Bit):
Bild
Groß: https://i.postimg.cc/fzP31Hp0/3-Bit-Dit ... r-Test.png

Graustufen - Dither / 8 Graustufen (3 Bit):
Bild
Groß: https://i.postimg.cc/b8GS1hS0/3-Bit-Dither-Test.png

Bildquelle & Lizenz: https://www.pexels.com/de/foto/augapfel ... id-890550/

Als nächstes versuche ich das Dither Bild etwas zu verwischen um es noch besser wirken zu lassen (nach dem Laden).
Auch muss ich noch den Dither Code nach Assembly konvertieren.
3 Bit (8 Stufen) Dither sieht nicht schlecht aus finde ich. :o

:coderselixir:
Antworten