I'd want to create a GIF that counts down for 60 seconds. I could use photoshop but don't want to go through the hassle of creating new layers for each number.
I'm looking for a way to automatically generate a GIF (or images that I can combine into a GIF after the fact) that counts down from 60 to 0.
I'll accept any answer that fulfills these requirements.
I post this AIR code as an education exercise to the reader. The base idea is to use ActionScript to render text via the TextField
clas within a Sprite
, use Flash's ability to render any DisplayObject to static bitmap data and then use a 3rd-party open-source lib to convert each rendered frame to a gif.
Note: You could save each BitmapData frame to a file so you could use an external gif creation tool.
package {
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.filesystem.File;
import flash.filesystem.FileStream;
import flash.filesystem.FileMode;
import org.bytearray.gif.encoder.GIFEncoder;
import org.bytearray.gif.player.GIFPlayer;
public class Main extends Sprite {
var defaultFormat:TextFormat = new TextFormat();
var background:Sprite = new Sprite();
var countdownText = new TextField();
var fsize:int = 125;
var xsize:int = 100;
var ysize:int = 100;
public function Main():void {
defaultFormat.font = "Arial";
defaultFormat.size = fsize;
defaultFormat.color = 0xffffff;
var encoder:GIFEncoder = new GIFEncoder();
encoder.setRepeat(0);
encoder.setDelay(1000);
encoder.start();
setupCounterDisplay();
var startFrom:uint = 60;
var startColor:uint = 255;
for (var i:int = startFrom; i > -1; i--) {
var colorRGB:uint = (startColor / startFrom) * i;
encoder.addFrame(createCounterDisplay(i, ( colorRGB << 16 ) | ( colorRGB << 8 ) | colorRGB ) );
}
encoder.finish();
removeChild(background);
saveGIF("CounterDown.gif", encoder.stream);
playGIF(encoder.stream);
}
private function playGIF(data:ByteArray):void {
data.position = 0;
var player:GIFPlayer = new GIFPlayer();
player.loadBytes(data);
addChild(player);
}
private function saveGIF(fileName:String, data:ByteArray):void {
var outFile:File = File.desktopDirectory;
outFile = outFile.resolvePath(fileName);
var outStream:FileStream = new FileStream();
outStream.open(outFile, FileMode.WRITE);
outStream.writeBytes(data, 0, data.length);
outStream.close();
}
private function padString(string:String, padChar:String, finalLength:int, padLeft:Boolean = true):String {
while (string.length < finalLength) {
string = padLeft ? padChar + string : string + padChar;
}
return string;
}
private function setupCounterDisplay():void {
var xsize:int = 100;
var ysize:int = 100;
background.graphics.beginFill(0x000000, 1);
background.graphics.drawCircle(xsize, ysize, ysize);
background.graphics.endFill();
countdownText.defaultTextFormat = defaultFormat;
countdownText.border = true;
countdownText.borderColor = 0xff0000;
background.addChild(countdownText);
this.addChild(background);
}
private function createCounterDisplay(num:int, color:uint):BitmapData {
background.graphics.beginFill(0x000000, 1);
background.graphics.drawCircle(xsize, ysize, ysize);
background.graphics.endFill();
defaultFormat.color = color;
countdownText.defaultTextFormat = defaultFormat;
countdownText.text = padString(num.toString(), "0", 2);
countdownText.autoSize = "center";
countdownText.x = countdownText.width / 5;
countdownText.y = countdownText.height / 5;
var bitmap:BitmapData = new BitmapData(countdownText.width * 1.5, countdownText.height * 1.5, true);
bitmap.draw(background);
return bitmap;
}
}
}
Gif library via : https://code.google.com/p/as3gif/wiki/How_to_use