Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIFF и Mixed Raster Content mode #32

Open
plzombie opened this issue Apr 26, 2024 · 63 comments
Open

TIFF и Mixed Raster Content mode #32

plzombie opened this issue Apr 26, 2024 · 63 comments
Assignees
Labels
dispute Debate enhancement New feature or request

Comments

@plzombie
Copy link
Contributor

В RFC 2301 написано, что TIFF может содержать три слоя

The 3 layers of the MRC model are Foreground and Background, which
are both multi-level, and Mask, which is bi-level. Each layer may
appear only once on a page and is coded independently of the other
two. In our earlier example, the black-and-white text could be in the
Mask layer, the color chart in the Foreground layer, and the color
image in the Background layer.

Насколько я понимаю, Scantailor сейчас не поддерживает такой режим. Изображение созраняется как фон (без маски). Вроде как Scantailor Featured мог сохранять две копии изображения - bg и отдельно mask.

Собственно, предложение. Для смешанного режима реализовать сохранение в mixed raster context. А потом уже разбираться, как сконвертировать это в djvu.

@zvezdochiot @noobie-iv @trufanov-nok (вроде никого не забыл) - нет возражений?

@plzombie plzombie added dispute Debate enhancement New feature or request labels Apr 26, 2024
@plzombie plzombie self-assigned this Apr 26, 2024
@trufanov-nok
Copy link
Member

Емнип STU, STA и наверное что-то им предшествовавшее, реализуют экспорт слоев страницы на этапе output. В отдельные файлы. Экспортируются в т.ч. background и foreground. Маска на этом этапе в этом режиме хранится неявно - у оригинального изображения пиксели 0x000000 И 0xFFFFFF (или только 0x000000 - не помню) резервируются под слой foreground (текст), везде где не picture zone. Т.о. экспорт представляет собой переписывания одного файла в два на основании pixel_color == 0x000000. Эти слои в дальнейшем собираются в djvu по методу раздельных сканов при помощи DjVu Imager. Он понимает только слои в виде отдельных файлов.
Смысла кодировать что-то в MRC я особого не вижу. Кодировщиков в djvu из tiff с его поддержкой нет. Насколько вьюверы его поддерживают, особенно в tiff - не ясно. Вот в wiki про Tiff ни слова: https://en.wikipedia.org/wiki/Mixed_raster_content
В STU кстати есть вроде экспорт слоев в multilayer или multipage tiff - не помню. Но это не совсем MRC. Но? кол-во файлов можно сэкономить.
Остается вопрос сохранения цветовой схемы (резервирование 0x000000 в не отмеченных picture зонами областей в mixed mode за текстовым слоем можно избегать)... Но это очень древняя фича и ее изменение потребует усилий.

В общем, ничего кроме лишнего геморроя...

@noobie-iv
Copy link
Member

Я использую в основном STA для перевода документов по работе в PDF. В документах дела обстоят так:

  1. Есть текст и черно-белые чертежи. Их надо переводить в монохром 600dpi
  2. Есть малоцветные чертежи, графики и т.п. Их надо переводить в малоцветную палитру 600dpi, 4-8 цветов. Возможно, принудительно, указывая эти несколько цветов мышкой.
  3. Есть многоцветные чертежи. Полноцвет слишком тяжел, а малоцвет их портит. Обычно там палитры от 64 до 256 цветов. Разрешение - спорный вопрос, иногда 600dpi, а иногда можно оставлять 300dpi, они не улучшаются от увеличения.
  4. Есть фото. Их вообще трогать не надо, они от этого только портятся. Разрешение надо оставлять как было, а обрезать в идеале хотелось бы как делает BetterJPEG, обратно в jpeg без перекодирований.
  5. Иногда все эти варианты встречаются прямо на одной странице.

Мне нужно, чтобы страница содержала несколько изображений разного формата и разрешения одновременно, обрабатывала каждый из них по-своему, и экспорт нужен в разные форматы сразу. Эта идея вообще никак не совместима с той реализацией, что есть сейчас в любой из версий ST. Тут не то что tiff поправить, тут саму систему хранения и обработки изображений переделывать надо - идентификаторы, кеши, устройство фильтров и видов. Из-за этого я и завел STD, но, похоже, не вывезу; по крайней мере, пока знания по плюсам не подтяну.

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 27, 2024

@noobie-iv , тогда смотри в сторону pnmtodjvurle. DjVuRLE позволяеет делать SEP-файлы (foreground+background), которые кодируются в djvu непосредственно утилитами csepdjvu или msepdjvu.

PS:

По поводу разделённых сканов. Я пользую CropperTktoPDF. Но хотелось бы иметь поделку на Qt и без reportlab для генерации PDF, ибо он использует кодировку ASCII85.

По поводу JPEG, использую комбинацию Info из Crop в PhotoQuick с шагом 16 + jpegtran + jpeg2pdf с полями (-m) по информации из PhotoQuick. (хотелось бы конечно иметь гуишный инструмент).

Для комбинации отдельх "слоёв" (PDF) в страницу имеется qpdf.

@trufanov-nok
Copy link
Member

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

А вы можете это сделать в каком-нибудь Photoshop, GIMP или SkanKromsator? Если да - то...

Есть пословица паскудная: "лучшее - враг хорошего". ST меня когда-то купил своей простотой. Я лет 8 назад его запустил, два раза куда-то тыкнул - и получил отличный (как мне тогда казалось) результат. Мне какие-то фичи были нужны (преимущественно хоткеи) - я их докрутил. Остальные спрятал в настройки, чтобы сохранить простой UX. До сих пор использую. Потом выяснилось существование метода раздельных сканов и это единственное, к.м.к., недочет ST семейства - что они не форсят создание djvu по этому методу, имея при том полуавтоматический сегментатор слоев внутри.

