-- ImageGen supplies the pose. Preserve limb lengths; only the heels rise. local src=app.open(app.params.source) local img=Image(src.cels[1].image) local cells=dofile(app.params.boxes) for p in img:pixels() do local c=p() if app.pixelColor.rgbaA(c)>=192 then p(app.pixelColor.rgba(app.pixelColor.rgbaR(c),app.pixelColor.rgbaG(c),app.pixelColor.rgbaB(c),255)) else p(0) end end local maxw,maxh=0,0 for _,b in ipairs(cells) do maxw,maxh=math.max(maxw,b.w),math.max(maxh,b.h) end local factor=math.min(40/maxw,44/maxh) local atlas=Image(144,64,ColorMode.RGB) local frames={} local neutral,raised for i,b in ipairs(cells) do local crop=Image(b.w,b.h,ColorMode.RGB);crop:drawImage(img,Point(-b.x,-b.y)) local tmp=Sprite(b.w,b.h,ColorMode.RGB);tmp.cels[1].image=crop local w,h=math.floor(b.w*factor+0.5),math.floor(b.h*factor+0.5) app.command.SpriteSize{ui=false,width=w,height=h,method='nearest-neighbor'} local base=Image(48,64,ColorMode.RGB) base:drawImage(tmp.cels[1].image,Point(math.floor((48-w)/2),61-h));tmp:close() if i==1 then neutral=Image(base) elseif i==2 then -- Source pose 3 also drew longer trousers. Keep the complete neutral -- head, torso and legs; borrow only the bent sleeves/forearms from pose 2. local arms=base base=Image(neutral) for y=35,51 do for x=0,18 do base:putPixel(x,y,arms:getPixel(x,y)) end for x=30,47 do base:putPixel(x,y,arms:getPixel(x,y)) end end raised=Image(base) else base=Image(raised) end local out=Image(48,64,ColorMode.RGB) local lift=i-1 -- Move the complete figure by 0/1/2 pixels. Every shin/thigh/torso row -- retains its original size. The short toe contacts stay on the floor; -- only the underside of the boots changes as his heels lift. out:drawImage(base,Point(0,-lift)) for y=61-lift,60 do for x=0,47 do out:putPixel(x,y,base:getPixel(x,60)) end end frames[i]=out;atlas:drawImage(out,Point((i-1)*48,0)) end src:close() local sheet=Sprite(144,64,ColorMode.RGB);sheet.cels[1].image=atlas;sheet:saveAs(app.params.output);sheet:close() if app.params.preview_sheet then local strip=Sprite(144,64,ColorMode.RGB);strip.cels[1].image=atlas app.command.SpriteSize{ui=false,width=432,height=192,method='nearest-neighbor'} strip:saveAs(app.params.preview_sheet);strip:close() end local gif=Sprite(48,64,ColorMode.RGB) local sequence={1,2,3,2,1} local durations={0.65,0.12,1.0,0.12,0.3} for i,index in ipairs(sequence) do if i>1 then gif:newFrame() end gif.cels[i].image=frames[index];gif.frames[i].duration=durations[i] end app.command.SpriteSize{ui=false,width=144,height=192,method='nearest-neighbor'} gif:saveAs(app.params.preview);gif:close() print('Tiptoe heel lift0/1/2px; full figure translated without stretching limbs.')