Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm для Windows/Dos > FASM. Вывод картинки на экран


Автор: R71MT 31.7.2015, 11:58
Привет всем! Помогите разобраться с таким вопросом..
Пытаюсь вывести 24-разрядный BMP-рисунок в окно программы. Приложение долно работать в реальном режиме под DOS. 

Код пишу на FASM'е, но споткнулся о формат BMP-файла, в доках которого говорится, что каждый пиксель описывается тремя байтами(RGB). Я создал в фотошопе рисунок 3х3 пикселя, каждый пиксель залил по-вертикали цветами B-G-R, и открыв получившийся BMP в HEX-редакторе увидел такую картину:

Код

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   42 4D 5C 00 00 00 00 00  00 00 36 00 00 00 28 00   BM\.......6...(.
00000010   00 00 03 00 00 00 03 00  00 00 01 00 18 00 00 00   ................
00000020   00 00 26 00 00 00 12 0B  00 00 12 0B 00 00 00 00   ..&.............
00000030   00 00 00 00 00 00 FF 00  00 00 FF 00 00 00 FF 00   ......я...я...я.
00000040   00 00 FF 00 00 00 FF 00  00 00 FF 00 00 00 FF 00   ..я...я...я...я.
00000050   00 00 FF 00 00 00 FF 00  00 00 00 00               ..я...я.....



Первые 35h байт занимает заголовок, а сам рисунок начинается в адреса 36h. Размер файла лежит в слове по адресу 02h (у меня 5Сh = 92 байта). В свойствах файла так-же 92 байта. Теперь вопрос..

Если размер файла 92, а заголовок занимает 54 байта, то выходит что полезной инфы в нём 92-54=38 байт. Рисунок у меня 3х3=9 точки, каждая из которых описывается 3-мя байтами, получается 27 байт. От куда ещё 11 байт? 

Вот картинка, начиная с адреса 36h (без заголовка), ..только полезная инфа: 

Код

FF0000   00FF00   0000FF     00 00 00 
FF0000   00FF00   0000FF     00 00 00 
FF0000   00FF00   0000FF     00 00 00 00 00

Цвета RGB определились, а болото нулей в хвостах строк - непонятно что!
Дело в том, что разобравшись со-структурой BMP, мне нужно будет перекодировать его в 16-цветный рисунок и вывести на экран в видео/режиме 12h (640x480x16). C этим проблем нет: 4 бита, 3 из которых - цвета, а старший яркость. Проверка на 1, со сдвигами вправо каждого байта. 

Но как быть в самой картинкой? Или при перекодировки нужно пропускать 3 байта в хвосте? Подскажите, где я туплю..

Автор: _zorn_ 31.7.2015, 19:39
Цитата(R71MT @  31.7.2015,  18:58 Найти цитируемый пост)
а сам рисунок начинается в адреса 36h

И ты не определил что на цвет 4 байта, а не 3 ?

ЗЫ: Хз зачем 4й, может прозрачность планировали в BMP....

Автор: R71MT 31.7.2015, 20:43
_zorn_, спасибо!
Оказывается это выравнивание по-параграфу. 
Если ширина картинки не кратна 4, то оставшиеся байты забиваются нулями (от 1 до 3).
Я попробовал сделать картинку в 4х4 пикселя и нули в конце пропали:
Код

  R       G       B        R
FF0000  00FF00  0000FF  FF0000 
FF0000  00FF00  0000FF  FF0000 
FF0000  00FF00  0000FF  FF0000
FF0000  00FF00  0000FF  FF0000  0000

Теперь вожусь с перекодировкой из 24-разрядного BMP в 4-битную палитру. Вроде получается... Хотя ХЗ какой будет результат.

Автор: _zorn_ 1.8.2015, 10:36
"Для себя" пойдёт, но больше это никому не нужно  smile 

Автор: R71MT 1.8.2015, 11:39
..ну да - это чисто в целях самообразования. 
Делаю boot-cd и прицеплю туда лого.

Автор: R71MT 3.8.2015, 18:05
..подскажите, что не так в коде? 
 Вроде что-то выводит, но ни как не нужную картинку. 
 Размер картинки пока фиксированный - 64х64 пикселей. Вес - 2000h байт:
Код:

Код

use16
org 100h
jmp start

fname    db  '1.bmp',0        ; картинка
width    dw  ?                ; её ширина
heigh    dw  ?                ;    ..и высота.
buff     dw  2000h dup(0)     ; буфер для хранения картинки
wcoun    db  0                ; счётчик столбцов
hcoun    db  0                ; счётчик строк

start:
   mov   al,12h
   int   10h                  ; ставим EGA 640x480x16

;--- читаем картинку в буфер --------------------------//
   mov   ax,3d00h             ; открыть файл!
   mov   dx,fname
   int   21h
   push  ax                   ; сохраняем хэндл файла

   mov   bx,ax                ; отправляем его в BX (для чтения)
   mov   ah,3Fh               ; читать файл!
   mov   dx,buff              ; куда..,
   mov   cx,2000h             ;   и сколько
   int   21h                  ; файл в буфере!

   pop   ax                   ; закрыть файл!
   mov   bx,ax
   mov   ah,3Eh
   int   21h

;--- сохраняем инфу о картинке в переменных -----------//
   mov   ax,word[buff+12h]    ; ширина
   mov   [width],ax
   mov   ax,word[buff+16h]    ; высота
   mov   [heigh],ax

;--- выводим её на экран ------------------------------//
   xor   bx,bx                ; страница(0)
   mov   dx,70                ; начальная позиция строки
   mov   cx,10                ;    ..и столбца.
   mov   si,36h               ; пропускаем заголовок в BMP
next:
   call  bitmap               ; зовём (fn) конвертирования 
   mov   ah,0Ch               ; функция вывода точки на экран
   int   10h
   inc   cx                   ; следующая точка в строке
   inc   byte[wcoun]          ; увеличим счётчик столбцов
   cmp   [wcoun],64           ; все столбцы вывели? (ширина картинки)
   jnz   next                 ; если нет - мотаем цикл.

   dec   dx                   ; одну строку вывели! перемещаемся выше
   mov   cx,10                ; сброс позиции столбца
   mov   [wcoun],0            ;    ..и счётчика столбцов 
   inc   byte[hcoun]          ; увеличим счётчик строк
   cmp   [hcoun],64           ; все строки вывели? (высота картинки)
   jnz   next                 ; если нет - мотаем цикл.

exit:
   xor   ax,ax
   int   16h
   mov   ax,4C00h             ; на выход!
   int   21h

;--- главная процедура ------------------------------------------//
; конвертирует - 24-разрядный BMP в 4-битную палитру.
; результат сохраняется в регистре al.
bitmap:
   xor   al,al                ; здесь будет результат  
   mov   ah,byte[buff+si]     ; берём цвет(B). читаем сколько синего
   shr   ah,7                 ; сдвигаем вправо на 7 разрядов
   and   ah,0001b             ; бит(0) маски отвечает за синий цвет
   or    al,ah                ; если имеется, то выставляем в маске синий

   inc   si                   ; берём цвет(G) (в BMP цвета идут BGR)
   mov   ah,byte[buff+si]     ; тоже/самое, только со сдвигом на 1 левее
   shr   ah,6                 ; сдвигаем вправо на 6 разрядов
   and   ah,0010b             ; бит(1) маски - зелёный цвет
   or    al,ah                ; выставляем зеленый

   inc   si                   ; берём цвет(R). читаем кол-во красного
   mov   ah,byte[buff+si]     ; всё/тоже,
   shr   ah,5                 ;   ..только со-сдвигом вправо на 5
   and   ah,0100b             ; бит(2) маски - красный
   or    al,ah                ; имеется? выставляем красный
   inc   si
   or    al,1000b             ; бит(3) маски - интенсивность.
ret

Автор: R71MT 4.8.2015, 16:12
Сорри! Всё оказывается работает.. Просто я пытался вывести 8-разрядный рисунок BMP, а нужен 24-разрядный

Автор: _zorn_ 5.8.2015, 14:56
У 8 разрядного индекса цвета ) Типа как в гифе.

Автор: R71MT 5.8.2015, 21:23
..в итоге, написал  отдельно перекодировщик, и подключаю уже 16-цветный рисунок в исходник инструкцией "FILE".. Всё работает...

Автор: _zorn_ 5.8.2015, 21:38
А я когда то звёзды рисовал мигающие на паскале поверх планеты, сконверченной из интернета скачаной картинки в 16 бит )
Ностальжи )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)