ImagePlugin Module (Cross platform multi format de-/encoder)

Share your advanced PureBasic knowledge/code with the community.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by wilbert »

I could add support (UseWindowsImageEncoder) for saving BMP, JPEG, GIFF, TIFF and PNG through GDIPlus.
The biggest problem is what to do with palette based images. Dither or not, use a fixed palette or optimal etc.
Animated GIF support is not possible for LoadImage / CatchImage.
Windows (x64)
Raspberry Pi OS (Arm64)
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by walbus »

Yep wilbert, this is clear.
I think, primary important, is a worry free working Tiff loading and saving routine for PB,
also for PNG.

Animated Gif is not important, i think.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by Kwai chang caine »

@KEYA
Thanks for your explanation 8)
This history of copyright never really ending :(

@WILBERT
Thanks when even WILBERT :| 8)
Walbus wrote:Animated Gif is not important, i think.
Image :lol:
ImageThe happiness is a road...
Not a destination
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by netmaestro »

The biggest problem is what to do with palette based images. Dither or not, use a fixed palette or optimal etc.
You have to start somewhere, what I would do is begin by defaulting to Neuquant with dither and consider adding options later if there's a demand. I don't believe there would be though as your defaults would be serving the needs of most PB coders. That's what my Gif Workshop is going to do when I get the chance to work on it again.
BERESHEIT
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by walbus »

Ahh, Kwai, this Gif is mangy, kiddies like this, not old Kung Fu fighters. :shock:

Yep :
what I would do is begin by defaulting to Neuquant with dither and consider adding options
Last edited by walbus on Thu Sep 01, 2016 4:11 pm, edited 1 time in total.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by netmaestro »

Ahh, Kwai, this Gif is mangy
At least this won't start a flamewar - you can't have a flamewar with KCC - he's just too nice a guy :mrgreen:
BERESHEIT
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by walbus »

I like Kwai :wink:
He's a good soul
Last edited by walbus on Thu Sep 01, 2016 11:01 pm, edited 2 times in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: ImagePlugin Module (UseWindowsImageDecoder)

Post by wilbert »

netmaestro wrote:You have to start somewhere, what I would do is begin by defaulting to Neuquant with dither and consider adding options later if there's a demand. I don't believe there would be though as your defaults would be serving the needs of most PB coders. That's what my Gif Workshop is going to do when I get the chance to work on it again.
It's more complicated as I expected.
At first I thought I could use the functionality GDI+ offers to convert to an optimized palette with 2, 16 or 256 colors and the choice wether to use dither and transparancy or not.
The thing I overlooked is that the required functionality is GDI+ 1.1 which isn't available on older computers. :(
So it's either using the default option (which uses dither) or writing your own procedure to convert to 1, 4 or 8 bit depth.
Doing the conversion yourself is of course possible but would make the source code much bigger.
In that case it would make more sense to create a plugin especially designed for gif images but that still wouldn't support animated gifs.
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: ImagePlugin Module (UseWindowsImageDecoder / Encoder)

Post by wilbert »

I added Encode functionality to the module :)
You can now encode a LZW compressed TIFF to memory 8)
See the first post for the updated module and the second post for updated examples.

Please test it (also on XP) end let me know if everything works fine.

To keep the code small, I only offered the default functionality.
This means only TIFF supports the ColorDepth argument and GIF images look dithered.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: ImagePlugin Module (UseWindowsImageDecoder / Encoder)

Post by J. Baker »

wilbert wrote:Please test it (also on XP) end let me know if everything works fine.
Works on XP! :D
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: ImagePlugin Module (UseWindowsImageDecoder / Encoder)

Post by electrochrisso »

Nice to see that gdiplus.lib is now included in the Windows lib folder of PureBasic, I wonder how many versions it's been sitting there and I didn't know it.
Is not in PB531, so it was introduced sometime after that.
PureBasic! Purely the best 8)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: ImagePlugin Module (UseWindowsImageDecoder / Encoder)

Post by wilbert »

electrochrisso wrote:Is not in PB531, so it was introduced sometime after that.
It probably was included with the introduction of the Vector library (PB 5.40) since that depends on GDIPlus.
For older PB versions, you can copy it from PB 5.40+ ( PureBasic\PureLibraries\Windows\Libraries folder ).
Windows (x64)
Raspberry Pi OS (Arm64)
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: ImagePlugin Module (UseWindowsImageDecoder / Encoder)

Post by walbus »

Hi wilbert
A first test say : works great !
Primary loading and saving Tiff, Gif, PNG, JPG, i have tested

I have see :
'Save as jpeg with quality 70'
'Encode as LZW compressed TIFF with 256 colors'
Great !

I test more to day, i must work firstly now a little.

A very, very good, helpfull and needfull work wilbert !

Best regards Werner
mestnyi
Addict
Addict
Posts: 1098
Joined: Mon Nov 25, 2013 6:41 am

Re: ImagePlugin Module (UseWindowsImageDecoder / Encoder)

Post by mestnyi »

with this code, you can open an animated gif

