Skip to main content
Inspiring
December 1, 2022
Answered

Possible to export KEYFRAMES as individual images?

  • December 1, 2022
  • 2 replies
  • 2506 views

In my timeline, I have frames that are sometimes on 2's, somtimes 4's, sometimes holding for dozens of frames. When I do "Export Movie" as PNG Sequence, it makes an image for every frame on 1's. For example, for the keyframe that is 4 frames long, it's exporting 4 identical images of that keyframe, rather than just 1 image for that keyframe. 

Is it possible so that the exported images reflect the keyframes, rather than every single 1 frame? 

Thank you.

Correct answer JoãoCésar17023019

Hi.

 

You just need to copy the code below, open up a text editor, paste the code and save it to a file ending in .jsfl.

 

Then you can:

- Double click on the file;

- Or drag and drop it over Animate's IDE;

- Or place it in the Commands folder to run it.

 

To run the code from the commands folder, place it in one of the following paths:

 

macOS:

/Users/<USER>/Library/Application Support/Adobe/<ANIMATE_VERSION>/<LANGUAGE>/Configuration/Commands

E.g.:

/Users/johndoe/Library/Application Support/Adobe/Animate 2023/en_US/Configuration/Commands

 

Windows:

<BOOT_DEVICE>\Users\<USER>\AppData\Local\Adobe\Animate <ANIMATE_VERSION>\<LANGUAGE>\Configuration\Commands

E.g.:

C:\Users\johndoe\AppData\Local\Adobe\Animate 2021\en_US\Configuration\Commands

 

Then you can run the command in Animate by going to Commands > Your Command Name.

 

Export Keyframes as PNGs.jsfl. (the code has been updated in 12/02/2022)

var dom = fl.getDocumentDOM();
var timeline = dom.getTimeline();
var layers = timeline.layers;
var baseLayer = 0; // change this number if the first layer is a folder or other type that possibly doesn't have frames
var frames = layers[baseLayer].frames;
var filePrefix = dom.name.replace(".fla", "") + "_"; // the prefix doesn't need to contain the FLA name
var digits = 2; // 01, 001, 0002...
var folder;

function main()
{	
	if (!dom)
	{
		alert("Please open up a FLA first.");
		return;
	}
	
	folder = fl.browseForFolderURL("Choose an output directory.");

	if (!folder)
	{
		alert("No folder selected.");
		return;
	}

	var i;
	
	for (i = 0; i < frames.length; i++)
	{
		timeline.currentFrame = i;
		lookForKeyframes(i);
	}
}

function lookForKeyframes(frameIndex)
{
	var i, layer;
	
	for (i = 0; i < layers.length; i++)
	{
		layer = layers[i];
		
		if (layer.layerType === "folder")
			continue;
		
		var frame = layer.frames[frameIndex];
		
		if (!frame)
			continue;

		if (frame.startFrame == frameIndex && !frame.isEmpty)
		{
			dom.exportPNG(folder + "/" + filePrefix + zeropad((frameIndex + 1), digits) + ".png", true, true);
			break;
		}
	}
}

function zeropad(number, length)
{
    var str = '' + number;
	
    while (str.length < length)
		str = '0' + str;
   
    return str;
}

main();

 

JSFL file download:

https://bit.ly/3ER3YEC

 

There's one edge case that I found in which the code won't detect a change in the visual of the timeline. I'll update the code if I can think of a solution.

 

Please let us know if you have any further questions.

 

Regards,

JC

2 replies

JoãoCésar17023019
Inspiring
December 1, 2022

Hi.

 

Save the code below in a .jsfl file and run it. I didn't test it throughly though.

 

The PNG settings are the same from File > Export > Export Image (Legacy)....

 

Export Keyframes as PNGs.jsfl

var dom = fl.getDocumentDOM();
var timeline = dom.getTimeline();
var layers = timeline.layers;
var baseLayer = 0; // change this number if the first layer is a folder or other type that possibly doesn't have frames
var frames = layers[baseLayer].frames;
var filePrefix = dom.name.replace(".fla", "") + "_"; // the prefix doesn't need to contain the FLA name
var zeros = 2; // 01, 001, 0002...
var folder;

function main()
{	
	if (!dom)
	{
		alert("Please open up a FLA first.");
		return;
	}
	
	folder = fl.browseForFolderURL("Choose an output directory.");

	if (!folder)
	{
		alert("No folder selected.");
		return;
	}

	var i;
	
	for (i = 0; i < frames.length; i++)
	{
		timeline.currentFrame = i;
		lookForKeyframes(i);
	}
}