Какие-то попытки изменить первоначальный концепт - например, этапы обработки местами менять - приводят к серьёзным пропихиванием невпихуемого в разные места кода, куда оно идти не должно. Это - возможно, смогут это "не только лишь все" и мало кому это уже надо, но и удивляться что оно идет против шерсти концепта - бессмысленно.

@plzombie
Copy link
Contributor Author

@trufanov-nok

Емнип STU, STA и наверное что-то им предшествовавшее, реализуют экспорт слоев страницы на этапе output. В отдельные файлы. Экспортируются в т.ч. background и foreground. Маска на этом этапе в этом режиме хранится неявно - у оригинального изображения пиксели 0x000000 И 0xFFFFFF (или только 0x000000 - не помню) резервируются под слой foreground (текст), везде где не picture zone. Т.о. экспорт представляет собой переписывания одного файла в два на основании pixel_color == 0x000000. Эти слои в дальнейшем собираются в djvu по методу раздельных сканов при помощи DjVu Imager. Он понимает только слои в виде отдельных файлов.

Видимо оно там тоже было когда-то. Потому что создаётся background слой с маской 0x000000 и 0xFFFFFF прямо на нём. Но как мне в StEx сделать отдельно background+отдельно foreground, а желательно ещё и отдельно маску, я не нашёл.

@zvezdochiot

По поводу разделённых сканов. Я пользую CropperTktoPDF. Но хотелось бы иметь поделку на Qt и без reportlab для генерации PDF, ибо он использует кодировку ASCII85.

Ну вот оно уже есть в StEx. Осталось сохранить в тот же tiff (благо в теории формат позволяет даже разбить фон на несколько изображений)

Я не думаю, что это прамо архисложно, написать утилиту, которая будет конвертировать tiff+MRC в pdf или djvu. Всё равно, данной функциональности сейчас нет вообще

@plzombie
Copy link
Contributor Author

На майских потыкаю палкой и StEx, и tiff. Если удастся сделать без ущерба к существующему функционалу и реализации, попробую добавить

@noobie-iv
Copy link
Member

У нас в строительстве официяльные документы принимают в PDF, потому я DJVU не использую, не у всех на него смотрелки есть. А для быстрой сборки в PDF я свалял простейшую консольку, которая папку OUT после STA разом пакует: https://forum.dwg.ru/showthread.php?t=167830. С этим уже жить можно, я так под тыщщу гостов собрал.

Текст у меня обрабатывает STA, а картинки в режиме разделения сканов я как раз в GIMP пережимаю, перед упаковкой в PDF. Деварп мне, собственно, не нужен - сканы обычно не кривые. И всего, чего не хватает - различать не два типа изображений на странице, как сейчас во всех ST, а три за раз, чтобы всю обработку в ST делать, а не ёрзать туда-сюда постоянно.

ST, конечно, простые, но у них ограничение - книги либо только с фото, либо только с малоцветками. А наши нормотворцы в новых документах взяли моду вместо ЧБ чертежей, как в старые добрые времена, вставлять что попало, даже фотки низкого разрешения из интернета, даже диаграммы желтым по белому, и прочую ересь. Вот с ними ST и не справляется в автомате. Нужен ST, у которого автомат малость посложнее. И потому же я в отдельную программу ушел, а не в реквесты на исходные STA/STU.

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 27, 2024

@plzombie , @noobie-iv , етить вашу мать, дайте ссылку на этот ваш StEx!

PS: @noobie-iv , пользовать MRC в PDF категорически не рекомендую. В PDF есть родной, простой и понятный способ илюстрирования - кадрирование изображений и наложение их сверху/снизу. А MRC в PDF - это сплошные и дикие тормоза во всех просмотрщиках + проблемы (!!!) с печатью.

@plzombie
Copy link
Contributor Author

@zvezdochiot Я этот форк имею в виду

@zvezdochiot
Copy link
Member

Кажется я начал понимать за что речь. Но ежели это действительно так, то я "улыбаюсь" с этой истории, ибо всё опять возвращается к макетированию страниц. И без макетирования вы желаемого результата не получите никак. Такие вот дела. ;)

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 27, 2024

@plzombie say:

На майских потыкаю палкой и StEx

Тогда посмотри ещё:

  1. как бы в FillZones пристроить no-kmeans, чтобы убрать его из PictureZones?
  2. как бы в Zones добавить для оконтуривания XSpline: feature: Line/XSpline in zones. #30?

@plzombie
Copy link
Contributor Author

@zvezdochiot да там ещё и вылетает редко при переходе от зон картинок к зонам заливки. Надо это поотлаживать прежде чем что-либо делать. Но займусь

@plzombie
Copy link
Contributor Author

@zvezdochiot К слову, можешь мне объяснить, что происходит, когда в смешанном режиме выбираешь цвет заливки? Такое ощущение, что за гранью "зоны картинок" он приводится к чб

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 27, 2024

@plzombie , да, я "химичил" с заливкой из-за k-means. И мне самому не до конца понятно, как грамотно организовать заливку. Надо ковыряться.

Вспомнил ещё один неприятный момент: в IntegralImage напрочь отсутствует метод принудительного высвобождения. Сейчас они висят до завершения области видимости. Да, некритично, ибо все процедуры короткие, но сам факт неприятный.

@noobie-iv
Copy link
Member

@zvezdochiot say:

