Web image loader class for 1.4

Hey - wrote this class some of you may find handy - its an image loader for web-based images. It grabs them from the web, and caches the results.


ImageLoader = class()

function ImageLoader:init(ns)
    namespace = ns or "global"
    --saveProjectInfo("Description", "Planetary Warfare")
    --saveProjectInfo("Author", "Tom Bortels")
    self.base = "http://github.com/bortels/planets/raw/master/images/"
    self.loadimg = image(100, 100)
    setContext(self.loadimg)
    background(118, 219, 50, 255)
    text("?", 50, 50)
    setContext()
    self.loading = 0
    self.imgs = {}
    self.imgs.unknown = self.loadimg
end

function ImageLoader:fetch(tag, name)
    local loaded = readProjectData("imageloader-" .. tag)
    if (loaded == nil) then
        self.imgs[tag] = self.loadimg
        print("fetching " .. tag)
        http.get(self.base .. name, self:newsuccess(tag))
        self.loading = self.loading + 1
    else
        self.imgs[tag]=readImage("Documents:" .. namespace .. "-" .. tag)
    end
end

function ImageLoader:newsuccess(tag)
    return function(body, result, headers)
        self.imgs[tag] = body
        saveImage("Documents:" .. namespace .. "-" .. tag, body)
        saveProjectData("imageloader-" .. tag, "ok")
        self.loading = self.loading - 1
    end
end

In setup(), you can call for images to be loaded like so:


    iload = ImageLoader("planets")
    iload:fetch("ship", "fighter.png")
    iload:fetch("homeworld", "garden.png")
    iload:fetch("planet", "planet.png")
    iload:fetch("t", "tomfezicon.jpeg")

Then when you draw the sprites, you use the tag:

        sprite(iload.imgs["homeworld"], WIDTH/2, HEIGHT - 200)
        sprite(iload.imgs["planet"], WIDTH/2, HEIGHT - 300)
        sprite(iload.imgs["ship"], WIDTH/2, HEIGHT - 400)
        sprite(iload.imgs["t"], WIDTH/2, HEIGHT - 500)

Why is this handy? Well - to do http.get, you have to do callbacks, and that can get somewhat ugly. This encapsulates the whole thing, letting you treat it as blocking. It also caches the graphics, so it’s very much a way to “download a spritepack” under program control (which means you can cut/paste code and still include graphics assets).

The “namespace” parameter should be unique to your object, so two objects loading “icon.jpg”, for example, won’t overwrite each other.

You’ll want to change the .base URL to where you have your images, of course.

Self.loading will be 0 when all of the images are loaded - you can inspect that if you want to make a “loading” page or something.

I think that’s everything relevant - I’ve stared at this so long I may be glossing over something, let me know if you have questions. Or - just look, it’s not that much code :slight_smile:

That’s very awesome @Bortels. I’d suggest removing your saveProjectInfo calls from init() so its more generic.

Heh - that’s what happens when I post at 1am. I’ve commented the out but left them as context.