![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
igor_bogomolov |
![]() ![]()
Сообщение
#1
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Привет всем.
Недавно задался вопросом, как можно средствами Qt вытащить кадр из gif. Оказалось, что для этого существует класс QImageReader. Для работы с графическими файлами поддерживающих анимацию, есть методы, которые позволяют нам узнать, сколько кадров содержит файл, период обновления кадров, возможно ли перейти на кадр с определенным номером, и т.д. Но, при работе с этими методами возникли некоторые "трудности". методы Цитата int QImageReader::loopCount () const всегда возвращают ноль, т.е. мы не можем узнать, сколько реально кадров содержит файл.int QImageReader::imageCount () const Цитата bool QImageReader::jumpToImage ( int imageNumber ) всегда возвращают false, и мы не знаем, можем ли мы считывать следующий кадр или нет. Усложняемся все тем, что если мы производим лишнюю операцию чтения, возникает непонятная для меня ошибка, и даже если мы снова сделаем setFileName, считать мы больше ничего не сможем. Т.е. новый цикл анимации не начнем.bool QImageReader::jumpToNextImage () Собственно говоря, у меня вопрос к сообществу. Что это бага, или я не разобрался в вопросе? ------------------------------------------------------------------------------------------------------------ Тем не менее, если вручную контролировать количество кадров (можно узнать любым графическим редактором), работа с гиф анимацией становится простой и удобной. Предлагаю, на мой взгляд, очень интересную демку. Надеюсь Вам понравится ![]() Компилируем, смотрим, отписываемся о результатах.
Прикрепленные файлы
|
|
|
![]() |
kwisp |
![]()
Сообщение
#2
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
int QImageReader::loopCount () const вернуло 999 для кота(кошки). Цитата canRead() is a lightweight function that only does a quick test to see if the image data is valid. read() may still return false after canRead() returns true, if the image data is corrupt.
Сообщение отредактировал kwisp - 29.5.2009, 14:18 |
|
|
igor_bogomolov |
![]()
Сообщение
#3
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
вернуло 999 для кота(кошки). А реально там 11 кодров. nextImageDelay и loopCount возвращают чуш. Надо попробовать заменить QImageReader на QMovie. Он такой же набор методов предоставляет. kwisp, спасибо разобрался. Счетчик действительно лишний. А как новый цикл начать без использования setFileName? |
|
|
kwisp |
![]()
Сообщение
#4
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
igor_bogomolov,
лажа какая то в исходниках добрался до виртуальной функции класса QImageIOHandler::imageCount() int
собственно всё. она кроме 0 и 1 ничего не вернет ![]() canRead() is a lightweight function that only does a quick test to see if the image data is valid. read() may still return false after canRead() returns true, if the image data is corrupt. я это ктому что после рида то проверка нужна ![]() А как новый цикл начать без использования setFileName? походу только так bool QImageReader::jumpToImage ( int imageNumber ) |
|
|
igor_bogomolov |
![]()
Сообщение
#5
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
я это ктому что после рида то проверка нужна у тебя нет Переделат так. Все работает. За количеством кадров следить не надо. Раскрывающийся текст
походу только так Не получается этим методом (((
bool QImageReader::jumpToImage ( int imageNumber ) Сообщение отредактировал igor_bogomolov - 29.5.2009, 14:57 |
|
|
Litkevich Yuriy |
![]()
Сообщение
#6
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
Я для проигрования gif'ки использовал QMovie + QLable.
|
|
|
kwisp |
![]()
Сообщение
#7
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
igor_bogomolov,
загляни в исходники. очень удивишься. класс QImageIOHandler содержит виртуальные функции и предназначен походу для наследования и переопределения их. из файла qimgeiohandler.cpp Раскрывающийся текст
не могу найти в исходниках где переопределяется переопределяются данные виртуальные функции ![]() |
|
|
igor_bogomolov |
![]()
Сообщение
#8
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
Я для проигрования gif'ки использовал QMovie + QLable. Это понятно. Все так используют. А если нужен overpainting? ![]() QLabel тут не подойтет. QMovie конечно можно использовать вместо QImageReader. Наверное так и надо сделать. Собери примет из первого сообщения. Помоему прикольно. |
|
|
Litkevich Yuriy |
![]()
Сообщение
#9
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
kwisp |
![]()
Сообщение
#10
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
нашел где переопределяют imageCount
похоже либо бага либо недоделка либо я накосячил.
таж фигня вид сбоку и функция не виртуальная. мда.... сразу мона было позырить сюда там вообще не только одна функция непереопределена штук 5 недоделаны. Сообщение отредактировал kwisp - 29.5.2009, 15:53 |
|
|
Litkevich Yuriy |
![]()
Сообщение
#11
|
![]() разработчик РЭА ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
igor_bogomolov |
![]()
Сообщение
#12
|
Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Сомодератор Сообщений: 1215 Регистрация: 22.3.2009 Из: Саратов Пользователь №: 630 Спасибо сказали: 235 раз(а) Репутация: ![]() ![]() ![]() |
kwisp, я переделал все на QMovie. Тож же самый функционал, потяжеловеснее только. Хотелось бы QImageReader обойтись. Да ну и черт с ним.
У QMovie loopCount () & frameCount () возвращают -1. Зато работает jumpToFrame и nextFrameDelaу. Цитата(kwisp) мда.... сразу мона было позырить сюда Бага то старинная и приоритет высокий. Странно что до сих пор не пофиксили.
Прикрепленные файлы
|
|
|
kwisp |
![]()
Сообщение
#13
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
я бы сказал для гифа точно в классе
QGifHandler не перепопределены толком виртуальные функции предка QImageIOHandler в остальных лень смотреть кому интересно в src/plugins/imageformats/ лежат дочерние классы в src\gui\image\ родитель QImageIOHandler У QMovie loopCount () & frameCount () возвращают -1 странно в исходниках они вроде переопределены по своему .... хм.. ну да черт с ними точно. потому что посмотрел я на баги.... многовато их... надо почаще туда лазить а то так голову поломать можно. P.S. кошара зачётная. почитай там в юморе в непридуманных историях есть про кота как раз рассказик. Сообщение отредактировал kwisp - 29.5.2009, 16:07 |
|
|
Rocky |
![]()
Сообщение
#14
|
Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: ![]() ![]() ![]() |
Ребят а с тех пор никто с гифками не работал? У меня щас 4.6.1.... а по ходу все тоже самое.. ( Как можно остановить анимацию когда последний кадр? я делал через QMovie... Походу сигнал finished не генерируется... А гифка так вечно и проигрывается, а нужно чтоб она один раз проиграла, и все... Блин(
|
|
|
kwisp |
![]()
Сообщение
#15
|
![]() астарожна ынтжинэр ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1404 Регистрация: 26.11.2008 Из: ТаганрогРодинаЧехова Пользователь №: 435 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
не делал.
посмотри баги может они так и остались. |
|
|
SABROG |
![]()
Сообщение
#16
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: ![]() ![]() ![]() |
Узнай количество фреймов:
int QMovie::frameCount () const и лови сигнал: void QMovie::frameChanged ( int frameNumber ) [signal] В слоте проверяй если frameNumber == frameCount(), то вызывай stop(): QTimer::singleShot(0, movie, SLOT(stop()); Чтобы movie успел проиграть последний фрейм и только после этого остановился. А finished() наверно никогда не придет, если в gif'ке стоит свойство играть по кругу. Если даже frameCount() не будет работать, то максимальное количество фреймов всегда можно обновить в слоте на frameChanged() и если новое значение меньше старого, значит пошел второй круг. Сообщение отредактировал SABROG - 10.3.2010, 23:44 |
|
|
Rocky |
![]()
Сообщение
#17
|
Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: ![]() ![]() ![]() |
SABROG, я так пробовал... frameCount всегда возвращает 0. в слоте, соединенном с сигналом frameChanged параметр frameNumber всегда 0. Более того, если этот сигнал соединять, то вообще срывает стэк почемуто =)
Боюсь что поддержки гифоф так и нет... Ладно, напишу свой класс, которому буду просто кормить последовательность картинок... |
|
|
SABROG |
![]()
Сообщение
#18
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: ![]() ![]() ![]() |
Выложи проект, посмотрю.
|
|
|
Rocky |
![]()
Сообщение
#19
|
Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: ![]() ![]() ![]() |
SABROG, спасибо но там точно баги. Я гуглил. Чтобы не тратить время просто свой класс написал на основе QLabel которому последовательность картинок передаю..
|
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 22.6.2025, 13:55 |