Saving image to file

Just starting out? Need help? Post your questions and find answers here.
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Saving image to file

Post by kpeters58 »

Given an imagegadget with an image loaded, how can I save that image to file?

I see that I can get ImageFormat(), ImageWidth(), ImageHeight() and ImageId() but how can I get the imagedata and save it?
PB 5.73 on Windows 10 & OS X High Sierra
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: Saving image to file

Post by Bisonte »

You can do it with a little trick.
Take the Image ID with GetGadgetState() and create a new image with the
Dimensions of the ImageGadget. Then draw the image by ID on the one you just created and save it.
This "workaround" should be crossplatform.

Code: Select all

#Win = 0
#ImageGadget  = 1
#ButtonGadget = 2

OpenWindow(#Win, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ImageGadget(#ImageGadget, 10, 10, 200, 200, LoadImage(1, #PB_Compiler_Home + "Examples\Sources\Data\Purebasic.bmp"))
ButtonGadget(#ButtonGadget, 1, 250, 100, 20,"GO")

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_CloseWindow
      Break
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #ButtonGadget
          ID = GetGadgetState(#ImageGadget)
          ImageToSave = CreateImage(#PB_Any, GadgetWidth(#ImageGadget), GadgetHeight(#ImageGadget))
          If IsImage(ImageToSave)
            If StartDrawing(ImageOutput(ImageToSave))
              DrawImage(ID, 0, 0)
              StopDrawing()
            EndIf
            SaveImage(ImageToSave, "D:\Image.bmp")
            Debug "Saved"  
          EndIf
          
      EndSelect
      
  EndSelect
  
ForEver
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Saving image to file

Post by Olliv »

Normally, one image has three places to be stored in a computer : as a file, compressed or not, in a mass storage.
As a buffer, swapped or not, in RAM.
As a texture, in VIDEO RAM.

LoadImage() expects a image file fullname. And returns an ID.

Code: Select all

ID = LoadImage(#Pb_Any, ImageFileName)
With ImageOutput() which expects a image number, we can create a draw process.

Code: Select all

If StartDrawing(ImageOutput(ID) )
   ; draw process...
   StopDrawing()
EndIf
Inside this draw process, we can ask any characteristics of the current ID image.

Code: Select all

Structure Coloring
 R.b
 G.b
 B.b
 A.b
EndStructure

Structure Pixel
 Pix.Coloring
EndStructure

; draw process
*Buffer.Pixel = DrawingBuffer()

To record a new file image just use SaveImage().
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Saving image to file

Post by RASHAD »

Tested with Windows 10 x64

Code: Select all

#Win = 0
#ImageGadget  = 1
#ButtonGadget = 2

;Get Image from ImagID by Danilo

Import ""
  PB_Object_EnumerateAll(*object,*callback,*d)
  PB_Object_EnumerateStart(*object)
  PB_Object_EnumerateNext(*object,*id.Integer)
  PB_Object_EnumerateAbort(*object)
  PB_Object_Count(*object)
EndImport

Procedure ImageFromImageID(ImageID)
  Protected id, Image_Objects, result = -1
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
      !extrn PB_Image_Objects
      !PUSH  qword [PB_Image_Objects]
      !POP   qword [p.v_Image_Objects]
  CompilerElse
      !extrn _PB_Image_Objects
      !PUSH  dword [_PB_Image_Objects]
      !POP   dword [p.v_Image_Objects]
  CompilerEndIf

  PB_Object_EnumerateStart(Image_Objects)
  While PB_Object_EnumerateNext(Image_Objects,@id)
      If ImageID = ImageID(id)
          result = id
          PB_Object_EnumerateAbort(Image_Objects)
          Break
      EndIf
  Wend
  ProcedureReturn result
EndProcedure

OpenWindow(#Win, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
img = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\Sources\Data\Purebasic.bmp")
ImageGadget(#ImageGadget, 10, 10, 200, 200,ImageID(img))
ButtonGadget(#ButtonGadget, 1, 250, 100, 20,"GO")

Repeat
  Event = WaitWindowEvent()
 
  Select Event
    Case #PB_Event_CloseWindow
      Break
     
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #ButtonGadget
          ID = GetGadgetState(#ImageGadget)
          pbimg = ImageFromImageID(ID)
          SaveImage(pbimg,"d:\image.bmp") 
         
      EndSelect
     
  EndSelect
 
ForEver
Egypt my love
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Saving image to file

Post by Dude »

kpeters58 wrote:Given an imagegadget with an image loaded, how can I save that image to file?
I don't get the question. An ImageGadget() holds an image that you gave it... thus you already have the image. So, SaveImage()?
User avatar
Bisonte
Addict
Addict
Posts: 1305
Joined: Tue Oct 09, 2007 2:15 am

Re: Saving image to file

Post by Bisonte »

Dude wrote:An ImageGadget() holds an image that you gave it... thus you already have the image. So, SaveImage()?
Sometimes you only have an ImageID (Os-Handle).
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Re: Saving image to file

Post by kpeters58 »

Thanks much for everone's help.

@Dude: That's easy. I have just read it from a blob in my database and the original image that got loaded into the database is long gone ...
PB 5.73 on Windows 10 & OS X High Sierra
Papala
User
User
Posts: 38
Joined: Wed Sep 12, 2012 5:09 pm

Re: Saving image to file

Post by Papala »

I have just read it from a blob in my database and the original image that got loaded into the database is long gone ...
Then why don't just getdatabaseblob => createfile => writedata ?
User avatar
mk-soft
Always Here
Always Here
Posts: 6204
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Saving image to file

Post by mk-soft »

@RASHAD

You can direct import PB_XXX_Objects...

Code: Select all

#Win = 0
#ImageGadget  = 1
#ButtonGadget = 2

;Get Image from ImagID by Danilo

; Update mk-soft

; Force Import Fonts
Global __Dummy = LoadFont(#PB_Any, "", 11) : FreeFont(__Dummy)
  
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  Import ""
    PB_Object_EnumerateStart( PB_Objects )
    PB_Object_EnumerateNext( PB_Objects, *ID.Integer )
    PB_Object_EnumerateAbort( PB_Objects )
    PB_Object_GetObject( PB_Object , DynamicOrArrayID)
    PB_Window_Objects.i
    PB_Gadget_Objects.i
    PB_Image_Objects.i
    PB_Font_Objects.i
  EndImport
CompilerElse
  ImportC ""
    PB_Object_EnumerateStart( PB_Objects )
    PB_Object_EnumerateNext( PB_Objects, *ID.Integer )
    PB_Object_EnumerateAbort( PB_Objects )
    PB_Object_GetObject( PB_Object , DynamicOrArrayID)
    PB_Window_Objects.i
    PB_Gadget_Objects.i
    PB_Image_Objects.i
    PB_Font_Objects.i
  EndImport
CompilerEndIf

Procedure ImageFromImageID(ImageID)
  PB_Object_EnumerateStart(PB_Image_Objects)
  While PB_Object_EnumerateNext(PB_Image_Objects,@id)
    If ImageID = ImageID(id)
      result = id
      PB_Object_EnumerateAbort(PB_Image_Objects)
      Break
    EndIf
  Wend
  ProcedureReturn result
EndProcedure

OpenWindow(#Win, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
img = LoadImage(#PB_Any, #PB_Compiler_Home + "examples/sources/Data/PureBasic.bmp")
;img = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\Sources\Data\Purebasic.bmp")
ImageGadget(#ImageGadget, 10, 10, 200, 200,ImageID(img))
ButtonGadget(#ButtonGadget, 1, 250, 100, 20,"GO")

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_CloseWindow
      Break
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #ButtonGadget
          ID = GetGadgetState(#ImageGadget)
          pbimg = ImageFromImageID(ID)
          SaveImage(pbimg,SaveFileRequester("Save", "", "*.bmp", 0))
          
      EndSelect
      
  EndSelect
  
ForEver
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Re: Saving image to file

Post by kpeters58 »

Papala wrote:
I have just read it from a blob in my database and the original image that got loaded into the database is long gone ...
Then why don't just getdatabaseblob => createfile => writedata ?

Because that's a very expensive operation (database server roundtrip etc.). I have the image locally and my users are looking at it when they decide to export it.
PB 5.73 on Windows 10 & OS X High Sierra
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Saving image to file

Post by Dude »

kpeters58 wrote:@Dude: That's easy. I have just read it from a blob in my database and the original image that got loaded into the database is long gone ...
I'm still not getting it. LoadImage(#FromBlob) from the database, set it to the gadget, and the image is still in #FromBlob until you free it (even if the database no longer holds it). What am I missing? Just because the database loses the image doesn't mean #FromBlob also loses it. It's still there for SaveImage(#FromBlob), etc.
Post Reply