Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как программно разбить GIF на кадры?


Автор: Tiffany 1.8.2012, 14:08
Задачка на первый взгляд проста: взять gif-анимацию, разбить на картинки и сохранить их все по отдельности. Никак не могу подобрать библиотеку. Нашла информацию об ImageMagick, даже кое-как собрала.. Но возникли проблемы с подключением. 
Чем сейчас вообще пользуются для такого рода задач?
Пишу в 10 студии. Желательно кроссплатформенную. 

Автор: magesi 1.8.2012, 15:17
GIF использует LZW алгоритм, значит Вам нужно знать, как самим имплементировать этот алгоритм или искать либу, которая работает с LZW, также Вам следует прочитать соответствующий стандарт почитать, какая структура у ГИФа, у каждого ее кадра и как вообще происходит работа анимации ГИФа.

http://www.w3.org/Graphics/GIF/spec-gif89a.txt

ГИФ состоит из таблицы цветов, сам формат файла учить надо ( с какого бита идет инфа о LZW, а с какого сам raw ), а так же есть там табличка
Graphic Control Extension, которая отвечает за то, как должна работать анимация.

Так, что либо учите стандарт, либо ищите либы , которых на CodePlex, SourceForge - море.

Но , юзание либ освобождает от знаний в виду всяких готовы методов...


Автор: borisbn 1.8.2012, 18:29
http://qt-project.org/doc/qt-4.8/qmovie.html
Код
QMovie m( "filename.gif" );
int frameCount = m.frameCount();
for ( int i = 0; i < frameCount; i++ ) {
    m.jumpToNextFrame();
    QPixmap p = m.currentPixmap();
    p.save( QString( "frame %1" ).arg( i ) );
}

Автор: magesi 1.8.2012, 23:03
borisbn, куйня прикладная эти Ваши либы  smile кайфа ни какого от разработки )

в стиле

*УЙНЯ объект = new *УЙНИ()
объект.играть<ГИФ>(файл);

и весь прикладной мир в таком стиле )

Автор: borisbn 1.8.2012, 23:32
magesi, сдаюсь.
Код

memcpy( (void*)(unsigned long long *)(& (ptr + 143 * sizeof(char) ) ), (char*)(unsigned long*)(& ptr[ 99 ] ), count * sizeof( ptr[0] ) / sizeof( ppp[ 0 ] ) * sizeof( char ) );
unsigned char * p = (unsigned char *)( &( struct_ptr++ ) );
*p++ = 0;

это - существенно проще и понятней  smile 

Автор: magesi 1.8.2012, 23:53
borisbn, это достаточно понятно вообще-то ) лучше бы на haskell привел бы аналог  smile 

Автор: Earnest 2.8.2012, 06:16
magesi,  smile 
Но ты не совсем прав. Если тебе эта *УЙНЯ нужна как бантик на окне, то тратить время на его разбор вместо просто new ; Play и глупо, и кайфа никакого. Так можно год потратить на точение разнообразных лопат, и совершенно забыть, что нужно это было всего лишь для того, чтобы пользователю не скучно было ждать пока идет твоя супер-мега обработка. 

Автор: Tiffany 2.8.2012, 10:45
Шутники smile
Спасибо за ваши идеи, а я вот еще кое-что нашла. Правда, на С#.

http://www.codeproject.com/Articles/11505/NGif-Animated-GIF-Encoder-for-NET

Earnest права, как раз хотелось бы избежать разбора формата и прочих премудростей.
ImageMagick++ предлагает простой метод
Код

    readImages(&imageList, "picture.gif" );

, но никак не хочет внедряться, видимо из-за кривизны рук. А вот было бы здорово найти аналогичный метод разбиения. 

Автор: borisbn 2.8.2012, 10:50
Цитата(Tiffany @  2.8.2012,  10:45 Найти цитируемый пост)
Earnest прав

права  smile 

Автор: Tiffany 2.8.2012, 10:57
Упс  smile 
Исправилась!

Автор: SVN74 3.8.2012, 21:05
Модератор: 
Часть текста удалена как продолжение вырезанного срача

Добавлено @ 21:12
Tiffany, 
А Вы какую IDE используете?

Автор: SVN74 3.8.2012, 21:33
Цитата(borisbn @  3.8.2012,  21:29 Найти цитируемый пост)
не уловил... а как это поможет в помощи ТС с её проблемой?

Если Builder? - есть уже готовая библиотечка, там есть и доступ к кадрам...

Автор: borisbn 3.8.2012, 21:35
Цитата(SVN74 @  3.8.2012,  21:33 Найти цитируемый пост)
Если Builder? - есть уже готовая библиотечка, 

аааа. ясно. в принципе, я тоже советовал фреймворкозависимое - КуТю...

Автор: Amp 4.8.2012, 13:23
Emacs + latex smile

Автор: Tiffany 5.8.2012, 22:41
SVN74, 
Цитата(Tiffany @  1.8.2012,  14:08 Найти цитируемый пост)
Пишу в 10 студии. Желательно кроссплатформенную. 

 smile 

Автор: Earnest 6.8.2012, 08:02
Модератор: 
Тему почистила, может, излишне жестоко, но ей богу, достали! Вернулась с выходных, а тут такое развели! От жары, что ли?
Некоторые посты, вполне вменяемые, тоже были удалены, т.к. находились в контексте срача. Надеюсь, авторы не в претензии.


Автор: Tiffany 16.8.2012, 12:55
Всем еще раз спасибо за отклик.
В итоге свой выбор остановила на http://www.xdp.it/cximage.htm.

Разбиение производится следующим способом

Код

CxImage img;
img.SetRetreiveAllFrames(true);
img.Load("C:\\tmp.gif", CXIMAGE_FORMAT_GIF);

if(img.IsValid())
{
    for(int i = 0; i < img.GetNumFrames(); ++i)
    {
        if(img.GetFrame(i))
        {
            CxImage frame;
            frame.Copy(*img.GetFrame(i));
            if(!frame.IsGrayScale())    
                frame.IncreaseBpp(24);
            //frame.SetJpegQuality(100);
            char a_Newfilename[256];
            sprintf(a_Newfilename, "C:\\tmp%d.jpg", i);
            frame.Save(a_Newfilename, CXIMAGE_FORMAT_JPG);
        }
    }
}


Строкой 
Код

frame.SetJpegQuality(100);

можно регулировать качество жипега и, соответственно, его размер.

Поддержка необходимых форматов включается/отключается в ximacfg.h. Для jpg необходимо собрать библиотеку jpeg.lib (дополнительно к CxImage.lib). 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)