Координаты в BMP-файле

Тема в разделе "WASM.GRAPHICS", создана пользователем Entropy, 2 авг 2024.

  1. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    233
    Привет,у меня есть BMP файл размером 100x100 пикселей с глубиной цвета 24 бит,мне нужно обработать пиксели на позиции X = 56 Y = 63,так вот как преобразовать координаты X,Y в файловое смещение,для того что бы через SetFilePointer() выставить позицию и начать обработку пикселей.

    bmp файл делаю с помощью FASM
    Код (ASM):
    1.  
    2. format binary as 'bmp'
    3.  
    4.  
    5. bftype db 'B','M'
    6. bfSize dd 30054
    7. res1 dw 0
    8. res2 dw 0
    9. bfoffbits dd 14+40
    10. biSize dd 40
    11. biWidth dd 100
    12. biHeight dd 100
    13. biPlanes dw 1
    14. biBitCount dw 24
    15. biCompression dd  0
    16. biSizeImage dd 30000
    17. biXPixelsPerMeter dd 0
    18. biYPixelsPerMeter dd 0
    19. biClrUsed dd 0
    20. biClrImportant dd 0
    21.  
    22. pixels db 30000 dup(0)
    23.  
     
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    4.172
    Entropy,
    1. 100(длина)х100(ширина)х3(цвет)=30000 байта «чистый» рисунок
    2. 54 заголовок + перевернутая картинка
    3. в строке пиксели идут слева направо, строки идут снизу вверх
    4. длина строки должна быть кратна 4, поэтому к строке добавляют от 1 до 3 «пустых» байт
    координаты
    пиксела
    линейный адрес
    XY
    99​
    99​
    300×(99-99)+3×(99-99)+54=54 ― первые 3 байта после заголовка
    99​
    98​
    300×(99-98)+3×(99-99)+54=354
    99​
    63​
    300×(99-63)+3×(99-99)+54=10854
    56​
    63​
    300×(99-63)+3×(99-56)+54=10983
    0​
    0​
    самые последние 3 байта в bmp-файле, 303×99+54=30054-3=30051
     
    mantissa нравится это.
  3. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    2.085
    Код (ASM):
    1. BMP_WIDTH    = 100
    2. BMP_HEIGHT    = 100
    3.  
    4.                 db 'BM'
    5. bfSize            dd eof - $$
    6. bfReserved1        dw 0
    7. bfReserved2        dw 0
    8. bfOffBits        dd 54
    9. biSize            dd 40
    10. biWidth            dd BMP_WIDTH
    11. biHeight        dd BMP_HEIGHT
    12. biPlanes        dw 1
    13. biBitCount        dw 24
    14. biCompression    dd 0
    15. biSizeImage        dd eof - $$ - 54
    16. biXPelsPerMeter    dd 0
    17. biYPelsPerMeter    dd 0
    18. biClrUsed        dd 0
    19. biClrImportant    dd 0
    20.  
    21. repeat BMP_HEIGHT
    22.     row = (% - 1)
    23.     repeat BMP_WIDTH
    24.         if row = 0
    25.             db 0,0,((% - 1)*2)and 0xFF
    26.         else
    27.             db 0xFF,0xFF,0xFF
    28.         end if
    29.         rb (BMP_HEIGHT*3)-(((BMP_HEIGHT*3)+(4-1))and not (4-1))
    30.     end repeat
    31. end repeat
    32. eof:
    Кодируется слева направо, снизу вверх, один пиксель - 3 байта, длина строки выравнивается до величины, кратной 4.
    Удачно совпало, что 100*3=300 и 300 кратно 4.
    --- Сообщение объединено, 2 авг 2024 ---
    И по оси Х слева направо:
    Код (Text):
    1. pixelOffset=54+(((height*3)+3)and not 3)*(height-Y) + X*3
    --- Сообщение объединено, 2 авг 2024 ---
    Даже вот так, потому что строки нумеруются с 1:
    Код (ASM):
    1. BMP_WIDTH    = 100
    2. BMP_HEIGHT    = 100
    3. X = 54
    4. Y = 63
    5.  
    6.                 db 'BM'
    7. bfSize            dd eof - $$
    8. bfReserved1        dw 0
    9. bfReserved2        dw 0
    10. bfOffBits        dd 54
    11. biSize            dd 40
    12. biWidth            dd BMP_WIDTH
    13. biHeight        dd BMP_HEIGHT
    14. biPlanes        dw 1
    15. biBitCount        dw 24
    16. biCompression    dd 0
    17. biSizeImage        dd eof - $$ - 54
    18. biXPelsPerMeter    dd 0
    19. biYPelsPerMeter    dd 0
    20. biClrUsed        dd 0
    21. biClrImportant    dd 0
    22.  
    23. repeat BMP_HEIGHT
    24.     row = (% - 1)
    25.     repeat BMP_WIDTH
    26.         if row = 0
    27.             db 0,0,((% - 1)*2)and 0xFF
    28.         else
    29.             db 0xFF,0xFF,0xFF
    30.         end if
    31.         rb (BMP_HEIGHT*3)-(((BMP_HEIGHT*3)+(4-1))and not (4-1))
    32.     end repeat
    33. end repeat
    34. eof:
    35.  
    36. pixelOffset=54+(((BMP_WIDTH*3)+3)and not 3)*(BMP_HEIGHT-1-Y) + X*3
    37. store byte 0 at $$ + pixelOffset + 0
    38. store byte 0 at $$ + pixelOffset + 1
    39. store byte 255 at $$ + pixelOffset + 2
     
    Mikl___ нравится это.
  4. vitokop

    vitokop Member

    Публикаций:
    0
    Регистрация:
    20 май 2006
    Сообщения:
    49
    ...точнее так:
    Заголовок = TBitmapFileHeader + TBitmapInfoHeader = 14 + 40 = 54
     
  5. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    233
    то есть если бы параметр BMP_WIDTH = 155 * 3 = 465 ,465 mod 4 = 1,тогда (465 + 3) mod 4 = 0 я правильно понял ?
     
  6. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    896
    Entropy, ширина_в_байтах = (ширина_в_пикселях * бит_на_пиксель + 31) / 8 AND -4.
     
  7. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    233
    Mikl___, если считать по тем формулам которые ты мне предложил,тогда X= 50 Y = 50 300×(99-50)+3×(99-50)+54=720501 (720501 - 30054 = 690447) получается гораздо больше чем общий размер файла,а вот как я думаю 300×(99-50)+(99-50)=14749,без учёта размера заголовка, двигаться начиная с 30000 байта,с самого конца файла (30000 - 14749 = 15251 адрес пикселя по X,Y)
    --- Сообщение объединено, 9 авг 2024 ---
    Thetrik, точнее так, ширина_картинки * байт_на_пиксель (100*3 = 300)
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    4.172
    Entropy, давай пересчитаем для координат X=50 Y=50
    3×100×(99-50)+3×(99-50)+54=300×49+3×49+54=303×49+54=14847+54=14901 с учетом размера заголовка. Откуда взялось 720501?
    тогда почему 14749, а не 720501-54=720447‬? и в расчете должно быть (99-50)
     
  9. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    233
    Mikl___,
    для X = 23 Y = 41 300×(99-41)+3×(99-23)+54=?
    1. 300 × (99-41) = 300 × 58 = 17400
    2. 17400 + 3×(99-23) = 17400 + 3×76 = 17400 + 228 = 17628
    3. 17628 + 54 = 17682
    верно думаю ?
    координаты X=0 Y=0 будут располагаться с 30053 байта
    Код (ASM):
    1. format binary as 'bmp'
    2.  
    3. bftype db 'B','M'
    4. bfSize dd 30054
    5. res1 dw 0
    6. res2 dw 0
    7. bfoffbits dd 14+40
    8. biSize dd 40
    9. biWidth dd 100
    10. biHeight dd 100
    11. biPlanes dw 1
    12. biBitCount dw 24
    13. biCompression dd  0
    14. biSizeImage dd 30000
    15. biXPixelsPerMeter dd 0
    16. biYPixelsPerMeter dd 0
    17. biClrUsed dd 0
    18. biClrImportant dd 0
    19.  
    20.  
    21. pixels db 30000 dup(0)
    22.  
    23. pix1 = 30051
    24. pix2 = 30052
    25. pix3 = 30053
    26.  
    27. repeat 75
    28.  
    29. store 0 at pix1
    30. store 0 at pix2
    31. store 255 at pix3
    32.  
    33. pix1 = pix1 - 3
    34. pix2 = pix2 - 3
    35. pix3 = pix3 - 3
    36.  
    37. end repeat
     
  10. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    4.172
    Entropy,
    теоретически всё верно, пора уже знания о BMP и на практике проверять ;)

    вывод картинок на экран (bmp, jpg, png)

     
  11. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    233
    А на практике,вот что получилось,открываю созданный bmp файл hex редактором ,выставляю смещение 17682 от начала файла,и записываю туда байты 0x00ff00,0x0000ff
     

    Вложения:

    • bmp_asm.zip
      Размер файла:
      29,5 КБ
      Просмотров:
      719
  12. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    4.172
    Entropy,
    это то, что ты хотел получить? Тебя это устраивает? Или следующий шаг это ― графический редактор для bmp-файлов?
     
  13. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    233
    нет, использование ассемблерных инструкций для обработки графики
    Я тут ещё подумал насчёт координат, если мы хотим двигаться по оси Y тогда нужно считать так 300×(Y)+54, например Y = 5 тогда линейный адрес такой 300×5+54 = 1554, собственно это значение можно указать в функции SetFilePointer(), тогда если двигаться по оси X 300+(X×3)+54, на практике, открываю файл hex редактором выставляю смещение 1554 и записываю туда байты 0xFF_FF_FF,затем открываю файл с помощью редактора Paint,смотрю в левом нижнем углу появился белый пиксель.
     
  14. CaptainObvious

    CaptainObvious Member

    Публикаций:
    1
    Регистрация:
    18 янв 2024
    Сообщения:
    95
    Оставьте их, они — слепые вожди слепых; а если слепой ведёт слепого, то оба упадут в яму
    (Евангелие от Матфея 15 стих 14)​
     
  15. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    233
    я попытался использовать ассемблерные инструкции для обработки графики
    Код (ASM):
    1.  
    2. .686p
    3. option casemap:none
    4. .model flat,stdcall
    5. .XMM
    6.  
    7.  
    8.  
    9.  
    10. public start
    11.  
    12. include windows.inc
    13. include kernel32.inc
    14. include msvcrt.inc
    15.  
    16. includelib papak\wlib\kernel32.lib
    17. includelib papak\wlib\msvcrt.lib
    18.  
    19. .data
    20.  
    21.  
    22.  
    23. BMPIMAGE STRUCT
    24.   bfType        WORD      ?
    25.   bfSize        DWORD      ?
    26.   bfReserved1   WORD      ?
    27.   bfReserved2   WORD      ?
    28.   bfOffBits     DWORD      ?
    29.   biSize            DWORD      ?
    30.   biWidth           DWORD      ?
    31.   biHeight          DWORD      ?
    32.   biPlanes          WORD       ?
    33.   biBitCount        WORD       ?
    34.   biCompression     DWORD      ?
    35.   biSizeImage       DWORD      ?
    36.   biXPelsPerMeter   DWORD      ?
    37.   biYPelsPerMeter   DWORD      ?
    38.   biClrUsed         DWORD      ?
    39.   biClrImportant    DWORD      ?
    40. BMPIMAGE ENDS
    41.  
    42. infohead BMPIMAGE <>
    43.  
    44.  
    45. file_name db 'deathcore.bmp'
    46.  
    47. info_write dword ?
    48.  
    49. hand dword ?
    50.  
    51. pixar db 500 dup (?)
    52.  
    53.  
    54.  
    55.  
    56.  
    57. .code
    58.  
    59.  
    60. start:
    61.  
    62.  
    63. mov [infohead.bfType],'MB'
    64. mov [infohead.bfSize],30054
    65.  
    66. mov [infohead.bfReserved1],0
    67. mov [infohead.bfReserved2],0
    68. mov [infohead.bfOffBits],54
    69.  
    70.  
    71. mov [infohead.biSize],40
    72. mov [infohead.biWidth],100
    73. mov [infohead.biHeight],100
    74.  
    75. mov [infohead.biPlanes],1
    76. mov [infohead.biBitCount],24
    77. mov [infohead.biCompression],0
    78.  
    79.  
    80. mov [infohead.biSizeImage],30000
    81. mov [infohead.biXPelsPerMeter],0
    82. mov [infohead.biYPelsPerMeter],0
    83.  
    84.  
    85. mov [infohead.biClrUsed],0
    86. mov [infohead.biClrImportant],0
    87.  
    88. invoke CreateFileA,addr file_name,GENERIC_ALL,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
    89.  
    90. mov [hand],eax
    91.  
    92. mov ebx,eax
    93.  
    94.  
    95. invoke WriteFile,ebx,addr infohead,sizeof BMPIMAGE,addr info_write,0
    96.  
    97. mov ebx,[hand]
    98.  
    99. invoke SetFilePointer,ebx,30054,0,FILE_BEGIN
    100.  
    101. mov ebx,[hand]
    102.  
    103. invoke SetEndOfFile,ebx
    104.  
    105.  
    106. xor edx,edx
    107.  
    108.  
    109. mov eax,offset pixar
    110.  
    111. mov ecx,0ffffffh
    112. mov ebx,030303h
    113.  
    114. movd xmm0,ecx
    115. movd xmm1,ebx
    116.  
    117.  
    118. bits_drop:
    119. mov ebx,ecx
    120.  
    121. mov  [eax],bl
    122. shr ebx,8
    123. mov  [eax+1],bl
    124. shr ebx,8
    125. mov  [eax+2],bl
    126.  
    127. psubb xmm0,xmm1
    128.  
    129. movd ecx,xmm0
    130.  
    131.  
    132. cmp ecx,0edededh
    133. je setup
    134.  
    135. after_setup:
    136. add eax,3
    137.  
    138. inc edx
    139. cmp edx,500
    140. je write_to_file
    141.  
    142. jmp bits_drop
    143.  
    144.  
    145. setup:
    146.  
    147. mov ecx,0ffffffh
    148. movd xmm0,ecx
    149.  
    150. jmp after_setup
    151.  
    152.  
    153. write_to_file:
    154.  
    155. mov ebx,[hand]
    156.  
    157. invoke SetFilePointer,ebx,15000,0,FILE_BEGIN
    158.  
    159. mov ebx,[hand]
    160. lea eax,[pixar]
    161. invoke WriteFile,ebx,eax,500,addr info_write,0
    162.  
    163. mov ebx,[hand]
    164. invoke CloseHandle,ebx
    165.  
    166.  
    167.  
    168. @@:
    169. push 5000
    170. call Sleep
    171.  
    172. push 0
    173. call ExitProcess
    174.  
    175. end
    176.