Картинка из буфера DIB

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Constantine
Активист
Сообщения: 185
Зарегистрирован: 07 Февраль 2017, 16:58

Картинка из буфера DIB

Сообщение Constantine »

Я бы, все-таки, для начала посоветовал бы удостовериться, что DIB все-таки 24-битный.
Для этого нужно считать BITMAPINFOHEADER и посмотреть параметр biBitCount. Для 24-битного там должно быть 24 :-)
Если битмап все-таки 24-битный, то пример 32-битного вряд ли подойдет: там совсем другая структура.
А известно как именно внешняя функция создает битмап?
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Картинка из буфера DIB

Сообщение Игорь Столяров »

Constantine писал(а): 27 Январь 2020, 15:11 А известно как именно внешняя функция создает битмап?
Да. Не пугайте меня пожалуйста наворотами заголовков графических файлов, мне бы с базовым Bitmap разобраться. ;)
DLL формирует традиционный Bitmap, есть даже пример его разбора и печати.

Код: Выделить всё

 int row, col, i = 0;
 unsigned int red, blue, green;

 for (row = 0; row < my_symbol->bitmap_height; row++) {
      for (column = 0; col < my_symbol->bitmap_width; column++) {
           red = my_symbol->bitmap[i];
           green = my_symbol->bitmap[i + 1];
           blue = my_symbol->bitmap[i + 2];
           render_pixel(row, column, red, green, blue);
           i += 3;
      }
 }
За теми кто отстал - не возвращаться. (С) Кодекс
Constantine
Активист
Сообщения: 185
Зарегистрирован: 07 Февраль 2017, 16:58

Картинка из буфера DIB

Сообщение Constantine »

Пугать не буду... :-)
Но с заголовком разбираться все равно придется...
Судя по коду, битмап действительно 24-битный.
Тогда его размер нужно считать так, как я написал выше.
Последний параметр BMPINFOHEADER - biSizeImage считается как BYTELINE*HEIGHT.
Структура BITMAPINFOHEADER:

Код: Выделить всё

!BITMAPINFOHEADER GROUP,TYPE   !Заголовок битмапа
!biSize                  ULONG
!biWidth                 LONG  ! Ширина изображения
!biHeight                LONG   ! Высота изображения
!biPlanes                USHORT
!biBitCount              USHORT
!biCompression           ULONG
!biSizeImage             ULONG
!biXPelsPerMeter         LONG
!biYPelsPerMeter         LONG
!biClrUsed               ULONG
!biClrImportant          ULONG
!                    END
Вам сначала нужно ее считать и посмотреть, что из себя представляет битмап.
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Картинка из буфера DIB

Сообщение kreator »

Constantine, Вы ещё забыли про BITMAPFILEHEADER. Он записан до приведённой Вами структуры.
We are hard at work… for you. :)
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Картинка из буфера DIB

Сообщение vic7tar »

Игорь Столяров писал(а): 27 Январь 2020, 9:51 Внешняя DLL формирует буфер с картинкой в обычном DIB формате (3 байта на пиксель) и возвращает её размер.
Если это продолжение борьбы с Zint, то причём тут DIB. Формируется обычный BitMap с разрядностью точек 32.
Базовыми функциями Clarion-а эту матрицу пикселей не вывести. Или вручную формировать в памяти картинку (примеры есть в Инете, но дальше формата BMP не продвинетесь) или другими способами.
C10, Win10x64
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Картинка из буфера DIB

Сообщение kreator »

Что касается BMP-формата, то biBitCount=24, а на пиксель всё равно отводится 4 байта. Проверил на Corel. Т.е. надо формировать последовательность из четырёх байт. Тогда кларионовский имидж поймёт эту последовательность.
We are hard at work… for you. :)
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Картинка из буфера DIB

Сообщение vic7tar »

kreator писал(а): 27 Январь 2020, 17:43 Т.е. надо формировать последовательность из четырёх байт.
Ну да, правильно, а четвертый заполнять нулём.
kreator писал(а): 27 Январь 2020, 17:43 Тогда кларионовский имидж поймёт эту последовательность.
А как он его поймёт? Вроде бы Clarion может работать с полноценными форматами, и то из файла или Blob-а. Или я заблуждаюсь?
C10, Win10x64
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Картинка из буфера DIB

Сообщение Игорь Столяров »

Нет, я пас. Спасибо за разъяснения.
Задача трансформации 24-битного bitmap в 32-битный DIB с заголовком в памяти пока для меня нерешаема.
Попробую вернуться к ней позже ...
За теми кто отстал - не возвращаться. (С) Кодекс
Constantine
Активист
Сообщения: 185
Зарегистрирован: 07 Февраль 2017, 16:58

Картинка из буфера DIB

Сообщение Constantine »