function lookForKeyframes(frameIndex)
{
	var i, layer;
	
	for (i = 0; i < layers.length; i++)
	{
		layer = layers[i];
		
		if (layer.layerType === "folder")
			continue;
		
		var frame = layer.frames[frameIndex];

		if (frame.startFrame == frameIndex && !frame.isEmpty)
		{
			dom.exportPNG(folder + "/" + filePrefix + zeropad(frameIndex, zeros) + ".png", true, true);
			break;
		}
	}
}

function zeropad(number, length)
{
    var str = '' + number;
	
    while (str.length < length)
		str = '0' + str;
   
    return str;
}

main();

 

I hope it helps.

 

Regards,

JC

YompaAuthor
Inspiring
December 2, 2022

Thank you.

How do I save the code in a .jsfl file? Sorry, I've never used code in Adobe Animate before.

YompaAuthor
Inspiring
December 2, 2022

Hi.

 

You just need to copy the code below, open up a text editor, paste the code and save it to a file ending in .jsfl.

 

Then you can:

- Double click on the file;

- Or drag and drop it over Animate's IDE;

- Or place it in the Commands folder to run it.

 

To run the code from the commands folder, place it in one of the following paths:

 

macOS:

/Users/<USER>/Library/Application Support/Adobe/<ANIMATE_VERSION>/<LANGUAGE>/Configuration/Commands

E.g.:

/Users/johndoe/Library/Application Support/Adobe/Animate 2023/en_US/Configuration/Commands

 

Windows:

<BOOT_DEVICE>\Users\<USER>\AppData\Local\Adobe\Animate <ANIMATE_VERSION>\<LANGUAGE>\Configuration\Commands

E.g.:

C:\Users\johndoe\AppData\Local\Adobe\Animate 2021\en_US\Configuration\Commands

 

Then you can run the command in Animate by going to Commands > Your Command Name.

 

Export Keyframes as PNGs.jsfl. (the code has been updated in 12/02/2022)

var dom = fl.getDocumentDOM();
var timeline = dom.getTimeline();
var layers = timeline.layers;
var baseLayer = 0; // change this number if the first layer is a folder or other type that possibly doesn't have frames
var frames = layers[baseLayer].frames;
var filePrefix = dom.name.replace(".fla", "") + "_"; // the prefix doesn't need to contain the FLA name
var digits = 2; // 01, 001, 0002...
var folder;

function main()
{	
	if (!dom)
	{
		alert("Please open up a FLA first.");
		return;
	}
	
	folder = fl.browseForFolderURL("Choose an output directory.");

	if (!folder)
	{
		alert("No folder selected.");
		return;
	}

	var i;
	
	for (i = 0; i < frames.length; i++)
	{
		timeline.currentFrame = i;
		lookForKeyframes(i);
	}
}

function lookForKeyframes(frameIndex)
{
	var i, layer;
	
	for (i = 0; i < layers.length; i++)
	{
		layer = layers[i];
		
		if (layer.layerType === "folder")
			continue;
		
		var frame = layer.frames[frameIndex];
		
		if (!frame)
			continue;

		if (frame.startFrame == frameIndex && !frame.isEmpty)
		{
			dom.exportPNG(folder + "/" + filePrefix + zeropad((frameIndex + 1), digits) + ".png", true, true);
			break;
		}
	}
}

function zeropad(number, length)
{
    var str = '' + number;
	
    while (str.length < length)
		str = '0' + str;
   
    return str;
}

main();

 

JSFL file download:

https://bit.ly/3ER3YEC

 

There's one edge case that I found in which the code won't detect a change in the visual of the timeline. I'll update the code if I can think of a solution.

 

Please let us know if you have any further questions.

 

Regards,

JC


Wow, this is exactly what I needed! It works.

Thank you so much for this!

kglad
Adobe Expert
December 1, 2022

that wouldn't make sense.  

 

if you want an image's duration to be one frame, make it a 1 frame image. or why make if more than 1frame?

YompaAuthor
Inspiring
December 1, 2022

You don't know what I'm using this for, and trust me, it makes sense.

I'm simply asking if this is possible.

kglad
Adobe Expert
December 1, 2022

no, afaik it's not.