пользовать MRC в PDF категорически не рекомендую

А как без него, если STA экспортирует две страницы одного размера - ЧБ+ЦВЕТ. Вот и приходится просто считать ЧБ маской, и сводить с картикной как есть.

всё опять возвращается к макетированию страниц

Чтобы не было MRC, в этом макете надо сохранять не маску, а набор честных габаритных прямоугольников в пределах страницы. Такой макет совсем не похож на то, что есть сейчас - ссылка на исходное изображение, контур подрезки и поворот. И система хранения другая, и обработка страниц видами другая. А если еще позволить разные разрешения в пределах страницы - то и система хранения изображений другая.

Собственно, это я и имел ввиду, когда затевал STD. Ну, пока об нехватку знаний не споткнулся. Если починю там битые превьюшки, есть шанс, что и остальное доделаю (тогда уж и в STEX починить их смогу, и в STA). Но это еще очень нескоро будет.

@zvezdochiot
Copy link
Member

@noobie-iv , неверно. Совсем.

Как раз с изображение делать что то "несусветное" вовсе нет надобности. Надобно либо сохранять отдельно xml макета, для использования его в дальнейшем, либо парсить сам проект STEX. В любом случае надобна дополнительная тулза для генерации PDF по макету из одного (ОДНОГО!) обычного tiff-а. Что то типа DjVu-Imager на новый лад. Такие вот дела. ;)

@noobie-iv
Copy link
Member

парсить сам проект STEX

Я не сохраняю проекты. Я скачиваю очередной гост, пропускаю в автомате через STA, и пакую как есть. А после STEX разные части картинки еще и перепаковывать надо, каждую в свой формат, это долго и лень.

изображение делать что то "несусветное" вовсе нет надобности

У меня есть. Мне принципиально надо, чтобы любой фильтр мог прогнать изображение через любую внешнюю команду. Может, деварп сторонний. Может, GMIC. Может, даже в GIMP для ручной правки. А значит, у фильтра своя временная папка заводится под редактированные изображения, чтобы он их дальше передавал, а не оригинал с подправленной рамкой, как сейчас. Но это все в STD должно быть. STEX я не трогаю, пусть остается минималистичным. Да я и STD не трогаю, тупой я для этого, просветления жду 😄

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 27, 2024

@noobie-iv , опять таки имеет место быть согласие.

Ежели сделать отдельную прогу макетирования страницы, то это решило бы очень много вопросов. А ваши вопросы порешало бы полностью. Необходимость макетирования в STEX для сложных страниц не отпала бы, но конструкция STEX->{GIMP, Krita, ...}->QPageMaket->PDF очень даже логична.

@plzombie
Copy link
Contributor Author

В tiff можно сохранять в передний/задний план отдельные области, а не всё изображение уменьшенное
То есть останутся отдельно иллюстрации (отдельные слои типа заднего плана), один чб слой типа маски и опционально можно в передний план что-нибудь добавить (а можно не добавлять - просто весь передний план закрасить чёрным цветом)

@plzombie
Copy link
Contributor Author

То есть дело за конвертером MRC TIFF => PDF. Ну и в STEX это добавить (собственно, для чего я этот топик создавал)

@zvezdochiot
Copy link
Member

@plzombie say:

То есть дело за конвертером MRC TIFF => PDF.

Нифига. MRC в PDF - это тормозное говно, которое хрен нормально распечатаешь и вообще нафиг ненужно. Другое дело постоение страницы из отдельных блоков по макету.

@noobie-iv
Copy link
Member

конвертером MRC TIFF => PDF

Чтобы такое было возможно и полезно, надо, чтобы в TIFF разные слои хранились с разным сжатием, для текста и картинок отдельно. Он так умеет? А лично мне надо, чтобы еще и на одной странице могли быть разные области с разным сжатием: монохром/fax4, фото/jpeg, малоцвет/lossless-palette, полноцвет/lossless.

В tiff можно сохранять в передний/задний план отдельные области

А их положение на странице он помнит? Например, как в редакторах, работающих со слоями, когда наложенную сверху заплатку можно подвигать туда-сюда? Если да, то из него можно будет честный PDF делать, без MRC. И еще хорошо бы, чтобы это чудо можно было просматривать, а не просто знать, что там внутри особая магия есть. Какой вьюер/редактор так может?

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 28, 2024

@noobie-iv , по вашим запросам, STEX должен генерить на выходе постраничные PDF, а значит как минимум уметь FAX CCITT GROUP4, либо JBIG2, FLATE, настраиваемый JPEG, либо JPEG2000. Но это не просто и сильно осложнит дальнейшую обработку. Такие вот дела. ;)

@noobie-iv
Copy link
Member

По моим запросам надо еще в обработку добавить редактирование через внешние программы. Тогда экспортированный PDF вообще не надо дальнейше обрабатывать.

Например, в современных гостах чертежи - это часто скриншоты, пережатые JPEGом до перхоти. Если бы их примитивной кривой пройти, чтобы перхоть выбелить в ноль, а черный чуть затемнить, меня бы результат устроил. А чтобы кривые не писать с нуля, я и хочу их через вызов внешних программ делать.

А если делать экспорт под дальнейшую обработку, все равно же придется вместе с картинками еще и контуры/координаты записывать (даже если считать, что они уже записаны в проекте). И такое просто посмотреть уже никто не может, надо конвертер/смотрелку дописывать. А зачем смотрелка, которая смотрит то, что в ST не доделано, и которая, кроме как за ST посмотреть, больше ничего не может? Такая смотрелка должна быть частью ST - это фильтр "Export" должен быть.

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 28, 2024

