|
2 | 2 | clear |
3 | 3 |
|
4 | 4 | disp('-----------------------------------------------------------') |
5 | | -disp('|Beware, this code is for GNU Octave ONLY !!! |') |
| 5 | +disp('| Optimized Indexed GIF creator for GNU Octave (bzip) |') |
6 | 6 | disp('-----------------------------------------------------------') |
7 | 7 |
|
8 | 8 | pkg load image |
9 | 9 |
|
10 | 10 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
11 | | -%User parameters |
| 11 | +% User parameters |
12 | 12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
13 | | -target_gif_file='Animation.gif'; %target file for animated gif |
14 | | -gif_deadtime=0.05; %delay is seconds between pictures for animated gifs |
15 | | -gif_skip=1; %keep every 1 out of gif_skip image for gif |
16 | | -scaling_factor=1; %because you may want to change the image format which is 4x natively |
| 13 | +target_gif_file = 'Animation.gif'; % target file for animated gif |
| 14 | +gif_deadtime = 0.05; % delay in seconds between pictures |
| 15 | +gif_skip = 4; % keep every 1 out of gif_skip images |
| 16 | +scaling_factor = 1; % scale images if needed |
17 | 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
18 | 18 |
|
| 19 | +% Load file list |
19 | 20 | listing = dir('./Pictures/*.png'); |
20 | | -for i=1:1:length(listing) |
21 | | - name=listing(i).name; |
22 | | - disp(['Processing ',listing(i).name]); |
23 | | - [frame,map]=imread(['./Pictures/',name]); |
24 | | - frame=imresize(frame,scaling_factor,'nearest'); |
25 | | - if i==1 |
26 | | - imwrite(frame,map,target_gif_file,'gif', 'Loopcount',inf,'DelayTime',gif_deadtime,'Compression','bzip'); |
27 | | - else |
28 | | - if rem(i,gif_skip)==0 |
29 | | - imwrite(frame,map,target_gif_file,'gif','WriteMode','append','DelayTime',gif_deadtime,'Compression','bzip'); |
| 21 | +n_files = numel(listing); |
| 22 | + |
| 23 | +if n_files == 0 |
| 24 | + error("No PNG images found in ./Pictures/") |
| 25 | +end |
| 26 | + |
| 27 | +% Preload frames + maps |
| 28 | +frames = {}; |
| 29 | +maps = {}; |
| 30 | +disp('Reading and resizing images...') |
| 31 | +for i = 1:n_files |
| 32 | + name = listing(i).name; |
| 33 | + fprintf("Processing %s (%d/%d)\n", name, i, n_files); |
| 34 | + |
| 35 | + if rem(i,gif_skip) == 0 |
| 36 | + [frame, map] = imread(fullfile('./Pictures', name)); |
| 37 | + if scaling_factor ~= 1 |
| 38 | + frame = imresize(frame, scaling_factor, 'nearest'); |
30 | 39 | end |
| 40 | + frames{end+1} = frame; |
| 41 | + maps{end+1} = map; |
31 | 42 | end |
32 | 43 | end |
33 | 44 |
|
| 45 | +fprintf("Total frames to write: %d\n", numel(frames)); |
| 46 | + |
| 47 | +% Write GIF (with mandatory bzip compression) |
| 48 | +disp("Writing animated GIF...") |
| 49 | +imwrite(frames{1}, maps{1}, target_gif_file, ... |
| 50 | + "gif", "LoopCount", Inf, ... |
| 51 | + "DelayTime", gif_deadtime, ... |
| 52 | + "Compression", "bzip"); |
| 53 | + |
| 54 | +for i = 2:numel(frames) |
| 55 | + fprintf("Appending frame %d/%d\n", i, numel(frames)); |
| 56 | + imwrite(frames{i}, maps{i}, target_gif_file, ... |
| 57 | + "gif", "WriteMode", "append", ... |
| 58 | + "DelayTime", gif_deadtime, ... |
| 59 | + "Compression", "bzip"); |
| 60 | +end |
| 61 | + |
| 62 | +disp('-----------------------------------------------------------') |
34 | 63 | disp('End of conversion, enjoy your fancy animations !') |
| 64 | +disp('-----------------------------------------------------------') |
| 65 | + |
0 commit comments