Привет,у меня есть BMP файл размером 100x100 пикселей с глубиной цвета 24 бит,мне нужно обработать пиксели на позиции X = 56 Y = 63,так вот как преобразовать координаты X,Y в файловое смещение,для того что бы через SetFilePointer() выставить позицию и начать обработку пикселей. bmp файл делаю с помощью FASM Код (ASM): format binary as 'bmp' bftype db 'B','M' bfSize dd 30054 res1 dw 0 res2 dw 0 bfoffbits dd 14+40 biSize dd 40 biWidth dd 100 biHeight dd 100 biPlanes dw 1 biBitCount dw 24 biCompression dd 0 biSizeImage dd 30000 biXPixelsPerMeter dd 0 biYPixelsPerMeter dd 0 biClrUsed dd 0 biClrImportant dd 0 pixels db 30000 dup(0)
Entropy, 100(длина)х100(ширина)х3(цвет)=30000 байта «чистый» рисунок 54 заголовок + перевернутая картинка в строке пиксели идут слева направо, строки идут снизу вверх длина строки должна быть кратна 4, поэтому к строке добавляют от 1 до 3 «пустых» байт координаты пикселалинейный адресXY9999300×(99-99)+3×(99-99)+54=54 ― первые 3 байта после заголовка9998300×(99-98)+3×(99-99)+54=3549963300×(99-63)+3×(99-99)+54=108545663300×(99-63)+3×(99-56)+54=1098300самые последние 3 байта в bmp-файле, 303×99+54=30054-3=30051
Код (ASM): BMP_WIDTH = 100 BMP_HEIGHT = 100 db 'BM' bfSize dd eof - $$ bfReserved1 dw 0 bfReserved2 dw 0 bfOffBits dd 54 biSize dd 40 biWidth dd BMP_WIDTH biHeight dd BMP_HEIGHT biPlanes dw 1 biBitCount dw 24 biCompression dd 0 biSizeImage dd eof - $$ - 54 biXPelsPerMeter dd 0 biYPelsPerMeter dd 0 biClrUsed dd 0 biClrImportant dd 0 repeat BMP_HEIGHT row = (% - 1) repeat BMP_WIDTH if row = 0 db 0,0,((% - 1)*2)and 0xFF else db 0xFF,0xFF,0xFF end if rb (BMP_HEIGHT*3)-(((BMP_HEIGHT*3)+(4-1))and not (4-1)) end repeat end repeat eof: Кодируется слева направо, снизу вверх, один пиксель - 3 байта, длина строки выравнивается до величины, кратной 4. Удачно совпало, что 100*3=300 и 300 кратно 4. --- Сообщение объединено, 2 авг 2024 --- И по оси Х слева направо: Код (Text): pixelOffset=54+(((height*3)+3)and not 3)*(height-Y) + X*3 --- Сообщение объединено, 2 авг 2024 --- Даже вот так, потому что строки нумеруются с 1: Код (ASM): BMP_WIDTH = 100 BMP_HEIGHT = 100 X = 54 Y = 63 db 'BM' bfSize dd eof - $$ bfReserved1 dw 0 bfReserved2 dw 0 bfOffBits dd 54 biSize dd 40 biWidth dd BMP_WIDTH biHeight dd BMP_HEIGHT biPlanes dw 1 biBitCount dw 24 biCompression dd 0 biSizeImage dd eof - $$ - 54 biXPelsPerMeter dd 0 biYPelsPerMeter dd 0 biClrUsed dd 0 biClrImportant dd 0 repeat BMP_HEIGHT row = (% - 1) repeat BMP_WIDTH if row = 0 db 0,0,((% - 1)*2)and 0xFF else db 0xFF,0xFF,0xFF end if rb (BMP_HEIGHT*3)-(((BMP_HEIGHT*3)+(4-1))and not (4-1)) end repeat end repeat eof: pixelOffset=54+(((BMP_WIDTH*3)+3)and not 3)*(BMP_HEIGHT-1-Y) + X*3 store byte 0 at $$ + pixelOffset + 0 store byte 0 at $$ + pixelOffset + 1 store byte 255 at $$ + pixelOffset + 2
то есть если бы параметр BMP_WIDTH = 155 * 3 = 465 ,465 mod 4 = 1,тогда (465 + 3) mod 4 = 0 я правильно понял ?
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)
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? и в расчете должно быть 3×(99-50)
Mikl___, для X = 23 Y = 41 300×(99-41)+3×(99-23)+54=? 300 × (99-41) = 300 × 58 = 17400 17400 + 3×(99-23) = 17400 + 3×76 = 17400 + 228 = 17628 17628 + 54 = 17682 верно думаю ? координаты X=0 Y=0 будут располагаться с 30053 байта Код (ASM): format binary as 'bmp' bftype db 'B','M' bfSize dd 30054 res1 dw 0 res2 dw 0 bfoffbits dd 14+40 biSize dd 40 biWidth dd 100 biHeight dd 100 biPlanes dw 1 biBitCount dw 24 biCompression dd 0 biSizeImage dd 30000 biXPixelsPerMeter dd 0 biYPixelsPerMeter dd 0 biClrUsed dd 0 biClrImportant dd 0 pixels db 30000 dup(0) pix1 = 30051 pix2 = 30052 pix3 = 30053 repeat 75 store 0 at pix1 store 0 at pix2 store 255 at pix3 pix1 = pix1 - 3 pix2 = pix2 - 3 pix3 = pix3 - 3 end repeat
Entropy, теоретически всё верно, пора уже знания о BMP и на практике проверять вывод картинок на экран (bmp, jpg, png) Глава двадцать восьмая (часть первая). Братец Кролик выводит картинки на экран LoadBitmap + CreateCompatibleDC + SelectObject + BitBlt Глава двадцать восьмая (часть вторая). Братец Кролик продолжает выводить картинки на экран LoadImage + CreateCompatibleDC + StretchBlt LoadImage + CreatePatternBrush + PatBlt GDI+: GdipCreateBitmapFromFile + GdipCreateHBITMAPFromBitmap + SendMessage(STM_SETIMAGE) LoadImage + CreatePatternBrush + wc.hbrBackground OLE
А на практике,вот что получилось,открываю созданный bmp файл hex редактором ,выставляю смещение 17682 от начала файла,и записываю туда байты 0x00ff00,0x0000ff
Entropy, это то, что ты хотел получить? Тебя это устраивает? Или следующий шаг это ― графический редактор для bmp-файлов?
нет, использование ассемблерных инструкций для обработки графики Я тут ещё подумал насчёт координат, если мы хотим двигаться по оси Y тогда нужно считать так 300×(Y)+54, например Y = 5 тогда линейный адрес такой 300×5+54 = 1554, собственно это значение можно указать в функции SetFilePointer(), тогда если двигаться по оси X 300+(X×3)+54, на практике, открываю файл hex редактором выставляю смещение 1554 и записываю туда байты 0xFF_FF_FF,затем открываю файл с помощью редактора Paint,смотрю в левом нижнем углу появился белый пиксель.
Оставьте их, они — слепые вожди слепых; а если слепой ведёт слепого, то оба упадут в яму (Евангелие от Матфея 15 стих 14)