@noobie-iv say:

Например, в современных гостах чертежи - это часто скриншоты, пережатые JPEGом до перхоти. Если бы их примитивной кривой пройти, чтобы перхоть выбелить в ноль, а черный чуть затемнить, меня бы результат устроил. А чтобы кривые не писать с нуля, я и хочу их через вызов внешних программ делать.

Так это ж S-кривая (сдвоенная дуга) в фильтрах. И стоит уже по дефолту на 0.5. Помимо этого есть C-кривая (чистая дуга).

@noobie-iv
Copy link
Member

Мне начало и конец сдвигать надо, а не на месте оставлять. А сама кривая должна оставаться прямой, только повернутой вокруг центра. Такое еще яркость-контраст делают, но менее удобно. А S и C для другого, они тени и света сохранить пытаются, а их срезать надо, там только шум лишний. И кроме кривых, еще иногда палитру выборочную надо сделать. Или еще что-то оригинальное. Проще всего это во внешних программах делать. В идеале - через интерфейс ST. Но он от этого из "простой программы" превращается в комбайн. И с этим много кто несогласен будет.

А что еще важнее, в STEX нет разделения вывода, и даже если какой фильтр сработает, результат потом опять обрабатывать надо - картинки выделять, пережимать. Потому я STEX не использую вообще, в моих документах STA+самодельный PDF быстрее выходит, даже с промежуточной ручной обработкой картинок.

@zvezdochiot
Copy link
Member

zvezdochiot commented Apr 28, 2024

@noobie-iv say:

Но он от этого из "простой программы" превращается в комбайн. И с этим много кто несогласен будет.

Ну так это только ваша задумка. От того всё сложно и получается, потому как вы эту сложность заложить и пытаетесь.
Моя же задумка - макетирование страниц и поблочная обработка, что оставляет простоту для простых страниц, но позволяет любую сложность для сложных страниц. И полностью согласуется со структурой STEX. Такие вот дела. ;)

PS: Я больше скажу: в моей задумке перенести вкладки зон с Output на Blocks, тем самым разгузив Output и упростив работу с Zones.

PS2: Я конечно могу занести в STEX:
https://github.com/ImageProcessing-ElectronicPublications/imthreshold/blob/c03843f92b8c8644822d5c77eb06cfd587b0680b/src/filter.cpp#L33-L34
https://github.com/ImageProcessing-ElectronicPublications/imthreshold/blob/c03843f92b8c8644822d5c77eb06cfd587b0680b/src/filter.cpp#L42-L43
https://github.com/ImageProcessing-ElectronicPublications/imthreshold/blob/c03843f92b8c8644822d5c77eb06cfd587b0680b/src/filter.cpp#L47-L49
, но не жирновато ли будет по фильтрам? Длина списка увеличится почти в двое! И чего тогда с ним делать? Только ежели заменить список на подсписок главных фильтров (S-,C-кривые и выравнивание) и селектор вспомогательных. Но с ГУИ у меня траблы, так что не по мне выделка. Вот ежели на уже имеющихся фильтрах покажите, как это грамотно сделать, тогда я дополню список селектора вспомогательных фильтров.

PS3: Фильтр, о котором вы говорили - это собственно LevelMean в списке выше. ;)

@trufanov-nok
Copy link
Member

Емнип, нельзя позволять exception выбрасываться за пределы конструктора, например вот поэтому: https://stackoverflow.com/a/71887635/841424
Если в конструкторе есть код, который может выдать excepion - его нужно в конструкторе и ловить, а потом коммуницировать об ошибке какимто др способом: флаг m_isValid ставить, Qt сигнал с описанием ошибки бросать...

@plzombie
Copy link
Contributor Author

plzombie commented May 9, 2024

@trufanov-nok это всё прекрасно, но прямо любой пример по RAII берёшь, и там конструктор кидает exception. Моя бы воля, я бы в конструкторе вообще ничего не делал кроме инициализации атрибутов простых типов, а всё остальное в методы Create()/Destroy() (ну и в деструкторе if(isInit()) Destroy(); добавить)

@noobie-iv
Copy link
Member

@plzombie

и не оборачивать в try {} catch {} всё содержимое main

В любой функции можно сгородить вложенный блок-трюкач. Есть даже специальный синтаксис, когда все тело функции - один большой блок:

#include <iostream>

void f() try {
    throw 0;
} catch (...) {
    std::cout << "Oops!";
}

int main()
{
    f(); // Oops!
}

Так же можно завернуть в блок все тело конструктора или деструктора, тогда из них тоже ничего не вылетит:

#include <iostream>

struct A { 
    A() { throw 0; }
};

struct B : public A
{
    B() try : A() {} catch(...) { std::cout << "Gotcha!"; }
};

int main()
{
    B b; // Gotcha!
}

любой пример по RAII берёшь, и там конструктор кидает exception

Если исключением кидается конструктор, все OK. Просто на уровне какой-то функции (не обязетельно main) надо сгородить трюкача, который разбирается с последствиями.

А если кидается деструктор - то один раз так сделать можно, все даже будет работать. Но вот если исключение уже выброшено, и еще не обработано до конца, прямо сейчас идет чистка стека, а чей-то деструктор кинет еще одно исключение - тогда программа вылетает без возможности обработки. Почему так - не пишут, видимо, есть сложности в реализации на уровне компилятора, про которые слишком долго рассказывать. Может, параллельная обработка ломает гарантию чистки в порядке, обратном созданию. Может, добавляет код, который должен работать и в случае, если исключение не выброшено. А может, еще какие фокусы есть.

