nonlinear MLSE investigation trying hard to implment ML-based pre Equalization to find the branch metrics
147 lines
5.3 KiB
Matlab
147 lines
5.3 KiB
Matlab
classdef GifWriter < handle
|
|
%GIFWRITER Simple class to create GIFs from figures (parallel-safe)
|
|
%
|
|
% Example:
|
|
% g = GifWriter('Name','mySim','Parallel',true);
|
|
% parfor i = 1:10
|
|
% plot(rand(10,1));
|
|
% g.addFrame(1,i);
|
|
% end
|
|
% g.compile(1);
|
|
|
|
properties
|
|
Name (1,:) char = 'default' % GIF base name
|
|
DelayTime (1,1) double = 0.1 % Frame delay in seconds
|
|
Parallel (1,1) logical = false % Enable parallel-safe mode
|
|
BaseDir (1,:) char % Base directory for temp frames
|
|
OutputDir (1,:) char % Final GIF output directory
|
|
end
|
|
|
|
methods
|
|
%% Constructor
|
|
function obj = GifWriter(varargin)
|
|
% Parse name/value pairs
|
|
p = inputParser;
|
|
addParameter(p, 'Name', 'default', @ischar);
|
|
addParameter(p, 'DelayTime', 0.1, @isnumeric);
|
|
addParameter(p, 'Parallel', false, @islogical);
|
|
addParameter(p, 'OutputDir', fullfile(pwd, 'gif_output'), @ischar);
|
|
parse(p, varargin{:});
|
|
|
|
obj.Name = p.Results.Name;
|
|
obj.DelayTime = p.Results.DelayTime;
|
|
obj.Parallel = p.Results.Parallel;
|
|
obj.OutputDir = p.Results.OutputDir;
|
|
obj.BaseDir = fullfile(obj.OutputDir, 'tmp', obj.Name);
|
|
|
|
if ~exist(obj.BaseDir, 'dir'), mkdir(obj.BaseDir); end
|
|
if ~exist(obj.OutputDir, 'dir'), mkdir(obj.OutputDir); end
|
|
end
|
|
|
|
%%
|
|
function addFrame(obj, figInput, pos)
|
|
%ADDFRAME Add a figure frame to the GIF (supports parallel mode)
|
|
%
|
|
% Usage:
|
|
% obj.addFrame(figHandle)
|
|
% obj.addFrame(figNum)
|
|
% obj.addFrame(figHandle, pos) % parallel mode
|
|
% obj.addFrame(figNum, pos)
|
|
%
|
|
% In parallel mode, 'pos' must be a unique integer (loop index).
|
|
|
|
if nargin < 3, pos = []; end
|
|
|
|
% --- Resolve figure handle ---
|
|
if isnumeric(figInput)
|
|
% User passed a figure number
|
|
if ~ishandle(figInput)
|
|
warning('GifWriter:addFrame', 'Figure %d not found.', figInput);
|
|
return;
|
|
end
|
|
figHandle = figure(figInput);
|
|
elseif isa(figInput, 'matlab.ui.Figure')
|
|
figHandle = figInput;
|
|
else
|
|
error('GifWriter:addFrame:InvalidInput', ...
|
|
'Input must be a figure handle or figure number.');
|
|
end
|
|
|
|
% --- Parallel-safe frame writing ---
|
|
if obj.Parallel
|
|
if isempty(pos)
|
|
error('GifWriter:ParallelMode', ...
|
|
'In parallel mode, provide a unique ''pos'' identifier.');
|
|
end
|
|
|
|
% Directory for this figure number
|
|
frameDir = fullfile(obj.BaseDir, sprintf('fig_%d', figHandle.Number));
|
|
if ~exist(frameDir, 'dir')
|
|
mkdir(frameDir);
|
|
end
|
|
|
|
% File path for this frame
|
|
frameFile = fullfile(frameDir, sprintf('frame_%05d.png', pos));
|
|
|
|
% Export to PNG (headless-safe)
|
|
exportgraphics(figHandle, frameFile, 'Resolution', 150);
|
|
|
|
else
|
|
% --- Serial mode: append directly to GIF ---
|
|
gifFile = fullfile(obj.OutputDir, ...
|
|
sprintf('%s_fig_%d.gif', obj.Name, figHandle.Number));
|
|
|
|
% Export frame temporarily
|
|
tmpFile = [tempname, '.png'];
|
|
exportgraphics(figHandle, tmpFile, 'Resolution', 150);
|
|
img = imread(tmpFile);
|
|
delete(tmpFile);
|
|
|
|
% Append to GIF
|
|
[A, map] = rgb2ind(img, 256);
|
|
if ~isfile(gifFile)
|
|
imwrite(A, map, gifFile, 'gif', ...
|
|
'LoopCount', Inf, 'DelayTime', obj.DelayTime);
|
|
else
|
|
imwrite(A, map, gifFile, 'gif', ...
|
|
'WriteMode', 'append', 'DelayTime', obj.DelayTime);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
%% Compile all PNGs into a GIF (and clean up)
|
|
function compile(obj, fignum)
|
|
figDir = fullfile(obj.BaseDir, sprintf('fig_%d', fignum));
|
|
gifFile = fullfile(obj.OutputDir, sprintf('%s_fig_%d.gif', obj.Name, fignum));
|
|
|
|
frames = dir(fullfile(figDir, 'frame_*.png'));
|
|
if isempty(frames)
|
|
warning('GifWriter:NoFrames', 'No frames found for figure %d.', fignum);
|
|
return;
|
|
end
|
|
|
|
% Sort by frame name
|
|
[~, idx] = sort({frames.name});
|
|
frames = frames(idx);
|
|
|
|
% Combine into a GIF
|
|
for i = 1:numel(frames)
|
|
img = imread(fullfile(frames(i).folder, frames(i).name));
|
|
[A, map] = rgb2ind(img, 256);
|
|
if i == 1
|
|
imwrite(A, map, gifFile, 'gif', ...
|
|
'LoopCount', Inf, 'DelayTime', obj.DelayTime);
|
|
else
|
|
imwrite(A, map, gifFile, 'gif', ...
|
|
'WriteMode', 'append', 'DelayTime', obj.DelayTime);
|
|
end
|
|
end
|
|
|
|
% Clean up temporary frames
|
|
rmdir(figDir, 's');
|
|
end
|
|
end
|
|
end
|