Imagegadget

Anfängerfragen zum Programmieren mit PureBasic.
Baba_Smurf
Beiträge: 55
Registriert: 01.03.2015 12:05
Wohnort: Saarland / Püttlingen
Kontaktdaten:

Imagegadget

Beitrag von Baba_Smurf »

Hallo,

mal eine Frage:

ich habe ein Imagegadget von 500x500px erstellt, und lade dort ein Bild hinein, das so skaliert wird, das es auch entweder 500 px
hoch oder 500px breit ist. ein kleiner Codeausschnitt

Code: Alles auswählen

  If ImageWidth(#Bild_Datei) And ImageHeight(#Bild_Datei) => 500
            a_h = ImageHeight(#Bild_Datei)    ;Bildhöhe auslesen
            a_b = ImageWidth(#Bild_Datei)     ;Bilödbreite auslesen
           Bild_breit = 500 / a_b             ;Skalierungsfaktor für Bildbreite errechnen
           Bild_hoch = 500 / a_h              ;Skalierungsfaktor für Bildhöhe errechnen
           Faktor_hoch = a_h* Bild_breit      ;errechnete Bidbreite für Imagegadget
           Faktor_breite = a_h * Bild_hoch    ;errechnete Bildhöhe für Imagegadget
          ResizeImage(#Bild_Datei,Faktor_breite,Faktor_hoch,#PB_Image_Smooth)
           Debug Faktor_breite 
           Debug Faktor_hoch
           Debug Bild_hoch
           Debug Bild_breit
           Debug ImageID(#Bild_Datei) 
        ImageGadget(#Bild_Anzeige,545,50,500,500,ImageID(#Bild_Datei)) ;Imagegadget mit Bild zeichnen
EndIf
das skalieren funktioniert gut, aber wenn ich das Imagegadget auf 300x300px verkleinere und lade trotzdem ein Bild hinein das 500x500px groß ist, wird das Imagegadget automatisch den neuen Bildmaße angepasst, aber warum ??
wie macht mann denn das, wenn das Bild größer wird wie das imagegadget, das ich es mit den pfeilen scrollen kann, bzw das Gadget nicht mit dem Bild mitwächst??
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Imagegadget

Beitrag von RSBasic »

Es spielt keine Rolle, wie groß dein ImageGadget ist. Diese beiden Parameter (Breite, Höhe) sind wirkungslos.
Wenn du das Bild skalieren möchtest, musst du das Bild (Image) verändern und das Bild neu setzen. (SetGadgetState(#ImageGadget, ImageID(#Image)))
Falls du ein größeres Bild in einem kleineren, scrollbaren Bereich einfügen möchtest, dann nutze dafür ScrollAreaGadget().
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Imagegadget

Beitrag von NicTheQuick »

Ein läuffähiges Beispiel wäre praktisch, damit man es auch direkt testen kann. Ich zumindest habe keine Zeit noch den Code drum herum zu schreiben, damit ich dein Problem nachvollziehen kann.
Benutzeravatar
uwe
Beiträge: 17
Registriert: 10.02.2011 23:38
Computerausstattung: PB 5.12 LTS, Manjaro Linux 16 (32-bit)
Wohnort: Oldenburg

Re: Imagegadget

Beitrag von uwe »

Hallo,

ich habe vor einiger Zeit mal ein PictureGadget() geschrieben, welches Scrollbalken enthält und auch der Zoom-Faktor festgelegt werden kann. Stellt man ihn auf 0%, wird das Bild automatisch verkleinert bzw. vergrößert. Einfach mal ausprobieren...

Gruß
Uwe

Code: Alles auswählen

EnableExplicit

UseJPEGImageDecoder()
UsePNGImageDecoder()

Enumeration ;settings
  #PictureHeight
  #PictureWidth
  #PictureScrollX
  #PictureScrollY
  #PictureScrollW
  #PictureScrollH
  #PictureZoom
EndEnumeration

Structure _PictureItem
  ScrollGadget.i
  ImageGadget.i
  In.i
  Out.i
  Zoom.f
  Smooth.i
EndStructure

Procedure PictureLayout(Gadget)
  ;resizes a loaded picture after resizing the gadget
  Protected *d._PictureItem, gw, gh, iw, ih, gr.f, ir.f, x, y, w, h, mode
  *d = GetGadgetData(Gadget)
  If IsImage(*d\In)
    ;sizes
    iw = ImageWidth(*d\In)
    ih = ImageHeight(*d\In)
    ;fit
    If *d\Zoom = 0
      gw = GadgetWidth(Gadget)
      gh = GadgetHeight(Gadget)
      ;ratios
      gr = gw / gh
      ir = iw / ih
      If gr < ir
        ;use full width
        w = gw
        h = gh / ir * gr
        x = 0
        y = (gh - h) / 2
      Else
        ;use full height
        w = gw * ir / gr
        h = gh
        y = 0
        x = (gw - w) / 2
      EndIf
    Else
      w = iw * *d\Zoom / 100
      h = ih * *d\Zoom / 100
    EndIf
    ;set inner width according new image size
    SetGadgetAttribute(Gadget, #PB_ScrollArea_InnerWidth, w)
    SetGadgetAttribute(Gadget, #PB_ScrollArea_InnerHeight, h)
    ;free memory of previous image
    If IsImage(*d\Out)
      FreeImage(*d\Out)
    EndIf
    ;create new image with new size
    *d\Out = CopyImage(*d\In, #PB_Any)
    If *d\Out
      ;smoothing too small images will take too long (until hang-up)
      If w <= 32 Or h <= 32
        mode = #PB_Image_Raw
      Else
        mode = #PB_Image_Smooth
      EndIf
      ResizeImage(*d\Out, w, h, #PB_Image_Smooth)
      SetGadgetState(*d\ImageGadget, ImageID(*d\Out))
    EndIf
  EndIf
EndProcedure
Procedure PictureGadget(Gadget, x, y, w, h)
  ;create a new picture gadget
  Protected *d._PictureItem, id
  id = ScrollAreaGadget(Gadget, x, y, w, h, 0, 0, 0, #PB_ScrollArea_Center)
  SetGadgetColor(Gadget, #PB_Gadget_BackColor, 0)
  *d = AllocateStructure(_PictureItem)
  *d\ImageGadget = ImageGadget(#PB_Any, x, y, w, h, #Null)
  HideGadget(*d\ImageGadget, #True)
  If Gadget = #PB_Any
    *d\ScrollGadget = id
  Else
    *d\ScrollGadget = Gadget
  EndIf
  SetGadgetData(*d\ScrollGadget, *d)
  CloseGadgetList()
  ProcedureReturn id
EndProcedure
Procedure PictureLoad(Gadget, Filename.s)
  ;loads a new picture
  Protected *d._PictureItem = GetGadgetData(Gadget)
  ;free memory of previous image
  If IsImage(*d\In)
    FreeImage(*d\In)
  EndIf
  ;load image
  *d\In = LoadImage(#PB_Any, Filename)
  ;show or hide gadget
  If IsImage(*d\In)
    HideGadget(*d\ImageGadget, #False)
    PictureLayout(Gadget)
    ProcedureReturn #True
  Else
    HideGadget(*d\ImageGadget, #True)
  EndIf
EndProcedure
Procedure PictureClose(Gadget)
  ;closes the current picture
  Protected *d._PictureItem = GetGadgetData(Gadget)
  ;free memory
  If IsImage(*d\In)
    FreeImage(*d\In)
  EndIf
  ;hide gadget
  HideGadget(*d\ImageGadget, #True)
EndProcedure
Procedure PictureGet(Gadget, Setting)
  ;get gadget attribute
  Protected *d._PictureItem
  *d = GetGadgetData(Gadget)
  If IsImage(*d\In)
    Select Setting
    Case #PictureHeight
      ProcedureReturn ImageHeight(*d\In)
    Case #PictureWidth
      ProcedureReturn ImageWidth(*d\In)
    Case #PictureScrollX
      ProcedureReturn GetGadgetAttribute(Gadget, #PB_ScrollArea_X)
    Case #PictureScrollY
      ProcedureReturn GetGadgetAttribute(Gadget, #PB_ScrollArea_Y)
    Case #PictureScrollW
      ProcedureReturn GetGadgetAttribute(Gadget, #PB_ScrollArea_InnerWidth)
    Case #PictureScrollH
      ProcedureReturn GetGadgetAttribute(Gadget, #PB_ScrollArea_InnerHeight)
    Case #PictureZoom
      ProcedureReturn *d\Zoom
    EndSelect
  EndIf
EndProcedure
Procedure PictureSet(Gadget, Setting, Value)
  ;set gadget attributes
  Protected *d._PictureItem = GetGadgetData(Gadget)
  Select Setting
  Case #PictureScrollX
    SetGadgetAttribute(Gadget, #PB_ScrollArea_X, Value)
  Case #PictureScrollY
    SetGadgetAttribute(Gadget, #PB_ScrollArea_Y, Value)
  Case #PictureZoom
    *d\Zoom = Value
    CompilerIf #PB_Compiler_OS = #PB_OS_Linux
      Protected policy
      If Value
        policy = #GTK_POLICY_AUTOMATIC
      Else
        policy = #GTK_POLICY_NEVER
      EndIf
      gtk_scrolled_window_set_policy_(GadgetID(*d\ScrollGadget), policy, policy)
    CompilerEndIf
    PictureLayout(Gadget)
  EndSelect
EndProcedure

DisableExplicit

CompilerIf #PB_Compiler_IsMainFile
  #Pad = 8
  #Filename = "YourTestPictureFilename.jpg"
  If OpenWindow(0, 0, 0, 600, 480, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
    PictureGadget(0, 0, 0, 600, 480)
    PictureLoad(0, #Filename)
    ;set zoom to 100%
    PictureSet(0, #PictureZoom, 100)
    ;center image
    PictureSet(0, #PictureScrollX, PictureGet(0, #PictureScrollW) / 2)
    PictureSet(0, #PictureScrolly, PictureGet(0, #PictureScrollh) / 2)
    ;event loop
    Repeat
      Select WaitWindowEvent()
      Case #PB_Event_SizeWindow
        w = WindowWidth(0) - #Pad * 2
        h = WindowHeight(0) - #Pad * 2
        ResizeGadget(0, #Pad, #Pad, w, h)
        PictureLayout(0)
      Case #PB_Event_CloseWindow
        Break
      EndSelect
    ForEver
  EndIf
CompilerEndIf
Purebasic 5.31 | Fedora 22 (64-bit)
Benutzeravatar
Bisonte
Beiträge: 2465
Registriert: 01.04.2007 20:18

Re: Imagegadget

Beitrag von Bisonte »

Nett :allright:

und aus

Code: Alles auswählen

*d = AllocateStructure(_PictureItem)
ein

Code: Alles auswählen

*d = AllocateMemory(SizeOf(_PictureItem))
gemacht, und es läuft auch mit der LTS Version....

(AllocateStructure() ist hier nicht notwendig, da es eine einfache Structure ist)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Baba_Smurf
Beiträge: 55
Registriert: 01.03.2015 12:05
Wohnort: Saarland / Püttlingen
Kontaktdaten:

Re: Imagegadget

Beitrag von Baba_Smurf »

Hallo,

vielen Dank für die Antworten, hat sich schon mit der Aussage von RSBasic erledigt.
Danke Uwe für dein Code, ist sehr praktisch, aber für mein Projekt erst mal uninteressant, meine Frage war mehr interessenshalber, da in Blitzmax ein Canvas dann nur ein Bildausschnitt in der besagten Größe zeigt, und selbst seine Größe behält.

mfg
Antworten