Для себя понимаю так: кидать исключение из деструктора можно, если освобождение ресурса настолько важно, что нельзя его оставить занятым. Если какой-нибудь важный файл не закрылся - значит, все настолько поломалось, что попытка продолжать работу может его доломать окончательно, и лучше вылететь, чем добить его до состояния, когда никто его уже не починит. Но это только в режиме параноика для особо важных программ и ресурсов. А в обычных лучше слушать старших, и в деструкторе не хулиганить.

я бы в конструкторе вообще ничего не делал кроме инициализации атрибутов простых типов

Еще пишут, что плюсовый код на исключениях работает быстрее, чем сишный на ручной обработке кодов возврата, потому что в основной логике программы нет никаких лишних ветвлений. Вроде как для того исключения и придумали - ускорить код, плюс никогда не забывать про обработку.

А вот если исключение вылетело - тут тормоза будут сильнее, чем при ручной обработке, поэтому нельзя включать трюкачей в основную логику взамен всяких if-then, и тем более в нагруженные циклы.

Вариант с ручной обработкой через Create/Destroy получается средним - вроде есть автоматическая чистка, но возвращается лишняя писанина с проверкой, которую можно забыть. И если забыть, то появляется объект, который вроде как создан, но внутри-то у него мусор. Из-за этого придется лепить чтото вроде if( ! IsInit() ) Create(); на каждом вызове каждого метода, на случай, что Create забыли сделать при создании. Подозреваю, что для решения этой проблемы придумали паттерн Builder, который весь этот геморрой прячет внутри метода Build - и ловит исключения, и выпускает наружу только правильно созданный объект, и потому позволяет внутри методов лишних проверок не ставить.

никто, почему-то, не пишет

Есть такая проблема, да. Я с плюсами на любительском уровне лет 15 знаком, а программистом не стал. Полно книг для чайников, но нет для кофейников. Я и в этот проект полез из любопытства - хоть раз посмотреть, как реальные программы устроены, а не примеры "сложите 2 и 2. подумайте, можно ли их еще и умножать".

@zvezdochiot
Copy link
Member

zvezdochiot commented May 10, 2024

@plzombie say:

Моя бы воля, я бы

Сделайте уже нормальный селектор доп.фильтров (к основным относятся только кривые и выравнивание). А то я сам от безысходности его слеплю и это будет откровенно кривая, уродливая и глючная фигня!

@zvezdochiot
Copy link
Member

@zvezdochiot say:

А то я сам от безысходности его слеплю и это будет откровенно кривая, уродливая и глючная фигня!

Ну как то так: 51b8f42

@zvezdochiot
Copy link
Member

@noobie-iv say:

Мини-проект "для разобраться" я себе завел. Сколько времени он отнимет - не знаю. С одной стороны, учить Qt мне нафиг не надо, потому что больше оно мне нигде не понадобится. С другой стороны, поразбираться с многопотоком, возможно, полезно. Так что какое-то время я еще здесь. Если после проекта починить STD до релизного состояния не выйдет, придется на участие в ST забить.

Доп. матариал (значительно более простой для разбора): Yet Another Scan Wizard.

@zvezdochiot
Copy link
Member

zvezdochiot commented May 18, 2024

@plzombie , в релизе не перебор? ( ❓ в названиях файлов и Win32, и X86-64).

PS: Ежели всё норм, то я в винде вообще перестаю что то понимать. Одним словом меня можно назвать - "ископаемое".

@plzombie
Copy link
Contributor Author

@zvezdochiot Win32 - программная платформа, x86-64 - аппаратная.
А то не совсем понятно, для чего конкретно данный зип архив

@zvezdochiot
Copy link
Member

@plzombie , ну так "этого" я и не распарсиваю. Win32 - это 32-битная винда, а x86-64 - это 64-битная.

PS: применяют обозначения либо "win32" и "win64", либо "win-x86" и "win-x86-64", но никак не "win32-x86-64".

@plzombie
Copy link
Contributor Author

PS: применяют обозначения либо "win32" и "win64", либо "win-x86" и "win-x86-64", но никак не "win32-x86-64".

Есть старое апи (называемое Win16), есть Win32, есть UWP
Отдельного Win64 как такового нет https://learn.microsoft.com/ru-ru/windows/win32/
Если называть так 64бит версию, то не понятно, как тогда обозвать версию для aarch64

Ну и тогда называться должно x86,x64,ARM64 (в терминологии вижуалстудии. или в терминологии линукс-дистрибутивов - i686,AMD64,AARCH64)

А обозначения x86-32/x86-64/ARM64 я использую так как так проще было называть установщик, не надо название хардкодить под каждую комбинацию архитектура+разрядность

@zvezdochiot
Copy link
Member

zvezdochiot commented May 18, 2024

@plzombie , ❓ так почему не "win-x86-64"? К чему тут "win32"? "32" что значит?

@plzombie
Copy link
Contributor Author

Потому что API называется Win32

@zvezdochiot
Copy link
Member

@plzombie , ага, вот теперь наконец распарсил. Ну и "мудрень". X0

@noobie-iv
Copy link
Member

@zvezdochiot

Доп. матариал

Не поможет. Я не собираюсь сделать работающую "такую же, но проще" версию. Я хочу понять, как работает ST. Мне хватит пары примитивных фильтров, но чтобы в принципе они были устроены как в оригинале.

По факту я потихоньку копипащу код из ST, пока не получится минимально работающее главное окно с центральной картинкой и превьюшками. Потом можно будет попробовать встроить туда макетирование. А потом по аналогии сделать то же в ST.