Ну, Игорь, не все так плохо! :-)
Задача обработки DIB средствами Клариона вполне решаема, ничего особо мудрого там нет.
Нужно разобраться в двух моментах:
1. Что именно лежит в DIB, формируемой внешней функцией, и
2. Как это подсунуть кларионовскому Image.
По первому вопросу возможно три варианта:
1. В DIB лежат только пиксели, без каких-либо заголовков (маловероятно).
2. Нормальный DIB: структура BITMAPINFOHEADER + пиксели.
3. Нормальный DIB, к которому зачем-то пришпилили заголовок файла *.BMP: BITMAPFILEHEADER + BITMAPINFOHEADER + пиксели.
Проще всего это сделать, проанализировав исходный код внешней функции, который, судя по всему, у Вас есть.
Судя по коду, который Вы приводили выше, эта самая внешняя функция, в числе прочего, производит конвертацию 32 бит - 24 бит, так что ничего дополнительно конвертировать Вам не нужно.
Таким образом, задача сводится всего-навсего, к вычислению смещения структуры BITMAPINFOHEADER и массива пикселей в исходной DIB.
Соответственно, по второму вопросу, нужно разобраться, что именно нужно подсовывать кларионовскому Image. Здесь есть два варианта:
1. Скорее всего, это нормальный DIB: BITMAPINFOHEADER + пиксели. В этом случае, Вам нужно всего лишь правильно подсчитать размер памяти:
biSizeImage + biSize.
2. Маловероятно, но может быть отдельно BITMAPINFOHEADER и пиксели. В этом случае, Вам нужно всего лишь правильно подсчитать адреса: пиксели будут начинаться с ADDRESS(...) + biSize. Количество пикселей - biSizeImage.
kreator писал(а): 27 Январь 2020, 17:43 Что касается BMP-формата, то biBitCount=24, а на пиксель всё равно отводится 4 байта.
Это не *.BMP, а DIB. Вся необходимая информация лежит в BITMAPINFOHEADER. Четвертый байт в 32-битном DIB - это прозрачность. 24-битный ее не поддерживает. Как ни странно, но основные проблемы с 32-битным форматом: мало кто может его корректно отобразить, поэтому целесообразно его конвертировать в 24-битный.
P.S. А можно показать код функции render_pixel? Я, в свое время, делал конвертацию 32-бит - 24 бит через WinAPI GetPixel(), возможно, там как-то по-другому?
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Картинка из буфера DIB

Сообщение Yufil »

Может быть, всё-таки ClarionFreeeImage поможет? Там можно использовать готовые шаблоны, а можно отдельно библиотеку FreeImage.
Когда-то лет 15 назад выкрутился ( традиционно волшебные слова LockThread - UnlockThread).
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7330
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Картинка из буфера DIB

Сообщение Игорь Столяров »

Constantine писал(а): 28 Январь 2020, 8:51 А можно показать код функции render_pixel
А нет кода - это просто заглушка, что бы показать содержание формируемого Bitmap.
И сказано, что render_pixel() - это некая пользовательская функция визуализирующая сформированный DLL Bitmap.
За теми кто отстал - не возвращаться. (С) Кодекс
Constantine
Активист
Сообщения: 185
Зарегистрирован: 07 Февраль 2017, 16:58

Картинка из буфера DIB

Сообщение Constantine »

Жаль... :-( Через GetPixel() медленно получается...
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Картинка из буфера DIB

Сообщение kreator »

vic7tar писал(а): 27 Январь 2020, 18:02 kreator писал(а): ↑
27 Январь 2020, 17:43
Тогда кларионовский имидж поймёт эту последовательность.

А как он его поймёт? Вроде бы Clarion может работать с полноценными форматами, и то из файла или Blob-а. Или я заблуждаюсь?
Я имел ввиду последовательность вместе с заголовком.
Не вижу проблем создать нужную последовательность из того, что выдаёт внешняя dll. Если есть возможность, лучше эту последовательность правильно настроить во внешней проге.
Повторюсь. Я манипулирую "ручными" bmp-картинками, проблем нет.
We are hard at work… for you. :)
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

Картинка из буфера DIB

Сообщение Дед Пахом »

vic7tar писал(а): 27 Январь 2020, 18:02 Вроде бы Clarion может работать с полноценными форматами, и то из файла или Blob-а. Или я заблуждаюсь?
  • Из файла: Prop:Text
  • Из блоба: Prop:Handle
  • Из памяти: Prop:ImageBits
С уважением, ДП
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Картинка из буфера DIB

Сообщение vic7tar »

kreator писал(а): 28 Январь 2020, 10:35 Я имел ввиду последовательность вместе с заголовком.
Так автор библиотеки так и делает, формирует BMP ручками, потом всё это дело пишется на диск. При желании формируется матрица пикселей, а что с ними делать решает пользователь.
C10, Win10x64
Ответить