Displaying GIF Image Matlab
144 views (last 30 days)
Show older comments
I tried using this code
[X,map] = imread('electricity.gif');
imshow(X,map)
I also tried looking at online help but it does not solve my problem.
Thank you
6 Comments
Image Analyst
on 6 Feb 2021
@Maram Abd, scroll down to see the "Answers". These are just "Comments" up here which are typically used to ask the poster to clarify the question and/or attach missing data or code. Steve's Image Processing Blog in the blog section here has also discussed GIF images
Accepted Answer
Image Analyst
on 21 Apr 2012
This will play a GIF but not with the colormap or in some axes control that you specify the handle of - it brings up the movie player:
fullFileName = 'C:\Users\Zach\Pictures\GIFs\AnimatedGifs\electricity.gif';
[gifImage cmap] = imread(fullFileName, 'Frames', 'all');
size(gifImage)
implay(gifImage);
5 Comments
Walter Roberson
on 23 Apr 2019
colormaps read in from GIF represent colors in the range 0 to 1, rather than integers 0 to 255.
DGM
on 9 Apr 2023
Edited: DGM
on 9 Apr 2023
The first example is not correct for any GIF. Gray or colored, there is no reason to assume that any given color table is ordered in a linear sequence by intensity. Consequently, there's no reason to assume that the index array should be rendered as a grayscale image.
[inpict CT] = imread('lenagrayunordered.gif');
imshow(inpict) % the index array is not an intensity image
imshow(inpict,CT) % use the CT
The second example only works for multiframe GIFs where all frames share the same colortable as the CT calculated for frame 1 (i.e. either the GCT or LCT1). That said, this GIF is a rare case where you have a color image sequence with no LCTs defined in the file. In this instance, the file could incidentally be read with the CT for frame 1 and no one would know that the procedure would otherwise fail with most other images.
Consider the following image. If we were to read it as above, this is what you'd get on the right. It's not even remotely correct.
So how would you read an image? Read the index data, and then read the remaining data from imfinfo(). If there's no need to convert the image and store an RGB copy, then don't. If there is, then don't do it in the display loop.
% this is the coalesced image included
fullFileName = 'CB2.gif';
% i'm not going to bother reading CT1 here
gifImage = imread(fullFileName, 'Frames', 'all');
% get all the colortables from imfinfo()
S = imfinfo(fullFileName);
numImages = numel(S);
% set up figure with a blank image
hi = imshow(zeros(size(gifImage(:,:,1,1))));
hi.CDataMapping = 'direct';
for k = 1 : numImages
% updating the object takes much less time
% and so frame delays are more accurate
hi.CData = gifImage(:,:,:,k);
colormap(S(k).ColorTable)
caption = sprintf('Frame %#d of %d', k, numImages);
title(caption);
drawnow;
% use the specified frame delays
pause(S(k).DelayTime/100)
end
That's normally the straightforward answer, but there are two complications that prevent it from being directly usable. First, R2018b introduced a bug in imread() that makes it impossible to read many multiframe GIFs correctly without modifying private function files. I've railed about that enough to know that nobody cares.
If we work around the bugs to read the file, we'll still get this junk from imread(). The second problem is that the given GIF in particular is heavily optimized. Imread() has never been good at reading optimized GIFs correctly. In this case, it's mishandling transparent regions in certain frames depending on their disposal method.
However, if we coalesce the image externally, it can be read just fine.
While it's not an issue for this image, coalescing is often a lossy process if we're forced by the format to stay in 8-bit indexed color. While that's a limitation of any external tool that has to rewrite the coalesced data to a new GIF, imread() has the opportunity to output to truecolor RGB or a wider indexed format, but it simply doesn't.
If I wanted to read that GIF, how would I do it? As much as it's crippled by the bugs in readgif.m, at least MIMT gifread() is simple to use.
inpict = gifread('Colored balls.gif','coalesce'); % output is 4D RGB
At that point, inpict is a 4D RGB image and if you wanted to wait for implay() to load, you could use it.
More Answers (2)
Walter Roberson
on 21 Apr 2012
Edited: Walter Roberson
on 6 Feb 2017
GIF Player from File Exchange
3 Comments
Image Analyst
on 15 Feb 2020
current_frame is probably an RGB image, and transparent_color might be a 3 element vector so you can't compare them that way. You might have to compare one color channel at a time
redMask = currentFrame(:, :, 1) == transparent_color(1);
greenMask = currentFrame(:, :, 2) == transparent_color(2);
blueMask = currentFrame(:, :, 3) == transparent_color(3);
If you want an overall mask where all 3 are true, then AND them together
mask = redMask & greenMask & blueMask;
DGM
on 4 May 2022
Edited: DGM
on 4 May 2022
FWIW, that error was an error internal to readgif(), which is used internally by imread(). At least as of R2019b, current_frame should be an indexed image during this test (if I recall correctly), and transparent_color should then be a scalar as defined in the file/frame header.
I don't exactly know why readgif() breaks in this one case that nobody needs solved anymore. The file isn't the most common sort of arrangement. There may be GIF functionality imread() doesn't support, and some things it really just can't support in an ideal way due to the conventions for image handling in MATLAB. So don't be surprised if readgif() breaks or returns garbage.
For what it's worth, the file can be re-saved using 'donotspecify' disposal instead of 'leaveinplace', and it reads fine and looks the same.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!