2016-01-23 14 views
15

Während ich einige Tests mit .gif Animationen in MATLAB durchführte, wurde mir klar, dass ich die Transparenz des Gifs irgendwie nicht lesen kann.Wie man ein animiertes GIF mit Alphakanal liest

Beispiel:

enter image description here

(Original source of the gif)

Wenn ich

[img,cmap]=imread('Finnandjake.gif'); 

img ist 4D mit einer redundanten 3. Dimension (komisch). Nach quetschen (img=squeeze(img);), wenn ich zeige es (imshow(img(:,:,30),cmap)):

enter image description here

Die Transparenz ist weg, als Hintergrund eine andere Farbe aus dem Bild verwenden, damit Funktionen zu löschen. Jedoch

[img,cmap,alpha]=imread('Finnandjake.gif'); 

gibt eine leere alpha zurück. Offensichtlich ist die Information des Alphas irgendwo im Bild, wie kann ich es in MATLAB lesen?

+1

Ich denke, dass Matlab die Transparenz für ein GIF-Bild nicht verwalten können. Von mathworks.com: 'imread (___) gibt zusätzlich die Bildtransparenz zurück. Diese Syntax gilt nur für PNG-, CUR- und ICO-Dateien. " – obchardon

+0

@obchardon Ich habe bemerkt, aber gibt es irgendeine Möglichkeit, eine gif-Datei mit den Alpha-Informationen in MATLAB zu laden? Es ist nur eine gif-Datei, es kann nicht so schwer sein –

+2

Ich wollte vorschlagen, die GIF zu konvertieren PNG mit Imagemagick und Lesen der PNGs in einer Schleife. Aber ich kann MATLAB nicht einmal dazu bringen, die Alpha-Ebene im PNG zu erkennen, obwohl sie * in der Datei * vorhanden ist. :-( – hbaderts

Antwort

9

/Update: Ich habe den Code unter MATLAB file exchange zur Verfügung gestellt. Die veröffentlichte Version ist kompatibel zu OCTAVE und enthält einige Dokumentationen.


Ich kam mit dieser Lösung auf. Rücksprungargumente sind die gestapelten Bilder, die Colormap und der Index, die der Transparenz entsprechen.

%do not use, instead use: http://www.mathworks.com/matlabcentral/fileexchange/55693-transparentgifread-filename- 
function [stack,map,transparent]=transparentGifRead(filename) 
if ~exist(filename,'file') 
    error('file %s does not exist',filename); 
end 
info=imfinfo(filename); 
%Check if color map for all frames is the same 
if any(any(any(diff(cat(3,info.ColorTable),[],3)))) 
    error('inconsistent color map') 
else 
    map=info(1).ColorTable; 
end 
%Check if transparent color for all frames is the same 
if any(diff([info.TransparentColor])) 
    error('inconsistent transparency information') 
else 
    transparent=info(1).TransparentColor-1; 
end 
import java.io.* 
str = javax.imageio.ImageIO.createImageInputStream(java.io.File(filename)); 
t = javax.imageio.ImageIO.getImageReaders(str); 
reader = t.next(); 
reader.setInput(str); 
numframes = reader.getNumImages(true); 
for imageix = 1:numframes 
    data = reader.read(imageix-1).getData(); 
    height = data.getHeight(); 
    width = data.getWidth(); 
    data2 = reader.read(imageix-1).getData().getPixels(0,0,width,height,[]); 
    if imageix == 1 
     stack=zeros(height,width,1,numframes,'uint8'); 
    end 
    %row major vs column major fix 
    stack(:,:,1,imageix) = reshape(data2,[width height]).';%' 
end 
str.close(); 
end 

Einige Demonstration Code, um die transparente Pixel grün zu färben:

[stack,map,transparent]=transparentGifRead('tr.gif'); 
map(transparent+1,:)=[0,1,0] %offset 1 because uint8 starts at 0 but indices at 1 
for frame=1:size(stack,ndims(stack)) 
    imshow(stack(:,:,frame),map); 
    pause(1/25); 
end 
+1

Zwei Probleme: 'x = fullfile (matlabroot, 'toolbox \ matlab \ imagesci', 'private', 'imgifinfo.m');' sollte 'x = fullfile sein (matlabroot, 'toolbox', 'matlab', 'imagesci ',' private ',' imgifinfo.m '); 'um plattformübergreifend zu arbeiten. Außerdem scheinen Sie einen Fehler mit den Bilddaten, die in die Colormap indiziert sind, zu haben. – horchler

+0

@horchler: Danke für die Rückmeldung, nur Werte verglichen und nicht realisiert meine Funktion zurückgegeben Doppel statt Uint8. Jetzt gibt es uint8 zurück, dort ist ein Offset von 1 zwischen Colormap und Integerwert vorgesehen. – Daniel

+1

Sie sollten 'info = iminfo (filename);' verwenden können, um Details wie die 'TransparentColor' -Eigenschaft für jeden Frame zu erhalten, anstatt eine private Funktion aufrufen zu müssen. – horchler