|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Я делаю как. 1) выгружаю исходный TIFF в многофреймовый битмап m_Bitmap Код: vbnet 1.
и могу с ним работать, фокус на отдельную страницу устанавливается так Код: vbnet 1.
ну и т.д. 2) создаю другой битмап m_CoverBitmap и туда рисую в соответствии с разрешением первого то что хочу сделать первым фреймом (это быстро) -он пока что в памяти 3) а финальный TIFF делается грубо говоря, сначала пиханием в него вновь созданного m_CoverBitmap, а затем перерисовкой в него фреймов исходного m_Bitmap последовательно, приведу кусок кода. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73.
Суть в чем, я по сути перерисовываю исходный TIFF заново в новый на довольно низком GDI+ уровне, что для 1-2 страниц несущественно по времени, а если страниц уже скажем 5-10-20 то операция накладная. Ну, оно конечно работает но долго. Мне по сути надо сдвинуть имеющиеся страницы в конец файла, ничего вообще в них не меняя, ни компрессии, ни размеров, ни разрешения, ни цветности (ч/б, 2 цвета), и вставить первую страницу. Свойства исх. файла (разрешение, компрессия) я вычислять умею - это быстро - чтобы правильно сделать вставляемую в начало новую страницу, которая у меня в памяти сидит как m_CoverBitmap. А вот как их быстро срастить? На сколько я понимаю, когда я делаю m_Bitmap = New Bitmap(FileName), я теряю "свойства" исходного файла, и вынужден ваять этот файл по сути рисуя заново, на что уходит время. М.б. сумбурно объясняю, но как смог чтобы не приводить простыни кодов и не сбивать с толку. В общем я хочу эту страничку "дорисовать" быстро. Ну или поставим задачу так: Есть 2 независимых TIFF с одинаково-совместимыми свойствами (компрессия, разрешение, размеры и т.д.), как бы их срастить в такой же "формат" в единый файл? ... |
|||
:
Нравится:
Не нравится:
|
|||
29.08.2018, 06:01 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Формат ttff прост и документирован, склеить несложно ... |
|||
:
Нравится:
Не нравится:
|
|||
29.08.2018, 12:10 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Изопропил, Я похоже лишние операции делаю Т.е. заново создаю структуру битмапа, и занимаюсь перерисовкой (см. фрагмент кода выше) Код: vbnet 1. 2. 3. 4. 5. 6. 7.
А это время-затратная операция, тогда как в моей текущей задаче просто достаточно дописать имеющиеся фреймы в новый tiff. Уши растут вот отсюда: Корректная конвертация ч/б TIFF(200х100)->BMP,JPG и т.п. Но там мне требовалось сжимать-растягивать картинку в связи с изменением разрешения, и простое пересохранение приводило к изменению глубины цветности с 2 цветов (ч/б) на 32-бит. Если мне в сращиваемых картинках ничего менять не надо, то все итак вроде итак будет OK и все эти свистопляски с перекачкой одного битмапа в другой не нужны, и будет на порядки быстрее. Попробую сделать аккурато, посмотрю. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.08.2018, 17:04 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Дмитрий77, Приписать в вставляемую страницу в конец файла, список IFD скорректировать, смещения пересчитать Ничего сложного ... |
|||
:
Нравится:
Не нравится:
|
|||
29.08.2018, 20:03 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
ИзопропилПриписать в вставляемую страницу в конец файла, список IFD скорректировать, смещения пересчитатьИзопропил, Ну ты предлагаешь сращивать, копаясь в файлах на байтовом уровне и знании формата (c SFF так как-то возился). Зачем, если можно сделать штатными даже .Net классами, не вдаваясь в низкоуровневые подробности. Я без GDI +/- все одно не обойдусь, титульный лист я генерирую на ходу. 1) Т.е. есть файл, про него нужно знать: (1)разрешение (2) compression -это я знаю как, узнал 2) Теперь создаю CoverPage зная (1)разрешение , кот. узнал на первом шаге. 3) Сохраняю CoverPage и добавляю фреймы из исходного файла. Делаю это используя (2) compression , кот. узнал на первом шаге. У меня класс, который работает с мульти-фреймами писан давно, изначально еще на VB6 и шибко путанный, решил нахаляву добавить туда этот функционал и огреб. Т.е. результат то получил, но много лишних операций (кусок кода в первом посте). В итоге "очень долго". Но счас все сделал без лишнего, получилось быстро (условно "мгновенно"), даже если подсовываю CoverPage под 50 страниц. 1. взял исх. файл, воткнул его в Bitmap, также узнал его (1)разрешение (2) compression , не суть как, умею. Код: vbnet 1.
2. сваял Cover Page, с учетом разрешения исходного файла (всего два варианта 204x196 или 204x98, им соответствуют размеры соответственно 1728x2339 и 1728x1169 для A4,PORTRAIT). Здесь без GDI да и без API не обойтись и структуру BITMAPINFO2 надо задавать. Использую FaxPrintCoverPageW function , причем недокументированно (без предварительного вызова FaxStartPrintJob как они там вещают в MSDN), моя задача "угнать" картинку в свой hdc, который я готовлю через CreateDC+CreateCompatibleDC. Ну в общем справился, на выходе имею битмап m_CoverBitmap, совместимый с исходным файлом. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133.
3. А вот дальше надо срастить m_CoverBitmap + m_Bitmap, для каноничности в той же "compression", что и исходный файл. И здесь как бы код вполне красивый и простой работает прилично и быстро, в отличии от тех наворотов, которые у меня были изначально: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.
Все четко-быстро. На выходе желаемый гибрид в нужном разрешении и компрессии. Понятно что два TIFF я аналогично сращу подобным же кодом двумя циклами (ну то что те кого сращивают должны быть совместимых разрешений/размеров это понятно на совести кодописателя). Здесь главное не плодить новых битмапов из одного в другой (можно нарваться что разрешение и палитра скаканут если не думая), и не плодить всяких DrawImage/BitBlt - можно нарваться на непотребное время работы кода. Ну OK вроде. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.08.2018, 05:34 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Дмитрий77, Ты же хочешь чтобы быстро было и без ковыряний в подробностях Для этого достатчно осилить несколько страниц описвния формата, причём не вникая в семантику ... |
|||
:
Нравится:
Не нравится:
|
|||
30.08.2018, 08:30 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
ИзопропилТы же хочешь чтобы быстро было и без ковыряний в подробностях Дык уже получилось быстро и считай без особых ковыряний. Код крайний мой смотрел внизу? Где там ковыряния? Просто грузишь tif-ы в битмапы (тупо одной строкой), и последовательно бухаешь все фреймы в новый файл, проходясь по битмапам циклом .SelectActiveFrame(FrameDimension.Page, i - 1). Проверил нарочно на более слабом компе, все равно быстро. cover+52 страницы, меньше секунды, это с учетом таки "ковыряния" с cover. ИзопропилДля этого достатчно осилить несколько страниц описвния формата, А вот это уже ковыряния будут. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.08.2018, 23:03 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
склеить Если просто склеить, вот накатал ф-цию, м.б. кому пригодится. !!! заведомо известно, что разрешения одинаковы иначе ИМХО фигня будет. (и в зависимости от задачи м.б. чего еще, для меня размеры критичны) Т.е. оно не анализирует "форматы" склеиваемых файлов. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81.
... |
|||
:
Нравится:
Не нравится:
|
|||
22.09.2018, 05:15 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Дмитрий77склеить Если просто склеить, вот накатал ф-цию, ... Мелкий непонятный глюк обнаружил.. Клею 4 файла кодом что полностью привел выше file0 (1 page) file1 (1 page) file2 (1 page) file3 (2 pages) На выходе получаю TIFF (5 pages): file0(1 page)-file1(1 page)-file2(1 page)-file3(2 pages) Вполне таки съедобный, т.е. кушается факс программой в правильной последовательности страниц file0-file1-file2-file3, виндовая программа также показывает страницы в этой же заказанной последовательности file0-file1-file2-file3. А если применить к этому склеенному TIFF утилиту tiff2pdf (из libtiff), то в PDF последние 2 блока переставлены . file0(1 page)-file1(1 page)- file3(2 pages)-file2(1 page) Как такое может быть? Если смотреть код выше 1) Самую первую страницу сохраняю с EncoderValue.MultiFrame 2) Все остальное добавляю с EncoderValue.FrameDimensionPage в заказанной последовательности страниц 3) В конце делаю EncoderValue.Flush Ну, факс-прога и просмотрщик виндов очевидно смотрят на физическую последовательность страниц А вот tiff2pdf видимо смотрит в какую-то "таблицу". В моем примере file0,file1,file3 финализированы через GDI (винды) file2 - сделан из SFF утилитой sff2tiff, возможно содержит признак последней страницы, не знаю Подозреваю что tiff2pdf это как-то отсекает, из за чего пихает его в конец. Смотрел, есть еще флаг EncoderValue.LastFrame - Указывает последний кадр многокадрового изображения. Может передаваться кодировщику TIFF в качестве параметра категории флага сохранения. Я его никак в коде не использую, м.б. воткнуть, только куда? (копать на низком уровне ес-нно желания нет) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2018, 20:27 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
В общем с ходу не могу понять. EncoderValue.LastFrame - если вставить в конец ничего не дает. Если клеить скажем несколько многостраничных, сам склеенный tiff типа нормальный, но конвертишь его потом в pdf через tiff2pdf, может сначала сохранить первые страницы из вклеек, потом вторые и т.п. и какую-нибудь серединную вклейку скинуть в конец pdf-а. Т.е. виндовский gdi-encoder чего-то (по tiff-науке) не дописывает в БЫСТРО склеенный файл, а libtiff (tiff2pdf) в итоге трактует последовательность страниц по своему. Чего в быстром коде склейки добавить-поменять, у меня идей нет. Если делать с пересозданием и полной перерисовкой битмапов, как в моем верхнем посте, то глюков надо думать не будет, но это будет очень медленно. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2018, 23:35 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Дмитрий77копать на низком уровне ес-нно желания нет И что в этом естественного? Дмитрий77Чего в быстром коде склейки добавить-поменять, у меня идей нет Для начала ознакомиться с описанием формата Хотя «что тут думать, трясти нужно» ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2018, 00:38 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
ИзопропилХотя «что тут думать, трясти нужно» Пытаюсь. Смотрю что показывает утилита tiffinfo.exe (libtiff). Клею 1.tif + 2.tif своей быстрой JoinTiffImages 1.tif (2 страницы) Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
2.tif (2 страницы) Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
После склейки имеем вот это: final.tif = 1.tif + 2.tif Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53.
Файл типа рабочий (если не копать, а последовательно читать картинки), но подвох в нумерации страниц, он их не перенумеровал 0-4 1-4 2-4 3-4 а оставил как есть 0-2 1-2 0-2 1-2 Виндовский вьюер - читает правильно. При попытке сделать этому файлу tiff2pdf имеем неправильную последовательность: 1(стр.1)-2(стр.1)-1(стр.2)-2(стр.2) (умничает, но тасует) Вьюер от вентафакс показывает только первые две страницы. Кто во что горазд (типа кто как начитался теории, так и интерпретирует). Спрашивается, почему моя ф-ция JoinTiffImages m_BaseBitmap.Save m_BaseBitmap.SaveAdd ... не проставляет новые номера страниц при создании нового tiff. GDI+ же не настолько тупое, значит я что-то упустил или как так? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2018, 01:30 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
не проставляет новые номера страниц при создании нового tiff. Вроде нащупал куда копать. PropertyTagPageNumber Код: vbnet 1.
Задается для каждой страницы каждого bitmap Прочесть можно типа так Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8.
В моем примере выдаст 0,2 1,2 0,2 1,2 Код склеивания (быстрого) эти таги не перезаписывает. Отсюда бардак. Как простой вариант, можно просто их поудалять. Код: vbnet 1. 2.
(ничего лучше чем путаница), а далее зависит от вольной интерпритации проги, что будет работать с этим tiff. Ну т.е. tiff2pdf уже будет в правильной последовательности страниц, а вот какая-нибудь вента вообще этот тиф не прочитает. Поэтому видно придется попариться и прописать таки эти таги "ручками" в каждый фрейм чтоб аккуратно было. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2018, 03:25 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Все, осилил, теперь без глюков. Пришлось изуродовать ф-цию и вычислять-пихать SetPropertyItem(<Image_Property_ID_Tags.PropertyTagPageNumber>) в каждую страницу. Но это жесть какая-то: Image.SetPropertyItem(PropertyItem) Method It is difficult to set property items, because the PropertyItem class has no public constructors . One way to work around this restriction is to obtain a PropertyItem by retrieving the PropertyItems property value or calling the GetPropertyItem method of an Image that already has property items. Then you can set the fields of the PropertyItem and pass it to SetPropertyItem. А вообще фигня, что эта Encoder-кухня сама автоматом страницы не нумерует при записи файла. Либо я чего-то недоглядел, недочитал. Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2018, 06:45 |
|
А есть способ БЫСТРО запихнуть еще одну страницу в начало многостраничного TIFF
|
|||
---|---|---|---|
#18+
Нет, но вообще ерунда какая-то. Посмотрел тут еще ряд старых своих кодов, где я просто сохраняю что-то в TIFF через GetEncoderInfo("image/tiff"). Не пишет он сволочь PropertyTagPageNumber, хоть по пикселям рисуй, хоть тупо клей. Плюс Но это жесть какая-то: Image.SetPropertyItem(PropertyItem) Method It is difficult to set property items, because the PropertyItem class has no public constructors . One way to work around this restriction is to obtain a PropertyItem by retrieving the PropertyItems property value or calling the GetPropertyItem method of an Image that already has property items. Then you can set the fields of the PropertyItem and pass it to SetPropertyItem. До кучи вот нашел еще на эту тему: Назначение свойств изображению Т.е. получается и "ручками" этот PropertyTagPageNumber и не всегда вставишь (в общем случае). Если я гружу m_bitmap из файла, m_Bitmap = New Bitmap(imageFiles) OK, я получаю объект PropertyItem (хоть какой-нибудь, чтоб его потом мудифицировать) как m_bitmap.PropertyItems(0). А вот если я этот m_Bitmap создаю с нуля, чтоб в него рисовать, а потом сохранить (ну например распечатка чистой Cover Page на hdc как приводил пример), то мне и взять-то PropertyItem в общем случае (без извращений) неоткуда, потому как в m_bitmap.PropertyItems(0) будет тупо пусто (до того как во что-то сохранил). Я вот думаю, надо ли продолжать копать или просто забить (для случаев когда просто сохраняю одну страницу TIFF или даже несколько страниц с нуля). Если одна страница или несколько без PropertyTagPageNumber в страницах, то большинство софта (включая мой) будут с этим TIFF корректно работать (тупое последовательное чтение картинок). Бардак возникает только при склеивании, когда в тагах получается мешанина: то бишь где-то страницы указаны, где-то нет, где-то повторяются, где-то некорректно указано общее к-во страниц, но эту основную проблему вроде как порешил. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2018, 18:11 |
|
|
start [/forum/topic.php?fid=20&fpage=27&tid=1399231]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
43ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
61ms |
get tp. blocked users: |
2ms |
others: | 13ms |
total: | 165ms |
0 / 0 |