Seite 1 von 2

Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 12:58
von silbersurfer
Hallo liebe Comunity

Ich bin Neu auf diesen Board, und habe angefangen mit PureBasic zu Proggen !
Grundwissen habe Ich soweit schon, da Ich vorher mit BlitzBasic Plus viel Programmiert habe.

Darum auch gleich meine erste frage bezüglich Canvas Gadget.

Ich versuche gerade mein Projekt in PureBasic zu übertragen was soweit schon gut vorran geht :D

Nun aber mein kleines Problem

in BlitzBasic gibt es ein ähnlichen Befehl um Gadgets zu Resizen SetGadgetshape
nur mit dem unterschied das der Inhalt vom Canvas Automatisch mit Skaliert wird, was auch sehr schnell ist....

Code: Alles auswählen

Function LeinwandZoom(factor,x=0,y=0)
	If ImageDatei=0 Return
	SetSliderValue(SliderV,y*factor)
	SetSliderValue(SliderH,x*factor)

	LeinwandX=-SliderValue(SliderH)
	LeinwandY=-SliderValue(SliderV)
	---------------------------------------------------------------------------------------------
	SetGadgetShape ImageLeinwand,LeinwandX,LeinwandY,Image_Width*factor,Image_Height*factor
   ---------------------------------------------------------------------------------------------
	SliderUpdate(SliderH,ClientWidth(ImageGruppe) ,Image_Width*factor)
	SliderUpdate(SliderV,ClientHeight(ImageGruppe) ,Image_Height*factor)
	LeinwandUpdate(ImageLeinwand,LeinwandX,LeinwandY)
	FlipCanvas ImageLeinwand
End Function
Ich konnte weder in der Hilfe, noch hier im Forum darüber genaues finden...
Meine Frage gibt es überhaupt die möglichkeit des Auto Skalieren vom Canvas in PureBasic oder auch als Api Funktion ?

Denn zur Zeit habe Ich das in PureBasic so gelöst was allerdings nicht sehr schnell ist.
gerade wenn man 4-10 fachen Zoom Factor setzt

Code: Alles auswählen

