Страница 2 из 3

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

Добавлено: 27 Январь 2020, 15:11
Constantine
Я бы, все-таки, для начала посоветовал бы удостовериться, что DIB все-таки 24-битный.
Для этого нужно считать BITMAPINFOHEADER и посмотреть параметр biBitCount. Для 24-битного там должно быть 24 :-)
Если битмап все-таки 24-битный, то пример 32-битного вряд ли подойдет: там совсем другая структура.
А известно как именно внешняя функция создает битмап?

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

Добавлено: 27 Январь 2020, 15:17
Игорь Столяров
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;
      }
 }

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

Добавлено: 27 Январь 2020, 15:28
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
Вам сначала нужно ее считать и посмотреть, что из себя представляет битмап.

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

Добавлено: 27 Январь 2020, 16:09
kreator
Constantine, Вы ещё забыли про BITMAPFILEHEADER. Он записан до приведённой Вами структуры.

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

Добавлено: 27 Январь 2020, 17:11
vic7tar
Игорь Столяров писал(а): 27 Январь 2020, 9:51 Внешняя DLL формирует буфер с картинкой в обычном DIB формате (3 байта на пиксель) и возвращает её размер.
Если это продолжение борьбы с Zint, то причём тут DIB. Формируется обычный BitMap с разрядностью точек 32.
Базовыми функциями Clarion-а эту матрицу пикселей не вывести. Или вручную формировать в памяти картинку (примеры есть в Инете, но дальше формата BMP не продвинетесь) или другими способами.

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

Добавлено: 27 Январь 2020, 17:43
kreator
Что касается BMP-формата, то biBitCount=24, а на пиксель всё равно отводится 4 байта. Проверил на Corel. Т.е. надо формировать последовательность из четырёх байт. Тогда кларионовский имидж поймёт эту последовательность.

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

Добавлено: 27 Январь 2020, 18:02
vic7tar
kreator писал(а): 27 Январь 2020, 17:43 Т.е. надо формировать последовательность из четырёх байт.
Ну да, правильно, а четвертый заполнять нулём.
kreator писал(а): 27 Январь 2020, 17:43 Тогда кларионовский имидж поймёт эту последовательность.
А как он его поймёт? Вроде бы Clarion может работать с полноценными форматами, и то из файла или Blob-а. Или я заблуждаюсь?

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

Добавлено: 27 Январь 2020, 22:15
Игорь Столяров
Нет, я пас. Спасибо за разъяснения.
Задача трансформации 24-битного bitmap в 32-битный DIB с заголовком в памяти пока для меня нерешаема.
Попробую вернуться к ней позже ...

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

Добавлено: 28 Январь 2020, 8:51
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(), возможно, там как-то по-другому?

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

Добавлено: 28 Январь 2020, 9:01
Yufil
Может быть, всё-таки ClarionFreeeImage поможет? Там можно использовать готовые шаблоны, а можно отдельно библиотеку FreeImage.
Когда-то лет 15 назад выкрутился ( традиционно волшебные слова LockThread - UnlockThread).

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

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

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

Добавлено: 28 Январь 2020, 9:23
Constantine
Жаль... :-( Через GetPixel() медленно получается...

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

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

А как он его поймёт? Вроде бы Clarion может работать с полноценными форматами, и то из файла или Blob-а. Или я заблуждаюсь?
Я имел ввиду последовательность вместе с заголовком.
Не вижу проблем создать нужную последовательность из того, что выдаёт внешняя dll. Если есть возможность, лучше эту последовательность правильно настроить во внешней проге.
Повторюсь. Я манипулирую "ручными" bmp-картинками, проблем нет.

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

Добавлено: 28 Январь 2020, 11:06
Дед Пахом
vic7tar писал(а): 27 Январь 2020, 18:02 Вроде бы Clarion может работать с полноценными форматами, и то из файла или Blob-а. Или я заблуждаюсь?
  • Из файла: Prop:Text
  • Из блоба: Prop:Handle
  • Из памяти: Prop:ImageBits

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

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