Aktuelle Zeit: 14.10.2019 23:22

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 19.10.2016 09:26 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Hallo,

ich habe gerade das Problem, dass ich das Image eines CanvasGadgets ersetzen möchte und dazu die exakte Größe des dafür nötigen Images suche. Das CanvasGadget hat einen Rahmen und dieser wird offenbar vom Darstellungsbereich abgezogen.

Über GadgetWidth() und GadgetHeight() bekomme ich die äußeren Maße des Gadgets. Diese Werte sind durch den Rahmen größer als das angezeigte Image. Unter Win 10 sind das z.B. 4 Pixel in jede Richtung.

Nun möchte ich aber nicht mit festen Werten arbeiten (ImageWidth = GadgetWidth() - 4), da diese evtl. von OS zu OS unterschiedlich sind. Gibt es eine Möglichkeit die tatsächlichen Ausmaße des Canvas-Images zu ermitteln?

Mit GetGadgetAttribute(MeinCanvasGadget, #PB_Canvas_Image) bekomme ich leider das Image(Windows-)handle zurück, welches nicht mit ImageWidth() funktioniert.

PS: Dann habe ich noch eine Verständnisfrage.
Ich möchte aus einem großen Image (z.B. 600 x 600 pixel) beim Drüberfahren mit der Maus einen 40 x 40 pixel großen Bereich herauskopieren, um ihn in einem separaten ImageGadget anzuzeigen. Das ganze passiert also bei jedem MouseMove-Event auf dem Canvas, unter Umständen also x mal pro Sekunde.

Frage: Ist der richtige Weg dies zu tun folgender?
1) NeuesImage = GrabImage(#CanvasImage, #PB_Any, MouseX, MouseY, 40, 40)
2) SetGadgetState(#ImageGadget, ImageID(NeuesImage))

Wenn das der richtige Weg ist, muss ich "NeuesImage" dann noch freigeben?
Vom Gefühl her würde ich es eher so machen, dass nicht x mal pro Sekunde ein neues Image generiert wird, sondern hätte gedacht, dass man irgendwie die Pixeldaten von einem Image zum einem anderen, bereits vorhandenen Image kopiert. Dazu habe ich in der Befehlsreferenz allerdings nichts gefunden.

_________________
"Never run a changing system!"
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 51.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 19.10.2016 10:10 
Offline
Benutzeravatar

Registriert: 21.08.2006 17:39
Hi,

kann dir da nicht groß helfen, aber wie wäre es mit einem zweiten Canvas, auf dem du das Bild einfach clipst?
Canvas1 ist dann das Original, zuständig für Hover ... und Canvas2 verschiebt sein dargestelltes Bild in einem 40x40 Viewport.

Und zu deinen Dimensionen. Hilft OutputHeight() vielleicht? Habs jetzt nicht getestet, erinnere mich aber an einen anderen Thread.

MFG
MIB

_________________
(hab alles, kann alles, weiß alles!!^^)

Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 19.10.2016 11:01 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
Direkt aus dem jaPBe Quellcode... (naja fast, da gabs kein Protected ^^ ) :

Code:
Procedure GetBitmapWidth(hBitmap)
  Protected BmpInfo.BITMAP
  If hBitmap = 0 : ProcedureReturn 0 : EndIf
  If GetObjectType_(hBitmap) <> #OBJ_BITMAP : ProcedureReturn 0 : EndIf
  If GetObject_(hBitmap, SizeOf(BITMAP), BmpInfo) = 0 : ProcedureReturn 0 : EndIf
  ProcedureReturn BmpInfo\bmWidth
EndProcedure
Procedure GetBitmapHeight(hBitmap)
  Protected BmpInfo.BITMAP
  If hBitmap = 0 : ProcedureReturn 0 : EndIf
  If GetObjectType_(hBitmap) <> #OBJ_BITMAP : ProcedureReturn 0 : EndIf
  If GetObject_(hBitmap, SizeOf(BITMAP), BmpInfo) = 0 : ProcedureReturn 0 : EndIf
  ProcedureReturn BmpInfo\bmHeight
EndProcedure


Hier werden die Ausmaße einer Bitmap zurückgegeben (also dein OS-Handle).
Ich denke das hast du jetzt gesucht.

Nachtrag :
Wenn Du #PB_Any zum erstellen nutzt, musst du freigeben. Bei einer festen Nummernvergabe nicht.
Dann kann man einfach "überschreiben". (Liegt an #PB_Any das extrem hohe Nummern vergibt)

_________________
PureBasic 5.71 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 19.10.2016 12:21 
Offline
Benutzeravatar

Registriert: 08.09.2004 00:57
Wohnort: Berlin
Bisonte hat geschrieben:
(Liegt an #PB_Any das extrem hohe Nummern vergibt)

Sind ja auch Speicheradressen!

_________________
PureBasic 5.71 | SpiderBasic 2.21 | Windows 10 Pro (x64) | Linux Mint 19.2 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 19.10.2016 12:47 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Danke Bisonte, die Prozeduren funktionieren einwandfrei. :allright:

Mit dem Grabben habe ich es jetzt so gelöst.

Code:
   If StartDrawing(CanvasOutput(Window_Screenshot_Canvas_Screenshot))
       iImageClip = GrabDrawingImage(#PB_Any, x, y, iImageWidth, iImageHeight)
      StopDrawing()
   EndIf
   If iImageClip = 0 : ProcedureReturn : EndIf
   
   SetGadgetState(Window_Screenshot_Image_Screenshot, ImageID(iImageClip))
   FreeImage(iImageClip)


Das funktioniert, ist aber halt eine ewige "GrabImage / FreeImage" Orgie.

Da ich die Image-Lib Internas nicht kenne, kann ich nicht beurteilen, wie groß der Overhead beim hochfrequenten Neuerstellen eines Images ist.

Wie gesagt, logischer wäre für mich, wenn man den BitmapInhalt eines Images in die Bitmap eines anderen Images kopieren könnte (ggf. auch als Ausschnitt) ohne dabei jedes mal ein drittes Image als temporären "Datenträger" benutzen zu müssen. Aber das scheint mit PB-eigenen Mitteln nicht zu gehen.

_________________
"Never run a changing system!"
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 51.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 19.10.2016 19:38 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
Wie gesagt. Wenn Du eine feste PB Objektnummer wählst, anstelle von #PB_Any, kannst du laufend "überschreiben". ohne freigabe des vorherigen Bildes.

Also die GrabImage Variante ist mit GrabImage(#CanvasImage, #ImageAusschnitt, MouseX, MouseY, 40, 40) noch am sinnvollsten (von der Logik her)
Kein Ewiges erstellen und freigeben, sondern überschreiben.

P.S.
Wobei ich gerade die Idee hatte, anstelle eines ImageGadgets ein Canvas zu nehmen und dort einfach nur versetzt zu zeichnen. so wie z.B. Ein Grosses Bild liegt unter einem kleinen ausschnitt und wird bewegt...
Dann nur noch die Koordinaten berechnen und an das kleinere Canvas schicken, das das bild unter dem ausschnitt richtig hinschiebt ....
(Kopierschutz Monkey Island damals ;) )

_________________
PureBasic 5.71 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 19.10.2016 21:14 
Offline
Benutzeravatar

Registriert: 21.08.2006 17:39
Hi,

Bisonte hat geschrieben:
P.S.
Wobei ich gerade die Idee hatte, anstelle eines ImageGadgets ein Canvas zu nehmen und dort einfach nur versetzt zu zeichnen. so wie z.B. Ein Grosses Bild liegt unter einem kleinen ausschnitt und wird bewegt...
Dann nur noch die Koordinaten berechnen und an das kleinere Canvas schicken, das das bild unter dem ausschnitt richtig hinschiebt ....
(Kopierschutz Monkey Island damals ;) )

man-in-black hat geschrieben:
kann dir da nicht groß helfen, aber wie wäre es mit einem zweiten Canvas, auf dem du das Bild einfach clipst?
Canvas1 ist dann das Original, zuständig für Hover ... und Canvas2 verschiebt sein dargestelltes Bild in einem 40x40 Viewport.

zu spät :P

man-in-black hat geschrieben:
Und zu deinen Dimensionen. Hilft OutputHeight() vielleicht?

Ich hab folgendes einfach mal q&d mit Win7 ausgeführt. "Leider" gibts bei mir keinen Rahmen, weshalb ich da nichts weiter testen kann.
Da obiges bereits überlesen wurde, häng ich meinen Testcode einfach mal an :P
Vielleicht mag das ein W10 Nutzer mal ausführen. Würd mich auch interessieren.
Code:
OpenWindow(#PB_Any,0,0,800,600,"")
CanvasGadget(1,0,0,800,600)

Repeat
  event = WaitWindowEvent()
 
  If event = #PB_Event_Gadget
    Select EventGadget()
      Case 1
        If EventType() = #PB_EventType_LeftClick
          Debug GadgetHeight(1)
          Debug GadgetWidth(1)
         
          StartDrawing(CanvasOutput(1))
            Debug OutputHeight()
            Debug OutputWidth()
           
            DrawingMode(#PB_2DDrawing_Outlined)
            Box(0,0,OutputWidth(),OutputHeight(),Random($FFFFFF))   ;visueller Test, ob Maße stimmen
         
          StopDrawing()
          Debug "-----"
         
        EndIf
    EndSelect
  EndIf

Until event = #PB_Event_CloseWindow


MIB

_________________
(hab alles, kann alles, weiß alles!!^^)

Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 20.10.2016 01:13 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
Ok das hab ich wohl irgendwie wegen der Fachausdrücke nicht gerafft ;) Man möge einem alten Mann verzeihen ....

Zu deinen Q&D TestCode auf Win 10... Rahmen beim Canvas gibts per #PB_Canvas_Border als Flag ;)
Und die OutputWidth() + OutputHeight() Angaben sind tatsächlich auch mit Rahmen korrekt.

800x600 ohne Rahmen
796x596 mit Rahmen

Edit : Hier mal schnell zusammengeschusterst als beispiel beide Techniken... verschieben und überschreiben....

(halt entsprechend auskommentieren)

Code:
#BigImage = 1
#SmallImage = 2

Global mx, my

Procedure CanvasImage_Events()
 
  If EventType() = #PB_EventType_MouseMove
    mx = GetGadgetAttribute(EventGadget(), #PB_Canvas_MouseX)
    my = GetGadgetAttribute(EventGadget(), #PB_Canvas_MouseY)
    GrabImage(#BigImage, #SmallImage, mx, my, 40, 40) ; Die überschreibvariante
    PostEvent(#PB_Event_Gadget, 0, 2, #PB_EventType_Change)
  EndIf
   
EndProcedure
Procedure CanvasMini_Events()
 
  If EventType() = #PB_EventType_Change

    StartDrawing(CanvasOutput(2))
    DrawImage(ImageID(#SmallImage), 0, 0) ; Die Überschreibvariante
    ; DrawImage(ImageID(#BigImage), -mx, -my) ; Die Verschiebetechnik
    StopDrawing()
   
  EndIf
   
EndProcedure


UsePNGImageDecoder()

LoadImage(#BigImage, "D:\Dein600x600px_Image.png")

OpenWindow(0, 0, 0, 800, 600, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)

CanvasGadget(1, 0, 0, 600, 600, #PB_Canvas_Border)
StartDrawing(CanvasOutput(1))
DrawImage(ImageID(#BigImage), 0, 0)
StopDrawing()

CanvasGadget(2, 610, 0, 40, 40, #PB_Canvas_Border)

BindGadgetEvent(1,@CanvasImage_Events())
BindGadgetEvent(2,@CanvasMini_Events())

Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_CloseWindow
    Break
  EndIf
ForEver


Wobei hier die Verschiebetechnik doch etwas mehr CPU Last erzeugt..
Es wird ja schliesslich noch das komplette Bild gezeichnet, auch wenn man es nicht sieht.

_________________
PureBasic 5.71 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ermitteln der Imagegröße eines CanvasGadgets?
BeitragVerfasst: 20.10.2016 11:35 
Offline
Benutzeravatar

Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg
Moinsen,

besten Dank für Eure konstruktiven Beiträge. :allright: Ich werde es dann wohl mit festen Imagenummern realisieren.
Schade, dass diese Imagenummerierung von PureBasic (#PB_Any bzw. feste Werte, ImageID() usw.) so viel Spielraum für Missverständnisse bereit hält. Da hätte man sich vielleicht lieber auf ein einziges System geeinigt, z.B. alles nur mit Handles regeln, die dann auch das OS versteht.

_________________
"Never run a changing system!"
PB 5.62, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Ich bin Baujahr 1968, also aktuell 51.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye