local src=app.open(app.params.source) local img=Image(src.cels[1].image) local target_h=tonumber(app.params.height) for pixel in img:pixels() do local c=pixel() if app.pixelColor.rgbaA(c)>=192 then pixel(app.pixelColor.rgba(app.pixelColor.rgbaR(c),app.pixelColor.rgbaG(c),app.pixelColor.rgbaB(c),255)) else pixel(0) end end local cells=dofile(app.params.boxes) local maxw,maxh=0,0 for _,box in ipairs(cells) do maxw,maxh=math.max(maxw,box.w),math.max(maxh,box.h) end local factor=math.min(40/maxw,target_h/maxh) local atlas=Image(144,64,ColorMode.RGB) local frames={} for index,box in ipairs(cells) do local crop=Image(box.w,box.h,ColorMode.RGB) crop:drawImage(img,Point(-box.x,-box.y)) local tmp=Sprite(box.w,box.h,ColorMode.RGB) tmp.cels[1].image=crop local w,h=math.max(1,math.floor(box.w*factor+0.5)),math.max(1,math.floor(box.h*factor+0.5)) app.command.SpriteSize{ui=false,width=w,height=h,method='nearest-neighbor'} local frame=Image(48,64,ColorMode.RGB) frame:drawImage(tmp.cels[1].image,Point(math.floor((48-w)/2),61-h)) table.insert(frames,frame) local col,row=(index-1)%3,math.floor((index-1)/3) atlas:drawImage(frame,Point(col*48,row*64)) tmp:close() end src:close() local out=Sprite(144,64,ColorMode.RGB) out.cels[1].image=atlas out:saveAs(app.params.output) out:close() local gif=Sprite(48,64,ColorMode.RGB) local seq={1,2,3,2} for i,frame_index in ipairs(seq) do if i>1 then gif:newFrame() end gif.cels[i].image=Image(frames[frame_index]) gif.frames[i].duration=0.16 end app.command.SpriteSize{ui=false,width=144,height=192,method='nearest-neighbor'} gif:saveAs(app.params.preview) gif:close() print('Exported '..#frames..' aligned pose frames; source max bounds '..maxw..'x'..maxh..'; uniform scale '..factor)