Stitching an image together from square tiles in a WoW Wotlk addon

122 Views Asked by At

Context

For educational purposes, I decided to create a WoW - Wotlk Classic AddOn that displays different maps when opening the world map. I am new to Lua and this is a learning project.

My Addon directory structure with relevant files is as follows:

core.lua
embeds.xml
Libs
|-magick
  |- build
    |- ...
    |- imagick.so
TextureMaps
|-map1
  |-map1[level]_[1-12].tga
|-map2
|-map3

level is the number 1 or higher.

Goal

Since the game supports .blp or .tga images in power-of-two sizes, I converted mine in tiles of 256x256 and I need to display them in 4:3 ratio - 1024x768. (using full image directly displays a light green texture)

I first looked at libraries that could help me achieve this, and I found ImageMagick. I built it using the procedure there: https://github.com/isage/lua-imagick but WoW does not seem to recognize libraries that are not in .lua

Question

I need to programmatically stitch 12 tiles together into one image with a 4:3 aspect ratio. Otherwise, it will have to be a 1024x1024 with undesired transparent space.

How can I achieve this without using external libraries? math is supported in WoW addons

Here is the function I have so far:

local function stitchTiles(mapName, level)
    local tileSize = 256 -- the size of each tile
    local numTiles = 12 -- the number of tiles to stitch together
    local totalWidth = tileSize * 4 -- the total width of the stitched image
    local totalHeight = tileSize * 3 -- the total height of the stitched image
    local finalImg = magick.blankImage(totalWidth, totalHeight, "rgba(0,0,0,0)") -- create a blank image to stitch the tiles onto

    for i = 1, numTiles do
        local tileX = ((i - 1) % 3) * tileSize -- calculate the x position of the current tile
        local tileY = math.floor((i - 1) / 3) * tileSize -- calculate the y position of the current tile
        local tileImg = magick.loadImage(mapName .. level .. "_" .. i .. ".tga") -- load the current tile image
        finalImg:composite(tileImg, tileX, tileY) -- composite the tile onto the final image
    end

    return finalImg
end

Here is where I would call the function in the code:

    -- Load magick library
    local magick = require("imagick")

    -- Create a frame to display the map
    local mapFrame = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
    mapFrame:SetSize(512, 384) -- 4:3 map aspect ratio
    mapFrame:SetPoint("CENTER")
    mapFrame:SetFrameLevel(1000)

    -- Load the dungeon map texture
    local texture = mapFrame:CreateTexture(nil, "ARTWORK")
    texture:SetAllPoints(mapFrame)

    -- Constructs the full image and set it as texture
    texture:SetTexture(stitchTiles(dungeonName, dungeonLevel))
0

There are 0 best solutions below