На сегодня у меня есть пустое главное окно с панельками, и полтора десятка классов типа "Получатель", "Возвращатель полученного", "Передаватель возвращенного", "Возвращатель переданного возвращенного обратно получателю через представителя", "Подставной представитель", "Поручитель подставного представителя", "Приниматель поручителя", и т.д. по списку. Программа по-прежнему не делает ничего полезного, а классы пока только ссылаются друг на друга, ни в одном из методов не заканчиваясь хоть каким-то реальным действием. На подходе, видимо, еще десяток-другой аналогичных бездельников.

Когда я для теста извлекал деварп, я так больше мегабайта кода вынужден был скопипастить, чтобы он только компилировался; я даже не стал проверять, что он вообще работает. Если тут придется мегабайт с нуля набрать - это мне лет на десять работы выйдет. Пока я не вижу ни одного реального действия в программе, и не могу понять, что тогда все эти "Абстрактно-теоретические заменители реальности" делают. Пока что происходящее напоминает мне известный FizzBuzzEnterpriseEdition

@zvezdochiot
Copy link
Member

@noobie-iv say:

Я не собираюсь сделать работающую "такую же, но проще" версию.

Ну это ты зря. Многие поклоники SK спят и видят, когда же кто-нибудь "придумает" STM (Scan Tailor Mini), занимающийся только разрезкой, преобразованиями и выравниванием. Это и к твоим целям более ближе: нарезал, выпрямил и выровнял, а дальше в любом редакторе делай что хочешь.

Сам же щаз думаю, как бы на этапе 3 "Геометрические преобразования" прикрутить индивидуальный масштабный фактор (по умолчанию 1.0000). Своего рода выравнивание DPI без самого DPI. И нужно именно на 3-ем этапе (в крайнем случае на 4ом, но на 4ом логика этого коэфициента теряется). Такие вот дела.

@noobie-iv
Copy link
Member

@zvezdochiot

Scan Tailor Mini

Для таких желающих достаточно в ST перевести картинки в цветной режим.

дальше в любом редакторе

Любой редактор тем и неудобен, что не дает списка листов и повторной пакетной обработки по ним. Фишка ST же в том и есть, что он все в одном за три щелчка может. Вот только набор фукнций лично мне маловат, отсюда и страдания.

на этапе 3 "Геометрические преобразования" прикрутить индивидуальный масштабный фактор

Минимум два надо - по X и Y. Здешний деварп слишком любит пропрорции корежить.

@plzombie
Copy link
Contributor Author

Кто-нибудь может мне в фотошопе сохранить TIFF со слоями? Хочу сравнить с тем, что делает GIMP (тупо несколько страниц с X/YPosition)

@zvezdochiot
Copy link
Member

@plzombie say:

Кто-нибудь может мне в фотошопе

Точно не я, но тут есть участник на макосе: @gasparschott . У него поспрашивай (на буржуйском).

@yozhic
Copy link

yozhic commented May 26, 2024

Вот, произвольный многослойный из PS на macOS: dropbox.com
Если что ещё в нём поменять надобно, пишите, поменяем. Можно и на Win сделать (тоже в PS).

Правка от @zvezdochiot : прикрепил к сообщению: PMT.zip (мало ли что с этим дропбокс)

@noobie-iv
Copy link
Member

За месяц копипасты с фигурной обрезкой получился такой микротейлор:

screen

Он только показывает фиксированную пару картинок и поворачивает их влево/вправо. До рабочих превьюшек еще далеко. Там всего десяток-другой реально содержательных строк (установка виджета, рисование картинки и т.п.). А общий объем кода уже вышел за 2000 строк. Теперь я понимаю, почему в отладчике не мог понять ни одной строки: гуевый код реально на 99% состоит из обвязки.

@zvezdochiot
Copy link
Member

zvezdochiot commented Jun 13, 2024

@noobie-iv , круть. 👍

Советую сохранить эту "поделку", на случай ежели решишь создать отдельную тулзу для создания макетов страниц (QPageMaket) и генерации PDF-страниц (а возможно и целых книг) на базе макетов. Я всё также, как и раньше, вижу решение "вопросов" к ST именно в наличии отдельной тулзы для макетирования страниц и использования цепочки:

ST -> {GIMP, Krita,... } -> QPageMaket -> PDF

PS: И всё же, хотелось бы вынести все (все!) зоны на отдельный этап, перед "Output". Это позволило бы напороч избавиться от мозолящего глаза "Mode" (какой такой режим, ежели всё обрабатывается согласно зон?), а заодно позволило бы добавить так назывемые palette-зоны, с заливкой маски выбранным цветом, как в fill-зонах, но "пипетка" будет работать на оригинальном цветном изображении + 2 зарезервированных (чёрный и белый). Такие вот дела. Да и фильтры можно было бы перенести туда же, чтобы видеть их действие, а не только на "цветном/сером" режиме.

@trufanov-nok
Copy link
Member

Впомнилось. В ST очень много всего реализовано с нуля. Если бы его делал я - то собирал бы из готовых частей, тащил бы модули из других опенсорс проектов. В свое время намучался с thumbnails list в ST (но больше всего хотелось бы, конечно, заменить машинерию для манипуляций с изображениями (выделение прямоугольником, эллипсом и пр.) ) и полез искать готовые официальные компоненты для Qt. И нашел для thumbnails list, как мне показалось, неплохой. Больше ничего не нашел. Если бы я сейчас переписывал эту часть GUI, то сперва попробовал бы использовать его: https://marketplace.qt.io/collections/all-products/products/longscroll-qt

