Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Miniwindows ➜ Loading images from a memory buffer - new in version 4.42

Loading images from a memory buffer - new in version 4.42

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Mon 06 Jul 2009 01:18 AM (UTC)
Message
Version 4.42 of MUSHclient introduces a new feature - the ability to load PNG images already loaded into memory.

The reason for this is to make it easier for plugin authors to distribute a plugin with a batch of images (eg. icons) associated with it. Instead of having to install dozens of image files, you can now simply distribute a SQLite database, and the plugin can then extract out images, as required, from the database.

Below I show how you can do this.

This feature is only available to Lua scripting, as Lua supports strings which are 8-bit "clean", in other words with any value including 0x00.

First, an example of creating such a database:


-- open database on disk (in MUSHclient application directory)
db = assert (sqlite3.open (GetInfo (66) .. "images.db"))

-- create a table
assert (db:execute[[

  DROP TABLE IF EXISTS images;
  CREATE TABLE images (
    name  text, 
    image blob,
  PRIMARY KEY  (name)
  );

]])

local f = assert (io.open (GetInfo (66) .. "sword.png", "rb"))
local s = f:read ("*a")  -- read all of it
f:close ()  -- close it

local stmt = db:prepare ("INSERT INTO images VALUES (:name, :image)")

stmt:bind_names {name = "sword", image = s}
stmt:step()
stmt:reset()
stmt:finalize()

-- close database
db:close()



The code above creates or opens a database in the MUSHclient application directory called images.db.

Inside that is created a table (obviously you only do this once), which has the image name as a text field, and the image data as a blob (binary large object).

Next we read into memory an image from the MUSHclient application directory ("sword.png").

To make it easy to insert this data into the database, which may contain binary zeroes, or quote symbols, we use bind_names to bind the data to the name "image". This simplifies the INSERT INTO statement.

The step does the actual insert, putting the row into the database. If you wanted to add more rows, you would then re-execute the stmt:bind_names, stmt:step and stmt:reset for each additional image.

The code above would be done by the plugin author to create the images database.

Now, in the plugin, we can extract out images like this:


-- open database on disk
db = assert (sqlite3.open (GetPluginInfo (20) .. "images.db"))  -- open in plugins directory

-- make a window for testing
win = GetPluginID ()  -- get a unique name
WindowCreate (win, 0, 0, 600, 600, 12, 0, ColourNameToRGB("white"))  -- create window

-- find the sword image
for a in db:nrows([[SELECT * FROM images WHERE name = 'sword']]) do 
   WindowLoadImageMemory (win, "im", a.image)
   WindowDrawImage (win, "im", 20, 20, 0, 0, 1)  -- straight copy
end

WindowShow (win,  true)  -- show it 

-- close database
db:close()



The code above assumes it is running in a plugin, so it opens the images.db database in the same directory that the plugin is loaded into (a reasonable place to put the database). Then it find the "sword" image in the database, loads that into memory, and draws it from there.

Note that this only works for PNG images (not BMP ones). The PNG loader had provision for reading from memory, and in any case PNG files (being compressed) are likely to be smaller than BMP ones.

Also see http://www.gammon.com.au/forum/?id=9566 which describes loading sound effects from memory. Obviously you could store the sound effects and the images in the same database, which means you still only have one extra file to distribute (apart from the plugin itself).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #1 on Mon 06 Jul 2009 04:29 AM (UTC)
Message
(directed at everyone in general, not you specifically)

I imagine it would probably be a good idea to have a folder under plugins\ specifically for database files by convention, such as plugins\db\. That way, the main plugins just go in plugins\, and any and all resources they need can go in plugins\db\, with each .db file named after its plugin's ID, much like you'd do with miniwindows.

I like this addition! ^_^

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


9,557 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.