Procedure CanvasZoom(CanvasZoom=1)
	Protected datei 
	ResizeGadget(ImageCanvas,0,0,Image_Width*CanvasZoom,Image_Height*CanvasZoom)
	Datei=ResizeImage(ImageDatei,Image_Width*CanvasZoom,Image_Height*CanvasZoom,#PB_Image_Raw)
	SetGadgetAttribute(ImageCanvas,#PB_Canvas_Image,Datei)
	CenterCanvasImage()
EndProcedure
Ich würde mich sehr über Ideen und Hilfestellungen freuen.....

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 13:47
von NicTheQuick
Ich hab es nicht ausprobiert, aber wie wäre es hiermit?

Code: Alles auswählen

Procedure CanvasZoom(CanvasZoom.f = 1.0)
	ResizeGadget(ImageCanvas, 0, 0, Image_Width * CanvasZoom, Image_Height * CanvasZoom)
	If StartDrawing(CanvasOutput(ImageCanvas))
		DrawImage(ImageDatei, 0, 0, GadgetWidth(ImageCanvas), GadgetHeight(ImageCanvas))
		StopDrawing()
	EndIf
EndProcedure
Ich weiß nur nicht, was die Funktion 'CenterCanvasImage()' bei dir macht.

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 13:58
von silbersurfer
Danke erstmal NicTheQuick
ist denn die DrawImage Funktion schneller als ResizeImage ?
werde es gleich mal testen...
Ich weiß nur nicht, was die Funktion 'CenterCanvasImage()' bei dir macht.
Diese überprüft nur ob ImageWidth<CanvasWidht und ImageHeight<CanvasHeight ist.
Um die Slider anzupassen, oder das Image wenn kleiner im Canvas zu Zentieren

Code: Alles auswählen

Procedure CenterCanvasImage()
  Protected wi,hi,wc,hc
  If IsGadget(ImageCanvas) 
    wi=GadgetWidth(#HauptGruppe) : wc=GadgetWidth(ImageCanvas)
    hi=GadgetHeight(#HauptGruppe) : hc=GadgetHeight(ImageCanvas)
    If wi>wc
    	ResizeGadget(ImageCanvas,(wi-wc)/2,#PB_Ignore,#PB_Ignore,#PB_Ignore)
    	SetGadgetAttribute(#HauptGruppe,#PB_ScrollArea_InnerWidth,wi-24)
    ElseIf wc>wi
    	ResizeGadget(ImageCanvas,0,#PB_Ignore,#PB_Ignore,#PB_Ignore)
    	SetGadgetAttribute(#HauptGruppe,#PB_ScrollArea_InnerWidth,wc)  	
    EndIf 
    If hi>hc 
    	ResizeGadget(ImageCanvas,#PB_Ignore,(hi-hc)/2,#PB_Ignore,#PB_Ignore)
    	SetGadgetAttribute(#HauptGruppe,#PB_ScrollArea_InnerHeight,hi-24)
    ElseIf hc>hi
    	ResizeGadget(ImageCanvas,#PB_Ignore,0,#PB_Ignore,#PB_Ignore)
    	SetGadgetAttribute(#HauptGruppe,#PB_ScrollArea_InnerHeight,hc)
    EndIf
  EndIf 
EndProcedure 
Edit: leider ist das auch nicht schneller NicTheQuick aber Danke für die schnelle Antwort..

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 14:31
von NicTheQuick
Dann wäre es mal interessant einen komplett lauffähigen Code zu sehen zum Testen. Denn ich kann mir gar nicht vorstellen, dass es so langsam sein soll.

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 16:17
von Bisonte
Ok... Nur mal so nebenbei... Warum das ganze Gadget verkleinern.... Das Bild innen reicht doch normalerweise. Hintergrundfarbe anpassen und gut.
Das dürfte schonmal ein kleinen Tacken schneller sein.

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 16:46
von silbersurfer
NicTheQuick schrieb:
Dann wäre es mal interessant einen komplett lauffähigen Code zu sehen zum Testen

hier jetzt mal ein Code der das veranschaulicht was ich meine

Code: Alles auswählen

If OpenWindow(0, 0 , 0, 1024, 768, "Scale Image Test !",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Global Canvas=CanvasGadget(#PB_Any, 0, 0, WindowWidth(0), WindowHeight(0),#PB_Canvas_Border) 
EndIf 

;fügt tastaturabfrage für + und - vom Zifferblock hinzu 
AddKeyboardShortcut(0,#PB_Shortcut_Add,1000)
AddKeyboardShortcut(0,#PB_Shortcut_Subtract,1001)

Global MImage=CreateImage(#PB_Any, 1024, 768,32)
CanvasZoom=1
If StartDrawing(ImageOutput(MImage))
    For t= 0 To 50
    	Circle(Random(1024),Random(768), Random(300), RGB(Random(255), Random(255), Random(255)))
    Next
    StopDrawing() 
    SetGadgetAttribute(Canvas,#PB_Canvas_Image ,ImageID(Mimage))
EndIf

Procedure ScaleImage(id,factor=1)
	Protected w=ImageWidth(id),h=ImageHeight(id)
	If StartDrawing(CanvasOutput(Canvas))
		DrawImage(ImageID(id),0,0,w*factor,h*factor)
		StopDrawing()
	EndIf 
EndProcedure	

Repeat 
  event=WaitWindowEvent()
  Select event 
  	Case #PB_Event_CloseWindow
  		quit=1
  	Case #PB_Event_Menu
  		Select EventMenu()
  			Case 1000 ;Plus
  				CanvasZoom=CanvasZoom+1
  				ScaleImage(MImage,CanvasZoom)
  			Case 1001 ;Minus
  				If CanvasZoom>1
  					CanvasZoom=CanvasZoom-1
  					ScaleImage(MImage,CanvasZoom)
  				EndIf 	
  		EndSelect
  EndSelect 		
Until Quit=1
Bisonte schrieb:
Ok... Nur mal so nebenbei... Warum das ganze Gadget verkleinern.
es geht hier ja auch nur um das Image welches Skaliert werden soll Bisnote, diese ist ja was so Performance zieht. Das Gadget selber ist rasend schnell Skaliert

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 17:13
von NicTheQuick
Danke für den Code. Ich hab ihn mal noch ein bisschen verschönert.
Jetzt kann ich jedenfalls nachvollziehen, dass das Resizing hier sehr langsam geht mit den Image-Befehlen. Das ist natürlich nicht so schön. Aber ich bin sicher, dass schon bald so Leute wie STARGATE oder ts-soft hier aufkreuzen und bessere Ideen haben.

Bist du sicher, dass bei BlitzPlus auch nur GDI benutzt wurde oder sind da solche Dinge mit DirectX gelaufen?

Code: Alles auswählen

EnableExplicit

Global Canvas.i

If OpenWindow(0, 0, 0, 1024, 768, "Scale Image Test !", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	Canvas = CanvasGadget(#PB_Any, 0, 0, WindowWidth(0), WindowHeight(0), #PB_Canvas_Border)
EndIf

;fügt tastaturabfrage für + und - vom Zifferblock hinzu
AddKeyboardShortcut(0, #PB_Shortcut_Q, 1000)
AddKeyboardShortcut(0, #PB_Shortcut_E, 1001)

Global MImage.i = CreateImage(#PB_Any, 1024, 768, 32)
Global CanvasZoom.f = 1.0, t.i
If StartDrawing(ImageOutput(MImage))
	For t = 0 To 50
		Circle(Random(1024), Random(768), Random(30), RGB(Random(255), Random(255), Random(255)))
	Next
	StopDrawing()
EndIf

Procedure ScaleImage(id.i, factor.f = 1)
	Protected w.i = ImageWidth(id), h.i = ImageHeight(id)
	If StartDrawing(CanvasOutput(Canvas))
		DrawImage(ImageID(id), 0, 0, w * factor, h * factor)
		StopDrawing()
	EndIf
EndProcedure   

Define event.i

ScaleImage(MImage)

Repeat
	event = WaitWindowEvent()
	Select event
		Case #PB_Event_CloseWindow
			Break
		
		Case #PB_Event_Menu
			Select EventMenu()
				Case 1000 ;A
					CanvasZoom * 1.1
					ScaleImage(MImage, CanvasZoom)
				
				Case 1001 ;B
					If CanvasZoom > 1
						CanvasZoom / 1.1
						ScaleImage(MImage, CanvasZoom)
					EndIf    
			EndSelect
	EndSelect       
ForEver

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 19:37
von silbersurfer
NicTheQuick schrieb:
Bist du sicher, dass bei BlitzPlus auch nur GDI benutzt wurde oder sind da solche Dinge mit DirectX gelaufen?
das kann Ich nicht mit sicherheit sagen, was mir aber stark auffällt ist das unter Blitzplus das Canvas rasendschnell Skaliert wird, sowohl das Canvas als auch das Image darin
und es ja auch genug andere BildAnzeigeProgs gibt die diesen Dienst genau so schnell verrichten !

was Ich jetzt Gemacht habe ist eine Art Speed Optimierung, nur da Macht mir die Event geschichte von PureBasic Probleme, weil diese nur auf MausUp events ausgerichtet sind
soweit Ich das sehen kann

Code: Alles auswählen

Procedure ImageScale()
	Protected x,y,w,h,Datei
	Static BackupImage
	x=GetGadgetAttribute(#HauptGruppe, #PB_ScrollArea_X)
	y=GetGadgetAttribute(#HauptGruppe, #PB_ScrollArea_Y)
	w=GadgetWidth(#HauptGruppe)
	h=GadgetHeight(#HauptGruppe)
	If BackupImage<>0 
		FreeImage(BackupImage)
	EndIf 	
	BackupImage = GrabImage(ImageDatei, #PB_Any, x/CanvasZoom, y/CanvasZoom, w/CanvasZoom, h/CanvasZoom)
	Datei=ResizeImage(BackupImage,w,h,#PB_Image_Raw)
 	If StartDrawing(CanvasOutput(ImageCanvas))
    	DrawImage(Datei, x, y)
    	StopDrawing()
    EndIf		
EndProcedure
das hier Funtzt Tadellos, bis auf das der Inhalt vom Canvas erst nach dem loslassen von der Maus beim Slider bewegen Aktualiesiert wird
was natürlich nicht im Sinne des Erfinders ist :cry:

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 19:39
von NicTheQuick
silbersurfer hat geschrieben:was Ich jetzt Gemacht habe ist eine Art Speed Optimierung, nur da Macht mir die Event geschichte von PureBasic Probleme, weil diese nur auf MausUp events ausgerichtet sind, soweit Ich das sehen kann.

Code: Alles auswählen

<snip>
das hier Funtzt Tadellos, bis auf das der Inhalt vom Canvas erst nach dem loslassen von der Maus beim Slider bewegen Aktualiesiert wird
Schau dir mal 'BindGadgetEvent()' an. Damit sollte das so laufen wie du dir das wünschst.

Re: Canvas Gadget Resize mit Image ?

Verfasst: 06.07.2014 19:57
von silbersurfer
NicTheQuick schrieb:
Schau dir mal 'BindGadgetEvent()' an
da kann Ich nichts in der Hilfe von PureBasic finden ist das eine API Funktion NicTheQuick ?