@noobie-iv
Copy link
Member

noobie-iv commented Jun 14, 2024

@zvezdochiot

ST -> {GIMP, Krita,... } -> QPageMaket -> PDF

А я считаю, что это все как раз и должно быть прямо в тейлоре. Нужен список стадий, которые можно выбирать, а не фиксированный набор. И среди них - встроенные (нарезка страниц, деварп, размер страницы), и внешние (GIMP, GMIC, ImageMagic). Кому не надо - просто не добавляет лишние стадии. Так устроен стек модификаторов в 3D-программах. Если решу делать свое - вот так оно будет. Но литраж моих слюней пока не соответствует емкости желудка 😄.

В идеале это должны быть внешние плагины. В линуксах есть программы с плагинами? В винде нет стандартных каталогов, и обычно программа просто ставится в свою папку. А внутри папки, рядом с программой, заводится папка Plugins, куда сваливают плагины-DLL. При загрузке программа сканирует каталог, и если DLL отзывается, добавляет ее в список плагинов. Дописывать плагины, реализуя десяток стандартных функций по образцу, легче, чем пересобирать программу целиком.

хотелось бы вынести все (все!) зоны на отдельный этап

Я только начинаю слегка въезжать, что тут в коде происходит. До возможности добавлять стадии мне еще далеко (подозреваю, что несколько лет, если терпения хватит).

@trufanov-nok

В ST очень много всего реализовано с нуля

Если бы просто с нуля. Там еще отрицательные величины есть. На сегодня мой любимый образец кода выглядит так:

  • Есть некий виджет Widget, хранящий целое число m_value.
  • Если пользователь устанавливает новое значение set(1), виджет надо обновить update()
#include <iostream>

class Widget
{
public:
    void set(int value)
    {
        int old_value = m_value;
        m_value = value;
        if (m_value != old_value)
            update();
    }

private:
    void update()
    {
        std::cout << m_value << std::endl;
    }

    int m_value = 0;
};

int main()
{
    Widget w;
    w.set(1);
}

Но это же плюсы. Нельзя же в коде просто проверить значение и обновиться. Оператор if надо инкапсулировать!

  • Заводим класс Watcher
  • Класс будет следить за обновлением переменной, поэтому внутри хранит старую копию m_value
  • Класс должен сообщать об обновлении, поэтому заводим указатель на хозяина m_owner
  • В конструкторе сохраняем старое значение переменной
  • В деструкторе проверяем устарелость, и обновляем хозяина, если он устарел
  • Теперь вместо if в методе set можно создать экземпляр класса Watcher, и на выходе его деструктор обновит хозяина
#include <iostream>

class Widget
{
public:
    void set(int value)
    {
        Watcher watcher(this);
        m_value = value;
    }

private:
    void update()
    {
        std::cout << m_value << std::endl;
    }

    class Watcher
    {
    public:
        Watcher(Widget* owner)
            : m_owner(owner)
            , m_value(m_owner->m_value)
        {
        }

        ~Watcher()
        {
            if(m_value != m_owner->m_value)
                m_owner->update();
        }

    private:
        Widget* m_owner;
        int m_value;
    };

    int m_value = 0;
};

int main()
{
    Widget w;
    w.set(1);
}

Этот маленький шедевр найден в ImageViewBase (класс TransformChangeWatcher). Как говорил джокер бетмену, "с тобой безумно весело" 😄.

@trufanov-nok
Copy link
Member

Но это же плюсы. Нельзя же в коде просто проверить значение и обновиться. Оператор if надо инкапсулировать!

Тут плюсы не при чем. Тут решается конкретная задача. Я уже плохо помню код, но скорее всего update() порождает тяжелые вычисления, и делать их нужно не на каждый чих пользователя, а только когда действительно припрёт. Как пример - рисование зон на вкладке Layers в Mixed mode. Если перегенирировать результат каждый раз, когда пользователь чего-то там двигает - ST повесится. А вот когда он с этой вкладки ушел (миллионом способов он это может сделать), т.е. вызвался ~ImageViewBase() - тогда да. Скорее вот такого отложенного обновления хотели добиться.

@zvezdochiot
Copy link
Member

zvezdochiot commented Jun 14, 2024

@trufanov-nok say:

Тут плюсы не при чем.

Ещё как при чём! У меня концы с концами из-за них не сходятся:

Стадия 3 "Геометрические искажения":

  1. Без искажений - угол == 0
  2. Поровот - угол == SkewFinder (заностися в параметры)
  3. Перспектива - угол == ???, но SkewFinder используется в TextLineSegmenter. Как его (угол) оттуда вынуть и прописать в параметры?!! (точнее наоборот: как использовать угол из "Поворота" вместо повторного определения?)
  4. Кривые - угол == ???, но SkewFinder используется в TextLineSegmenter. Как его (угол) оттуда вынуть и прописать в параметры?!! (точнее наоборот: как использовать угол из "Поворота" вместо повторного определения?)

Вот тебе и не при чём. Угол поворота определяется везде, а прописывается только в варианте 2. Вот это номер! Отсюда отсутствие сортировки по углу и дубляж кода. Вот это "щастье"! Такие вот дела.

@noobie-iv say:

А я считаю, что это все как раз и должно быть прямо в тейлоре.

Чтобы не быть голословным: Что такое макетирование на примере?:

Вот оригинальный материал: page-1-2-origin.pdf [5M].

А вот обработка в STEX + GIMP и простенькое макетирование с помощью python-cropper-tk + gs и пр.: page-1-2-stex_croppertk.pdf [1M].

