Fetching an image from the .fuskin file via script?

User avatar
AndrewHazelden
Fusionator
Posts: 1391
Joined: Fri Apr 03, 2015 3:20 pm
Answers: 4
Location: West Dover, Nova Scotia, Canada
Been thanked: 59 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#16

Post by AndrewHazelden » Mon May 06, 2019 6:41 pm

Midgardsormr wrote:
Thu Dec 06, 2018 4:51 pm
The other was the potential of an interface that would automatically update if the skin changed by pulling its assets from the skin file itself. That way, if BMD decided to alter the icons again, my GUI would adapt automatically. Assuming they didn't change file names, of course, which is a largeish assumption.
Hi @Midgardsormr.

Here is a demo of a Fusion 16/Resolve 16 compatible script that extracts a series of image resources from the zipped Fuskin file and generates a new UI Manager based toolbar GUI. This script uses the new "ZipFile()" functionality that is only present in Fu16+ Lua scripting.

Code: [Select all] [Expand/Collapse] [Download] (FuskinButtonToolbarGUI.lua)
  1. --[[--
  2. FuSkin Button Toolbar GUI - v1.0 2019-05-06
  3. by Andrew Hazelden <andrew@andrewhazelden.com>
  4.  
  5. A Fusion 16/Resolve 16 compatible script that extracts a series of image resources from the zipped Fuskin file and generate a new UI Manager based toolbar GUI. This script uses the new "ZipFile()" functionality that is only present in Fu16+ Lua scripting.
  6.  
  7. --]]--
  8.  
  9.  
  10. -- Get the base filename from a filepath
  11. function GetFilename(mediaDirName)
  12.     local path, basename = string.match(mediaDirName, "^(.+[/\\])(.+)")
  13.    
  14.     return basename
  15. end
  16.  
  17. -- Where the unzipping magic happens
  18. function UnzipSkinFiles(zipFilename, extractFileTable, destFolder)
  19.     -- Create a file handler for the fuskin zipfile
  20.     local zip = ZipFile(zipFilename, false)
  21.    
  22.     -- Create the output folder
  23.     bmd.createdir(destFolder)
  24.    
  25.     -- Verify the zip file could be accessed
  26.     if zip:IsOpen() then
  27.         print("[Zip] [Opened Zip] " .. zipFilename)
  28.  
  29.         -- Scan through a list of files in a lua table
  30.         for i, extractFilename in ipairs(extractFileTable) do
  31.             -- Search for a file
  32.             if zip:LocateFile(extractFilename, true) then
  33.                 print("[Zip] [" .. tostring(i) .. "] [Found] " .. extractFilename)
  34.  
  35.                 -- Access the png image
  36.                 if zip:OpenFile() then
  37.                     print("[Zip]\t[Opened File] " .. tostring(zip:GetFileName()))
  38.  
  39.                     -- Print the file creation date as YYYY-MM-DD
  40.                     print("[Zip]\t[File Date] " .. os.date("%Y-%m-%d", zip:GetFileTime()))
  41.  
  42.                     filesize = tonumber(zip:GetFileSize())
  43.                     print("[Zip]\t[File Size] " .. tostring(filesize))
  44.  
  45.                     -- Create an FFI based buffer variable to hold the extracted file data
  46.                     -- Note: You might have to increase the "BUF_SIZE" value to allow larger then 65K files to be extracted in your scripts.
  47.                     local BUF_SIZE = 65536
  48.                     local buf = ffi.new("char[?]", BUF_SIZE)
  49.  
  50.                     -- Read the file from the zip
  51.                     -- The "zip:readfile()" size argument should be set to the value returned by "zip:GetFileSize()"
  52.                     local len = zip:ReadFile(buf, filesize)
  53.                     print("[Zip]\t[Bytes Read] " .. tostring(len))
  54.  
  55.                     -- Write the extracted file to disk
  56.                     extractFilePath = destFolder .. GetFilename(extractFilename)
  57.                     local extractFileOut = io.open(extractFilePath, "wb")
  58.                     if len > 0 then
  59.                         extractFileOut:write(ffi.string(buf, len), len)
  60.                         print("[Zip]\t[Extracted File] " .. tostring(extractFilePath))
  61.                     else
  62.                         print("[Zip]\t[Extracted File is Empty] ")
  63.                     end
  64.                     extractFileOut:close()
  65.  
  66.                     -- Close the zip
  67.                     zip:CloseFile()
  68.                 else
  69.                     print("[Zip]\t[Unable to Open File] " .. extractFilename)
  70.                 end
  71.             else
  72.                 print("[Zip]\t[Not Found] " .. extractFilename)
  73.             end
  74.         end
  75.     else
  76.         print("[Zip] [Unable to Open Zip] " .. zipFilename)
  77.     end
  78. end
  79.  
  80.  
  81. -- Build a UI Manager GUI
  82. function DisplayToolbar(destFolder)
  83.     local ui = fu.UIManager
  84.     local disp = bmd.UIDispatcher(ui)
  85.     local width,height = 730,60
  86.     local iconsMediumLong = {120,60}
  87.  
  88.     local win = disp:AddWindow({
  89.         ID = "FuSkinToolbarWin",
  90.         TargetID = "FuSkinToolbarWin",
  91.         WindowTitle = "Toolbar",
  92.         Geometry = {0, 0, width, height},
  93.         Spacing = 0,
  94.         Margin = 0,
  95.  
  96.         ui:VGroup{
  97.             ID = "root",
  98.            
  99.             -- Add your GUI elements here:
  100.             ui:HGroup{
  101.                 ui:HGroup{
  102.                     Weight = 0.7,
  103.  
  104.                     -- Add buttons that have an icon resource attached and no border shading
  105.                     ui:Button{
  106.                         ID = "IconButtonCamera",
  107.                         Text = "Camera",
  108.                         Flat = true,
  109.                         IconSize = {60, 60},
  110.                         Icon = ui:Icon{File = destFolder .. "camera@2x.png"},
  111.                         MinimumSize = iconsMediumLong,
  112.                         Checkable = false,
  113.                     },
  114.                     ui:Button{
  115.                         ID = "IconButtonCube",
  116.                         Text = "Cube",
  117.                         Flat = true,
  118.                         IconSize = {60, 60},
  119.                         Icon = ui:Icon{File = destFolder .. "cube@2x.png"},
  120.                         MinimumSize = iconsMediumLong,
  121.                         Checkable = false,
  122.                     },
  123.                     ui:Button{
  124.                         ID = "IconButtonCubeMap",
  125.                         Text = "CubeMap",
  126.                         Flat = true,
  127.                         IconSize = {60, 60},
  128.                         Icon = ui:Icon{File = destFolder .. "cubemap@2x.png"},
  129.                         MinimumSize = iconsMediumLong,
  130.                         Checkable = false,
  131.                     },
  132.                     ui:Button{
  133.                         ID = "IconButtonDirectionalLight",
  134.                         Text = "Directional Light",
  135.                         Flat = true,
  136.                         IconSize = {60, 60},
  137.                         Icon = ui:Icon{File = destFolder .. "directional_light@2x.png"},
  138.                         MinimumSize = iconsMediumLong,
  139.                         Checkable = false,
  140.                     },
  141.                 },
  142.             },
  143.  
  144.         },
  145.     })
  146.  
  147.     -- The window was closed
  148.     function win.On.FuSkinToolbarWin.Close(ev)
  149.         disp:ExitLoop()
  150.     end
  151.  
  152.     -- Add your GUI element based event functions here:
  153.     itm = win:GetItems()
  154.  
  155.     function win.On.IconButtonCamera.Clicked(ev)
  156.         print("[Camera][Button]")
  157.         comp:AddTool("Camera3D", -32768, -32768)
  158.     end
  159.  
  160.     function win.On.IconButtonCube.Clicked(ev)
  161.         print("[Cube][Button]")
  162.         comp:AddTool("Cube3D", -32768, -32768)
  163.     end
  164.  
  165.     function win.On.IconButtonCubeMap.Clicked(ev)
  166.         print("[CubeMap][Button]")
  167.         comp:AddTool("CubeMap", -32768, -32768)
  168.     end
  169.  
  170.     function win.On.IconButtonDirectionalLight.Clicked(ev)
  171.         print("[Directional Light][Button]")
  172.         comp:AddTool("LightDirectional", -32768, -32768)
  173.     end
  174.  
  175.     -- The app:AddConfig() command that will capture the "Control + W" or "Control + F4" hotkeys so they will close the window instead of closing the foreground composite.
  176.     app:AddConfig("FuSkinToolbarWin", {
  177.         Target {
  178.             ID = "FuSkinToolbarWin",
  179.         },
  180.  
  181.         Hotkeys {
  182.             Target = "FuSkinToolbarWin",
  183.             Defaults = true,
  184.  
  185.             CONTROL_W = "Execute{cmd = [[app.UIManager:QueueEvent(obj, 'Close', {})]]}",
  186.             CONTROL_F4 = "Execute{cmd = [[app.UIManager:QueueEvent(obj, 'Close', {})]]}",
  187.         },
  188.     })
  189.  
  190.     -- Display the window
  191.     win:Show()
  192.  
  193.     -- Keep the window updating until the script is quit
  194.     disp:RunLoop()
  195.     win:Hide()
  196.    
  197.     app:RemoveConfig("FuSkinToolbarWin")
  198.     collectgarbage()
  199. end
  200.  
  201.  
  202. function Main()
  203.     -- Zip file settings
  204.     skinZipFile = fusion:MapPath("FusionLibs:/Skins/Fusion.fuskin")
  205.  
  206.     -- Files to extract from the zip archive
  207.     imageList = {
  208.     "Tools/Icons/3d/camera@2x.png",
  209.     "Tools/Icons/3d/cube@2x.png",
  210.     "Tools/Icons/3d/cubemap@2x.png",
  211.     "Tools/Icons/3d/directional_light@2x.png",
  212.     }
  213.  
  214.     -- The output folder location
  215.     outFolderPath = fusion:MapPath("Temp:/Fusion/")
  216.  
  217.     -- Check that Fusion/Resolve 16+ is found
  218.     local ver = app:GetVersion()[1]
  219.     if ver >= 16 then
  220.         -- Extract the files from the fuskin
  221.         UnzipSkinFiles(skinZipFile, imageList, outFolderPath)
  222.  
  223.         -- Display a GUI
  224.         DisplayToolbar(outFolderPath)
  225.     else
  226.         print("[Error] Fusion/Resolve 16+ is required to use the Zip functionality.")
  227.     end
  228.    
  229.     print("[Done]")
  230. end
  231.  
  232.  
  233. -- Run the main function
  234. Main()
  235.  

Script Screenshot

FuskinButtonToolbarGUI.png
You do not have the required permissions to view the files attached to this post.

Tags:

User avatar
Midgardsormr
Fusionator
Posts: 1216
Joined: Wed Nov 26, 2014 8:04 pm
Answers: 3
Location: Los Angeles, CA, USA
Been thanked: 95 times
Contact:

Re: Fetching an image from the .fuskin file via script?

#17

Post by Midgardsormr » Mon May 06, 2019 7:14 pm

Well, somebody granted my wish, eh? Thanks for pointing it out, Andrew!