function bytes = figToImStream(varargin)   
%     figToImStream Streams out a snapshot of a figure represented by 
%       a byte array encoded in the format specified. 
%
%     figToImStream
%       figToImStream alone creates a signed byte array with the png data 
%       for the current figure.  The size and position of the printed 
%       output depends on the figure's PaperPosition[mode] properties.
%
%     figToImStream('figHandle', <Figure Handle>, ...)
%       You can optionally specific the figure output to be used.
%       The Default is the current image
%
%     figToImStream('imageFormat', <imageFormat>, ...)
%       You can optionally specify an image format to convert to.
%       The valid types are:
%           png
%           jpg
%       The Default is png
%
%     figToImStream('outputType', <outputType>)
%       You can optionally specify an output data type for the bytes.
%       The valid types are:
%           int8    (signed byte)   Used for the java primitive Byte
%           uint8   (unsigned byte) Used for the .NET primitive Byte
%       The default is int8
%
%      figToImStream( ... )
%        Same as above only this is a comma separated parenthesized 
%        argument list. It allows the passing of variables for any or all 
%        of the input arguments.
%
%   Examples:
%   
%   Convert the current figure to a signed png byte array:
%       surf(peaks)
%       bytes = figToImStream;
%   
%   Convert a specific figure to an unsigned jpg byte array:
%       f = figure;
%       surf(peaks)
%       bytes = figToImStream('figHandle', f, ...
%                             'imageFormat', 'jpg', ...
%                             'outputType', 'uint8');
%

% Copyright 2021 The MathWorks, Inc.

    % First parsing: check data type of imageFormat and outputType
    p = inputParser;
       
    %If no figure is passed in use the current figure
    p.addOptional('figHandle',get(0,'CurrentFigure'), ...
        @(x)~isempty(x) && ishghandle(x) && strcmp(get(x,'type'),'figure'))
    
    %If no image format is passed in use PNG
    p.addOptional('imageFormat','png', ...
        @(x)validateattributes(x,{'char','string'},{'scalartext'}, ...
        'figToImStream','imageFormat'))

    %If no outputType is specified use int8
    p.addOptional('outputType','int8', ...
        @(x)validateattributes(x,{'char','string'},{'scalartext'}, ...
        'figToImStream','outputType'))
    p.parse(varargin{:});
    
    % Ensure imageFormat is a valid option
    if ~any(strcmpi(p.Results.imageFormat,{'png','jpg'}))
        error(message('Compiler:figToImStream:InvalidImageFormat', ...
            char(p.Results.imageFormat)))
    end
    
    % Ensure outputType is a valid option
    if ~any(strcmpi(p.Results.outputType,{'int8', 'uint8'}))
        error(message('Compiler:figToImStream:InvalidOutputType', ...
            char(p.Results.outputType)))
    end
    
    % Check that a figure exists 
    %(if you clear all variables there is no GCF)
    if(isempty(p.Results.figHandle))
        error(message('Compiler:figToImStream:InvalidFigureHandle'));
    end
    
    % create tempfile for image writing
    tmpFile = fullfile([convertStringsToChars(tempname), '.', convertStringsToChars(p.Results.imageFormat)]);
    
    % delete on exit
    deleteFile = onCleanup(@() delete(tmpFile));
    
    % save background color
    color = get(p.Results.figHandle,'Color');
    
    % Maintain size
    size = p.Results.figHandle.ScreenPixelsPerInch;

    % Call exportgraphics to write the tmpFile
    exportgraphics(p.Results.figHandle,tmpFile,'BackgroundColor',color,'Resolution',size);
    
    % Read the image file returning in bytes.
    s = dir(tmpFile);
    fileSize = s.bytes;
    fid = fopen(tmpFile, 'r');
    data= fread(fid, fileSize,'uint8=>uint8');
    fclose(fid);
    bytes = typecast(data,convertStringsToChars(p.Results.outputType));
end
