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

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

  1. Entropy

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    Привет,у меня есть 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
    Сообщения:
    3.792
    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
    Сообщения:
    1.995
    Код (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
    Сообщения:
    48
    ...точнее так:
    Заголовок = TBitmapFileHeader + TBitmapInfoHeader = 14 + 40 = 54
     
  5. Entropy

    Entropy Member

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

    Thetrik UA6527P

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

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    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
    Сообщения:
    3.792
    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
    Сообщения:
    185
    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
    Сообщения:
    3.792
    Entropy,
    теоретически всё верно, пора уже знания о BMP и на практике проверять ;)

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

     
  11. Entropy

    Entropy Member

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

    Вложения:

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

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

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

    Entropy Member

    Публикаций:
    0
    Регистрация:
    23 авг 2020
    Сообщения:
    185
    нет, использование ассемблерных инструкций для обработки графики
    Я тут ещё подумал насчёт координат, если мы хотим двигаться по оси 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
    Сообщения:
    87
    Оставьте их, они — слепые вожди слепых; а если слепой ведёт слепого, то оба упадут в яму
    (Евангелие от Матфея 15 стих 14)​