Code: Select all

; Если не установленно ComFramework раскоментируй эти строки
Macro DefineGUID(IID, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11)
  DataSection
    IID:
    Data.l Data1
    Data.w Data2, Data3
    Data.b Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11
  EndDataSection
EndMacro

DefineGUID(CLSID_ShellImageDatasFactory, $66e4e4fb, $f385, $4dd0, $8d, $74, $a2, $ef, $d1, $bc, $61, $78)
DefineGUID(IID_IShellImageDatasFactory, $9be8ed5c, $edab, $4d75, $90, $f3, $bd, $5b, $db, $b2, $1c, $82)

Interface IShellImageDatasFactory Extends IUnknown
  CreateIShellImageDatas(a.l) 
  CreateImageFromFile(a.p - unicode, b.l)
  CreateImageFromStream(a.l, b.l) 
  GetDatasFormatFromPath(a.l, b.l)
EndInterface

#CLSCTX_INPROC_SERVER = 1 ; не четная цыфра
CoCreateInstance_(?CLSID_ShellImageDatasFactory, #Null, #CLSCTX_INPROC_SERVER, ?IID_IShellImageDatasFactory, @*factory.IShellImageDatasFactory)

Interface IShellImageDatas Extends IUnknown
  Decode(a.l, b.l, c.l) 
  Draw(a.l, b.l, c.l)
  NextFrame()
  NextPage() 
  PrevPage() 
  IsTransparent() 
  IsAnimated() 
  IsVector() 
  IsMultipage()
  IsEditable() 
  IsPrintable() 
  IsDecoded()
  GetCurrentPage(a.l) 
  GetPageCount(a.l) 
  SelectPage(a.l) 
  GetSize(a.l) 
  GetRawDatasFormat(a.l)
  GetPixelFormat(a.l) 
  GetDelay(a.l) 
  GetProperties(a.l, b.l) 
  Rotate(a.l) 
  Scale(a.l, b.l, c.l)
  DiscardEdit() 
  SetEncoderParams(a.l) 
  DisplayName(a.l, b.l) 
  GetResolution(a.l, b.l)
  GetEncoderParams(a.l, b.l) 
  RegisterAbort(a.l, b.l) 
  CloneFrame(a.l) 
  ReplaceFrame(a.l)
EndInterface

#SHIMGDEC_DEFAULT = 0  ; четная цыфра
Global *Datas.IShellImageDatas


If OpenWindow(0, 0, 0, 400, 353, "Press ESC to quit", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar)
  AddWindowTimer(0, 1, 1)
  
  ContainerGadget(5,5,5,255,343,#PB_Container_Flat)
  CloseGadgetList()
  ;ImageGadget(5,5,5,255,343,0,#PB_Image_Border) ; нужно чтобы ImageGadget правильно показывало, без следов, а не на ContainerGadget-е
  ButtonGadget(1,265,4,130,20,"открыть")
  
EndIf

Global dc.l,rc.RECT
        

Procedure Timer()
  Static t
  Protected time
  
  If *Datas And *Datas\IsAnimated() = 0
    *Datas\GetDelay(@time);
    
    If t>time
      If *Datas\NextFrame()
        *Datas\SelectPage(0);
      EndIf
      
      InvalidateRect_(GadgetID(5),0, #True) 
      UpdateWindow_(GadgetID(5))
      *Datas\Draw(dc, @rc, @rc);
    
      t=0
    Else
      t=t+14
    EndIf
    
  EndIf       
EndProcedure
BindEvent(#PB_Event_Timer,@Timer())

Repeat
  
  Event  = WaitWindowEvent()
  gEvent = EventGadget()
  
  Select Event
      
    Case #PB_Event_Gadget
      If gEvent = 1
        wszPath.s = OpenFileRequester("Please select", "", "GIF files (*.gif)|*.gif", 1)
        *factory\CreateImageFromFile(wszPath, @*Datas)
        *Datas\Decode(#SHIMGDEC_DEFAULT, 0, 0);
        *Datas\GetSize(@rc\right);
        dc.l = GetDC_(GadgetID(5))
        *Datas\Draw(dc, @rc, @rc) ;
      EndIf           
  EndSelect
Until Event = #PB_Event_CloseWindow 
; IDE Options = PureBasic 5.11 (Windows - x86)
; CursorPosition = 59
; FirstLine = 20
; Folding = -
; EnableXP
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: ImagePlugin Module (UseWindowsImageDecoder / Encoder)

Post by wilbert »

mestnyi wrote:with this code, you can open an animated gif
IShellImageData is deprecated.
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Microsoft wrote:[This interface will eventually be unsupported. It is recommended that Windows GDI+ APIs be used in place of IShellImageData methods.]
You can also open an animated gif with GDI+ and access each frame.
It's just that for a PureBasic image decoder plugin it's not possible because they work with PB images which have no concept of multiple frames.

Personally I have no experience with windows components but if you are familiar with them, you might also want to look at the Windows Imaging Component.
It's available since Windows XP SP2 and has more capabilities.
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply