Russian Qt Forum

Qt => Дополнительные компоненты => Тема начата: Авварон от Декабрь 11, 2016, 22:33



Название: Картиночки
Отправлено: Авварон от Декабрь 11, 2016, 22:33
Какое-то время я работал над библиотечкой, которая могла бы заменить текущие имаджформаты в Qt (да, они не совершенны).
Что-то получилось:) Прежде, чем выдавать на суд кутешникам, спрошу мнения здесь - понятно ли, что вообще за зверь, зачем это надо.
Возможно, будут какие-то предложения.

Документация (http://abbapoh.github.io/docs/imageformats-ng/)
Сорцы (https://github.com/ABBAPOH/imageformats-ng)


Название: Re: Картиночки
Отправлено: Igors от Декабрь 12, 2016, 14:12
Думается о "замене текущих форматов" лучше умолчать, а упирать на dds. Напр назвать это хозяйство "dds format support". А dds уже  может содержать много чего (мипы, фреймы и др). И "problematic" если не убрать то засунуть в конец

Если же планы шире (мол, dds только частный случай) - то нужны доп пояснения, напр какие приложения смогут прочесть записанное


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 12, 2016, 17:08
Думается о "замене текущих форматов" лучше умолчать, а упирать на dds.

Ну так-то все понимают, что текущие имадж форматы не очень (например, нельзя записать gif, ico, icns, это ограничение API). Проблема что их некому развивать, последний коммит там пару месяцев назад был.

Если же планы шире (мол, dds только частный случай) - то нужны доп пояснения, напр какие приложения смогут прочесть записанное

В целом, добавить примеров можно.
К сожалению, я не близок к миру 3д графики, поэтому не очень в курсе, как используется тот же DDS и какие задачи с ним на практике (ну кроме зафигачить файл целиком на видюху, это не к плагинам)


Название: Re: Картиночки
Отправлено: Racheengel от Декабрь 13, 2016, 00:10
Как видится,

Код:
Optional<ImageContents> maybeContents = reader.read();
if (!maybeContents) {
        qWarning() << "Error reading image:" << reader.error().errorString();
        return 1;
    }
ImageContents contents = *maybeContents;

тут Optional<> - избыточная конструкция. Я бы предпочел такое:

Код:
ImageContents contents = reader.read();
if (!contents.isValid()) {
        qWarning() << "Error reading image:" << reader.error().errorString();
        return 1;
    }

Абсолютно неочевиден смысл операции *maybeContents, да она по сути и не нужна.


Название: Re: Картиночки
Отправлено: lit-uriy от Декабрь 13, 2016, 06:29
Абсолютно неочевиден смысл операции *maybeContents ...
Согласен полностью


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 13, 2016, 10:41
Абсолютно неочевиден смысл операции *maybeContents, да она по сути и не нужна.

Сейчас есть такая бага:
Код:
QImageReader reader("empty.png");
auto image = reader.read();
if (image.isNull()) {
    qWarning() << reader.errorString(); // ooops there was no error, image is really null
}

Возможно, лучше передавать по результат по ссылке, а возвращать error код.


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 13, 2016, 11:20
Еще можно возвращать std::pair<ImageIOError, ImageContents>, как делает std::map::insert.
Дело в том, что в 17х плюсах обещают python-like возврат множественых значений из ф-ии (путем возврата std::pair/std::tuple и их автоматического разворачивания).
Тогда юзание будет какое-то такое:

Код:
ImageIo reader("file.png");
auto [ok, contents] = reader.read();
if (!ok) {
    qWarning() << ok.errorString();
}
/// ...


Название: Re: Картиночки
Отправлено: Igors от Декабрь 13, 2016, 17:42
Ну так-то все понимают, что текущие имадж форматы не очень
Ну как "не очень" - необходимость просто загрузить одну картинку (без затей) всегда была и будет.
(например, нельзя записать gif, ico, icns, это ограничение API).
Вот на это и напирайте, мол multiply images support и все такое. И список этих новых поддержек ставьте первым

К сожалению, я не близок к миру 3д графики, поэтому не очень в курсе, как используется тот же DDS и какие задачи с ним на практике (ну кроме зафигачить файл целиком на видюху, это не к плагинам)
Я впервые услышал о dds. Вообще 3D и OpenGL - очень разные вещи/запросы. Volume Texture - это чисто дела OpenGL, и, насколько мне известно, успехи с ней невелики т.к. сделано явно тупо - гигантский объем, ноль интеллекта. Гораздо интереснее/перспективнее форматы воксельной графики.

Карты отражения/окружения широко используются везде, вариаций много. Напр есть еще angular (круг), fish, skyDome и др. Шесть имеджей - ну это уже все больше "дань истории", еще лет 5 назад меня попросили конвертировать их в cross (не те времена чтобы экономить % имеджа). Нельзя сказать что какой-то формат заметно лучше, напр многие юзают старый добрый spherical.

Мипы - ну тоже дела OpenGL. Мульти-фреймы - таких форматов мало, гораздо чаще используют просто "набор файлов" (с именами типа file00000.jpg, file00001.jpg, file00002.jpg, и.т.д) или же мувик

Особняком стоят форматы с большей точностью или большим диапазоном. Популярен .exr, да и хотя бы 2 байта на канал (ushort) - дело нужное

В общем все как-то приспособились.


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 13, 2016, 18:51
Ну как "не очень" - необходимость просто загрузить одну картинку (без затей) всегда была и будет.
Да, но не делать же отдельное АПИ на каждый тип картинок, их количество весьма ограничено.
У меня только psd не поддерживаются, потому что яхз, что там у "ей внутре".

Вот на это и напирайте, мол multiply images support и все такое. И список этих новых поддержек ставьте первым
Ок

Я впервые услышал о dds. Вообще 3D и OpenGL - очень разные вещи/запросы. Volume Texture - это чисто дела OpenGL, и, насколько мне известно, успехи с ней невелики т.к. сделано явно тупо - гигантский объем, ноль интеллекта. Гораздо интереснее/перспективнее форматы воксельной графики.
Ну основной юзкейз dds - это плоские 2д текстуры. Современные видюхи умеют работать напрямую с DDS. Например, в Cтаркрафте все текстуры хранятся в dds.

Мипы - ну тоже дела OpenGL. Мульти-фреймы - таких форматов мало, гораздо чаще используют просто "набор файлов" (с именами типа file00000.jpg, file00001.jpg, file00002.jpg, и.т.д) или же мувик
А как же иконки?:)

Особняком стоят форматы с большей точностью или большим диапазоном. Популярен .exr, да и хотя бы 2 байта на канал (ushort) - дело нужное
Как я уже упоминал, это просто еще один формат для QImage, никакого нового АПИ тут не нужно.
Таких форматов туда можно много напихать (в том же dds их около сотни (!) поддерживается)


Название: Re: Картиночки
Отправлено: panAlexey от Декабрь 13, 2016, 22:43
Меня интересуют некоторые операции которые технически я не знаю как реализовать с пом. Qt , это:
- создание файлов *.ico; (требуется для windows приложений)
- установка прозрачного фона для картинок (постоянно требуется для создания пиктограмм приложений).
Скажите с пом. "Картиночек" это можно будет реализовать?


Название: Re: Картиночки
Отправлено: Igors от Декабрь 14, 2016, 11:55
У меня только psd не поддерживаются, потому что яхз, что там у "ей внутре".
Там своя песня, упор на "слои" которые могут всяко-разно комбинироваться, часто с помощью масок. 

А как же иконки?:)
Трехмерщику такая мелочь неинтересна, если там пикселей с гулькин нос - ничего путного не отрендерить

Как я уже упоминал, это просто еще один формат для QImage, никакого нового АПИ тут не нужно.
Таких форматов туда можно много напихать (в том же dds их около сотни (!) поддерживается)
Не думаю что все так просто, во всяком случае эти форматы имеют свои специфичные данные. И неясно как "трактовать" содержимое имеджа (bits()). Если в родных данных то как рисовать, иначе родные надо где-то еще хранить.

Пример: популярная задача "terranizer". Юзер мазюкает чего-то (напр в фотошопе) и отдает картинку плагину который по ней строит "горы", где цвет белее - гора выше, темнее - ниже. Казалось бы, все просто и даже примитивно. И тут выясняется что 256 значений высоты - это очень мало, горы получаются явно "ступеньками". Фотошоп сможет делать бОльший диапазон, но читать-то это нечем. Поэтому "2-bytes textures support" - реальная, крутая фича


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 14, 2016, 13:15
- создание файлов *.ico; (требуется для windows приложений)

Да, это один из основных юзкейзов.

- установка прозрачного фона для картинок (постоянно требуется для создания пиктограмм приложений).
На чтении или записи? На чтении сейчас можно сделать QImageReader::setBackgroundColor (http://doc.qt.io/qt-5/qimagereader.html#setBackgroundColor)
На запись - как картинку запишите, так и будет.


Название: Re: Картиночки
Отправлено: Racheengel от Декабрь 14, 2016, 14:43
Абсолютно неочевиден смысл операции *maybeContents, да она по сути и не нужна.

Сейчас есть такая бага:
Код:
QImageReader reader("empty.png");
auto image = reader.read();
if (image.isNull()) {
    qWarning() << reader.errorString(); // ooops there was no error, image is really null
}

Возможно, лучше передавать по результат по ссылке, а возвращать error код.

Не вижу бага тут, ну пустая картинка и пустая.
Уберите Optional вообще, а в ImageContents добавьте что-то вроде isValid().
А еще что  то типа ImageContents::toImage() например.


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 14, 2016, 15:06

Не вижу бага тут, ну пустая картинка и пустая.
Уберите Optional вообще, а в ImageContents добавьте что-то вроде isValid().
А еще что  то типа ImageContents::toImage() например.


Пустая картинка возвращается в двух случаях - либо была ошибка, либо файл содержит пустую картинку. Как вы эти 2 случаях собираетесь различать?
Насчёт isValid(). Разделение QString::isEmpty/QString::isNull считается ошибочным и в Qt6 его уберут.


Название: Re: Картиночки
Отправлено: Пантер от Декабрь 14, 2016, 15:07
Exception же!


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 14, 2016, 15:31
Exception же!

К сожалению, нельзя)
Да и даже std:: предоставляет способ работы без исключений, например, с потоками или процессами.


Название: Re: Картиночки
Отправлено: Racheengel от Декабрь 14, 2016, 19:37
Пустая картинка возвращается в двух случаях - либо была ошибка, либо файл содержит пустую картинку. Как вы эти 2 случаях собираетесь различать?

"Не мы, а вы" :)
ImageContents то формируется вашим ридером, сделайте в нем флажок типа bool m_valid, и ставьте его как надо.
Тогда isValid() будет делать return m_valid, и усе.
Мы примерно так реализовали у себя подобный функционал.

Насчёт isValid(). Разделение QString::isEmpty/QString::isNull считается ошибочным и в Qt6 его уберут.

Ну, в случае со строкой действительно не понятно, чем пустая строка от нулевой отличается. В принципе это синонимы.
А для картинок не совсем.


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 14, 2016, 19:41
Racheengel
Да тоже самое:) Есть пустой контент, есть непустой. А есть отсутствие контента, это либо опшнал (который, к слову, в 17х плюсах будет), либо пара bool, контент.


Название: Re: Картиночки
Отправлено: kambala от Декабрь 14, 2016, 23:13
можно сделать enum Status из трех значений


Название: Re: Картиночки
Отправлено: panAlexey от Декабрь 15, 2016, 09:09
- создание файлов *.ico; (требуется для windows приложений)

Да, это один из основных юзкейзов.

