2016-01-23 3 views
15

Выполняя некоторые тесты с анимацией .gif в MATLAB, я понял, что каким-то образом я не могу прочитать прозрачность gif.Как читать анимированный gif с альфа-каналом

Пример:

enter image description here

(Original source of the gif)

Если я

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

img является 4D с резервированием 3-го измерения (странно). После выдавливания его (img=squeeze(img);), если я его показать (imshow(img(:,:,30),cmap)):

enter image description here

прозрачность исчезает, используя другой цвет из изображения в качестве фона, тем самым удаляя функции. Однако

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

возвращает пустой alpha. Очевидно, что информация о альфе находится где-то в изображении, как я могу ее прочитать в MATLAB?

+1

Я думаю, что MATLAB не может управлять прозрачности для GIF-изображения. Из mathworks.com: 'imread (___) дополнительно возвращает прозрачность изображения. Этот синтаксис применим только к файлам PNG, CUR и ICO. « – obchardon

+0

@obchardon Я заметил, но тогда есть ли способ загрузить GIF-файл в MATLAB с альфа-информацией? Его просто файл gif, это не может быть так сложно –

+2

Я хотел предложить конвертировать GIF в PNG с помощью Imagemagick и считывать PNG в цикле. Но я даже не могу заставить MATLAB распознавать слой Alpha в PNG, хотя он * присутствует * в файле. :-( – hbaderts

ответ

9

/Обновление: Я сделал код в MATLAB file exchange. Опубликованная версия совместима с OCTAVE и поставляется с некоторой документацией.


Я придумал это решение. Возвращаемые аргументы - это стоп-кадры, цветовая палитра и индекс, соответствующие прозрачности.

%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 

Некоторые демонстрационное раскрасить прозрачные пикселы зеленый:

[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

Два вопроса: 'x = fullfile (matlabroot, 'toolbox \ matlab \ imagesci', 'private', 'imgifinfo.m');' должно быть 'x = fullfile (matlabroot, 'toolbox', 'matlab', 'imagesci ',' private ',' imgifinfo.m '); 'работать на межплатформенной платформе. Кроме того, у вас, похоже, есть ошибка «один за другим» с данными изображения, индексированными в цветовой палитре. – horchler

+0

@horchler: Спасибо за обратную связь, просто сравнили значения и не осознали, что моя функция возвратила удвоение вместо uint8. Теперь он возвращает uint8, там предусмотрено смещение 1 между значением colormap и integer. – Daniel

+1

Вы должны иметь возможность использовать 'info = iminfo (filename);', чтобы получить информацию, такую ​​как свойство TransparentColor для каждого фрейма, а не для вызова частной функции. – horchler

Смежные вопросы