This code will create an atlas image and text file for every png image in your media folder and should be pretty easy to adapt for your purposes:
// Project: AtlasCreator
// Created: 2015-06-22
// set window properties
SetWindowTitle( "AtlasCreator" )
SetWindowSize( 1024, 768, 0 )
// set display properties
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )
// Create array
imageList as integer[]
file$ = GetFirstFile()
while file$<>""
if Lower(Right(file$, 3))="png"
imageList.insert(LoadImage(file$))
endif
file$ = GetNextFile()
endwhile
CreateAtlas("TestAtlas", imageList)
do
Print( "Done!" )
Sync()
loop
type boxType
name as string
id as integer
sx as integer
sy as integer
width as integer
height as integer
endtype
function CreateAtlas(name as string, imageList as integer[])
box as boxType[]
tVol = 0
maxW = -1
maxH = -1
memblockList as integer[]
for i=0 to imageList.length
memblockList.insert(CreateMemblockFromImage(imageList[i]))
next
for i=0 to memblockList.length
exists = -1
for j=0 to i-1
if MemblocksAreEqual(memblockList[i], memblockList[j])>0
exists = 1
endif
next
if exists<0
b as boxType
file$ = GetImageFilename(memblockList[i])
b.name = Left(file$, len(file$)-4)
b.id = memblockList[i]
b.width = GetImageWidth(b.id) + 2
b.height = GetImageHeight(b.id) + 2
box.insert(b)
if b.width>maxW then maxW = b.width
if b.height>maxH then maxH = b.height
tVol = tVol + (b.width * b.height)
endif
next
side = PowerOfTwo(Sqrt(tVol))
sideX = side*2
sideY = side
dim area[sideX-1,sideY-1] as integer
for x=0 to sideX-1
for y=0 to sideY-1
area[x,y] = 0
next
next
used as integer[]
used.length = box.length
for i=0 to box.length
used[i] = 0
next
done = 0
highest = -1
while done=0
best = -1
bestH = -1
found = 0
for i=0 to box.length
if used[i]=0
found = 1
if box[i].height>bestH
bestH = box[i].height
best = i
endif
endif
next
if found=0
done = 1
else
spaceFound = 0
used[best] = 1
for x=0 to sideX-1
for y=0 to sideY-1
if area[x,y]=0
ok = 1
for x1=x to x+box[best].width
for y1=y to y+box[best].height
if x1<sideX and y1<sideY
if area[x1,y1]=1
ok = 0
exit
endif
else
ok = 0
endif
next
if ok=0 then exit
next
if ok=1
for x1=x+1 to x+box[best].width
for y1=y+1 to y+box[best].height
area[x1,y1] = 1
next
next
box[best].sx = x
box[best].sy = y
spaceFound = 1
exit
endif
endif
next
if spaceFound=1 then exit
next
endif
endwhile
width = -1
for x=sideX-1 to 0 step -1
for y=0 to sideY-1
if area[x,y]=1
width = x + 1
exit
endif
next
if width>0 then exit
next
width = PowerOfTwo(width)
height = -1
for y=sideY-1 to 0 step -1
for x=0 to sideX-1
if area[x,y]=1
height = y + 1
exit
endif
next
if height>0 then exit
next
height = PowerOfTwo(height)
fn = OpenToWrite(name + ".atlas")
WriteLine(fn, "")
WriteLine(fn, name + ".png")
WriteLine(fn, "size: " + str(width) + "," + str(height))
WriteLine(fn, "format: RGBA8888")
WriteLine(fn, "filter: Linear,Linear")
WriteLine(fn, "repeat: none")
spr = CreateSprite(0)
FixSpriteToScreen(spr, 1)
ClearScreen()
for i=0 to box.length
WriteLine(fn, box[i].name)
WriteLine(fn, " rotate: false")
WriteLine(fn, " xy: " + str(box[i].sx+1) + ", " + str(box[i].sy+1))
WriteLine(fn, " size: " + str(box[i].width-2) + ", " + str(box[i].height-2))
WriteLine(fn, " orig: " + str(box[i].width-2) + ", " + str(box[i].height-2))
WriteLine(fn, " offset: 0, 0")
WriteLine(fn, " index: -1")
SetImageMinFilter(box[i].id, 0)
SetImageMagFilter(box[i].id, 0)
SetSpriteImage(spr, box[i].id)
SetSpriteSize(spr, box[i].width, box[i].height)
SetSpritePosition(spr, box[i].sx + 1, box[i].sy + 1)
DrawSprite(spr)
SetImageMinFilter(box[i].id, 1)
SetImageMagFilter(box[i].id, 1)
next
WriteLine(fn, "")
DeleteSprite(spr)
img = GetImage(0, 0, width, height)
SaveImage(img, name + ".png")
ClearScreen()
CloseFile(fn)
box.length = -1
endfunction
function PowerOfTwo(v)
s = 1
while s<v
s = s*2
endwhile
v = s
endfunction v
function MemblocksAreEqual(mem1, mem2)
size = GetMemblockSize(mem1)
s2 = GetMemblockSize(mem2)
if size<>s2
`message("size is wrong")
exitfunction -1
endif
w1 = GetMemblockInt(mem1, 0)
w2 = GetMemblockInt(mem2, 0)
if w1<>w2
`message("width is wrong")
exitfunction -1
endif
h1 = GetMemblockInt(mem1, 4)
h2 = GetMemblockInt(mem2, 4)
if h1<>h2
`message("height is wrong")
exitfunction -1
endif
for i=12 to size-1
r1 = GetMemblockByte(mem1, i)
r2 = GetMemblockByte(mem2, i)
inc i
g1 = GetMemblockByte(mem1, i)
g2 = GetMemblockByte(mem2, i)
inc i
inc i
b1 = GetMemblockByte(mem1, i)
b2 = GetMemblockByte(mem2, i)
inc i
inc i
a1 = GetMemblockByte(mem1, i)
a2 = GetMemblockByte(mem2, i)
inc i
if a1+a2>0
if r1<>r2
`message("red is wrong")
exitfunction -1
endif
if g1<>g2
`message("green is wrong")
exitfunction -1
endif
if b1<>b2
`message("blue is wrong")
exitfunction -1
endif
endif
next
endfunction 1
I should say I haven't tested the output much so you might want to check it does what it should...
It isn't perfect and won't rotate the images for best fit either but it should fit as many images as possible into a single power of two sized image most of the time.
Using AppGameKit V2 Tier 1