- установка прозрачного фона для картинок (постоянно требуется для создания пиктограмм приложений).
На чтении или записи? На чтении сейчас можно сделать QImageReader::setBackgroundColor (http://doc.qt.io/qt-5/qimagereader.html#setBackgroundColor)
На запись - как картинку запишите, так и будет.

Спасибо! Хотелось бы понять как делать это при записи, что-бы модифициировать эту софтинку (https://github.com/Gr1N/EasyPaint/). И иметь на компе инструмент под рукой.
И хотелось возможности вашей разработки подключить к этому редактору..
ПС. С++11 нет возможности использовать в силу старой операционки.


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 15, 2016, 13:41
Спасибо! Хотелось бы понять как делать это при записи, что-бы модифициировать эту софтинку (https://github.com/Gr1N/EasyPaint/). И иметь на компе инструмент под рукой.
Ну так там просто надо сделать кнопочку "залить прозрачным", это и сейчас можно (если формат поддерживает прозрачность, офк).

ПС. С++11 нет возможности использовать в силу старой операционки.

Ну вообще-то Qt с какой-то версии требует с++11:)
Даже эту софтинку когда собирал пришлось включить с++11, так как Qt ругалось.


Название: Re: Картиночки
Отправлено: panAlexey от Декабрь 16, 2016, 01:01
Ну вообще-то Qt с какой-то версии требует с++11:)
Даже эту софтинку когда собирал пришлось включить с++11, так как Qt ругалось.
эйзипаинт (https://github.com/trdm/EasyPaint) нормально собрался на Qt 4.7.3, а она не требует с++11


Название: Re: Картиночки
Отправлено: panAlexey от Декабрь 16, 2016, 01:03
Ну так там просто надо сделать кнопочку "залить прозрачным", это и сейчас можно (если формат поддерживает прозрачность, офк).
И как это сделать? применительно к QImage?
Мне просто надо знать как и я это сделаю.
Можно подсказку?


Название: Re: Картиночки
Отправлено: Авварон от Декабрь 16, 2016, 09:45
эйзипаинт (https://github.com/trdm/EasyPaint) нормально собрался на Qt 4.7.3, а она не требует с++11

У меня 4ки уже нет года 2.

И как это сделать? применительно к QImage?
Мне просто надо знать как и я это сделаю.
Можно подсказку?

Код:
QImage image(100, 100, QImage::Format_ARGB32);
image.fill(Qt::transparent);
А потом поверх рисуете что надо.


Название: Re: Картиночки
Отправлено: panAlexey от Декабрь 19, 2016, 18:59
И как это сделать? применительно к QImage?
Мне просто надо знать как и я это сделаю.
Можно подсказку?

Код:
QImage image(100, 100, QImage::Format_ARGB32);
image.fill(Qt::transparent);
А потом поверх рисуете что надо.
Благодарствую!
Но тут скорее немного иная задача стоит.
Выбрать цвет и превратить все пиксели этого цвета в цвет прозрачности.


Название: Re: Картиночки
Отправлено: Bepec от Декабрь 19, 2016, 19:56
Код:
for(всё изображение)
{
если (пиксель такой то)
     setPixel(координаты, Qt::transparent);
}


Название: Re: Картиночки
Отправлено: Авварон от Январь 18, 2017, 23:22
Обновил кое-чего.
Переименовал ImageIOError->ImageIOResult, а енум из Error в Status (теперь так (http://abbapoh.github.io/docs/imageformats-ng/class_image_i_o_result.html))
Теперь вместо опшнла возвращается пара<статус операции, контент> (пример (http://abbapoh.github.io/docs/imageformats-ng/class_image_i_o.html#a367e297536512e980b71a4852723feb6)). Это позволяет не хранить ошибку мембером ImageIO.
Теперь раздельное чтение хедера и данных выглядит так (http://abbapoh.github.io/docs/imageformats-ng/class_image_i_o.html#a53ec4c6b26a695bf3751866881bbac6a) (раньше надо было просто звать read, он сам определял, звали ли до этого readHeader). Это для того, чтобы ImageIO не хранил header и contents.
Добавил передачу опций (http://abbapoh.github.io/docs/imageformats-ng/class_image_options.html) на чтение (и написал доку к ним)