@noobie-iv
Copy link
Member

@zvezdochiot

Как его (угол) оттуда вынуть

Вроде как Task, CacheDrivenTask, Filter и OptionsWidget имеют указатель на настройки - m_ptrSettings. Внутри любого из них можно вытащить нужную настройку:

m_ptrSettings->getPageParams(m_pageId)->rotationParams().compensationAngleDeg();

Если доступен указатель на фильтр - из него можно получить указатель на настройки, а дальше по той же цепочке:

m_ptrFilter->getSettings()->...;

Угол поворота определяется везде, а прописывается только в варианте 2

Тут вроде как не плюсы виноваты. Это событийно-ориентированная программа. Не знаю как там в линуксах, а в виндах родное API для графических программ - чистый С без плюсов, со времен первой версии винды. Но в нем программа тоже нелинейная. Там тоже надо написать тучу функций обратного вызова, и сводить передачу данных между ними в уме. Реально линейность сидит где-то внутри очереди событий, которой рулит винда, которая дергает эти коллбеки. Но программист этого не видит, только callback-обрывки, и они тоже срабатывают когда захотят. Синхронизация данных между коллбэк-обрывками - головная боль программиста.

Qt - плюсовая обертка, но по факту работает так же. Те же сигналы, что и события винды, те же фишки с установкой фильтров. Те же проблемы с нелинейностью.

Был популярный VisualBasic - вообще не плюсы, но работал так же.

В автокаде API плюсовое (на старых плюсах - до 11), но и там идеи те же: хочешь свой объект - наследуйся и переопределяй пачку стандартных обработчиков, которых будет дергать автокад.

Я бы сказал, тут проблема в том, что большой проект (100 тыс строк) написан в одного, потому не откомментирован, и подключаться к нему тяжело. По WinApi есть описания функций, и примеры программ с нуля. По ObjectARX есть примеры. Про любую функцию есть подробности с примерами - зачем нужна, что за параметры, когда вызывается. А тут надо все три мегабайта кода лопатить, чтобы понять кто где.

Я из-за этого и начал свою микропародию писать. Добавляю десяток строк, и смотрю что они делают. В оригинальных мегабайтах я просто завяз, ни одной строки не понимаю: 99% - либо вызовы Qt, которых я не знаю, либо вызовы самодельных классов, про которые даже нагуглить нечего.

На сегодня скопипащено 2 тыс строк из 100 - это 2% за месяц. Что эти строки делают - теперь понимаю. На полное понимание таким методом, очевидно, надо 5 лет. Разумеется, я не буду смотреть алгоритмы обработки, только базовую логику. Если примитивно-базовое изображение в единственном рабочем фильтре заняло 2тыс строк, есть шанс, что код превьюшек займет столько же, а после этого (через месяц-другой) я смогу вернуться к STD и уже чинить его до первого релиза.

простенькое макетирование

Я бы тоже хотел макетирование в ST. Мне еще и разных размеров страниц не хватает: сканы строительных чертежей разноформатные.

Сейчас в главном окне хранится список ImageId c путями к изображениям, и по щелчкам запускается обработка выбранного Id по цепочке фильтров. Проблема в том, что на этот ImageId завязан весь код всех фильтров, всех виджетов, кеша превью и хз чего еще, Переделка основной логики работы требует перелопатить все три мегабайта кода. Мне такого на несколько лет работы. Самодельный внешний макетировщик, к которому можно потихоньку фильтры прикручивать, может, и проще, но до конца его довести - тоже много лет.

@zvezdochiot
Copy link
Member

@noobie-iv say:

Самодельный внешний макетировщик, к которому можно потихоньку фильтры прикручивать, может, и проще, но до конца его довести - тоже много лет.

Ненадо никакого "до конца"! Ну о чём мы говорим? О том, что сейчас я делаю макетирование с помощью откровенного питоновского говна через reportlab, которым даже закодировать "по-людски" никак нельзя (он везде пихает ASCII85). Нафиг мне этот рак, дайте хоть какую-нибудь рыбу!

@noobie-iv
Copy link
Member

Нужен макетировщик, который смотрит проект ST с размеченными картинками, и позволяет экспортить в PDF/DJVU?

@zvezdochiot
Copy link
Member

zvezdochiot commented Jun 15, 2024

@noobie-iv say:

Нужен макетировщик, который смотрит проект ST с размеченными картинками, и позволяет экспортить в PDF/DJVU?

Нет. На данный момент в проектах ST необходимого нет. Макет - это фактически плитка из прямоугольных областей, каждая из которых может быть упакованна разным способом (JPEG, JPX, DEFLATE, CCITT FAX GROUP 4, JBIG2) и со своим масштабным фактором. Сейчас же я делаю подобное с помощью указанной питоновской поделки + GhostScript + препарирую (режу на объекты), вычлеяя JPEG и JPX, перекодирую и сшиваю обратно PDF.

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

@zvezdochiot
Copy link
Member

zvezdochiot commented Jul 13, 2024

@noobie-iv , @plzombie , @trufanov-nok .

Модифицирую 4-ый этап "Полезная область" под регулятор:

Вконец запутался: всё есть, но ни шиша не работает. Ненавижу плюсы. Может кто подскажет, где собака порылась?

Суть же проста: мне нужно довести коэффициент из ГУЯ в

BinaryImage bw150(binarizeEdgeDiv(GrayImage(gray150), QSize(51, 51), 0.0, 1.0, 0));

и поставить его вместо 0.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dispute Debate enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants