Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2003.09.15;
Скачать: [xml.tar.bz2];

Вниз

Кто знает формат .bmp, помогите.   Найти похожие ветки 

 
выарп   (2003-08-23 19:49) [0]

Хочу отобразить .bmp файл на форме (ни какой практической цели этим не преследую).
Но вот не получается. Цвета не всегда (не для всякой бэ-эм-пэшки) правильно отображаются. Объясните, пожалуйста, что не так.

program Project1;
uses
Forms,
Unit1 in "Unit1.pas" {Form1};
{$R *.RES}
begin
assign(bmpfile, "file.bmp");
reset(bmpfile,1);
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
Close(bmpfile);
end.
//----------------
unit Unit1;
...
var
...
bmpfile: file;
buff: array[1..3072] of char;
numread, i: integer;
bmpwidth, bmpheight, x, y: integer;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
blockread(bmpfile, buff, sizeof(buff));
bmpwidth:=ord(buff[19])+ord(buff[20])*256+ord(buff[21])*256*256+ord(bu ff[22])*256*256*256;
bmpheight:=ord(buff[23])+ord(buff[24])*256+ord(buff[25])*256*256+ord(b uff[26])*256*256*256;
seek(bmpfile, 54);
x:=1; y:=bmpheight; i:=0;
repeat
blockread(bmpfile, buff, sizeof(buff), numread);
repeat
canvas.Pixels[x,y]:=ord(buff[1+i*3])+ord(buff[2+i*3])*256+ord(buff[3+i *3])*256*256;
inc(i);
inc(x);
if x>bmpwidth then begin x:=1; inc(y,-1) end;
until i=1024;
i:=0;
until numread=0;
end;


 
shark   (2003-08-23 19:58) [1]

Так ты просто в TBitmap загрузи .


 
выарп   (2003-08-23 20:12) [2]

Я просто хочу понять, что не так?


 
выарп   (2003-08-23 20:41) [3]

Забыл сказать, что бэ-эм-пэшки 24-битные.


 
Palladin   (2003-08-23 22:41) [4]

хм, это интересно...
а в каком смысле "не совсем так"? Совсем не так или похоже?

в этом случае можно провести экспиримент, загрузить BMP где цвета не так в TBitmap и прочитать значение палитры, после - сравнить с той которую читаешь ты и посмотреть разницу, только так можно понять что не так :)


 
wl   (2003-08-24 01:57) [5]

Задай свой вопрос не в "Потрепаться" а в "WinAPI", плиз(спешиал фо ми)


 
DrPass   (2003-08-24 12:28) [6]

Просто не зря данные в bmp-файле начинаются не сначала. Первые блоки - это информация о палитре. Почитать бы доку кое-кому сперва


 
выарп   (2003-08-24 16:35) [7]

>DrPass © (24.08.03 12:28) [6]
>Просто не зря данные в bmp-файле начинаются не сначала. Первые
>блоки - это информация о палитре. Почитать бы доку кое-кому сперва

Я-то как раз читал:
"The color table is not present
for bitmaps with 24 color bits because each pixel is represented by 24-bit
red-green-blue (RGB) values in the actual bitmap data area."


 
выарп   (2003-08-24 16:40) [8]

>DrPass © (24.08.03 12:28) [6]
>Просто не зря данные в bmp-файле начинаются не сначала. Первые
>блоки - это информация о палитре. Почитать бы доку кое-кому сперва

Ты бы лучше мой код прочитал и сказал, что не так?


 
Ketmar   (2003-08-24 17:00) [9]

всё не так.


 
выарп   (2003-08-24 17:43) [10]

>Ketmar © (24.08.03 17:00) [9]
>всё не так.

Намекни на самые главные ошибки.


 
Ketmar   (2003-08-24 18:33) [11]

начиная с "var" и дальше -- всё сплошная ошибка. за такой код убивают. из шотгана. в живот.


 
Palladin   (2003-08-24 18:38) [12]

лучше в голову


 
выарп   (2003-08-24 19:17) [13]

Насчет кода - так я ведь не сочинение писал, а просто хотел понять формат .bmp (цель знаете ли другая).
Спасибо, что помогли; действительно, МАСТЕРА.

з.ы. вы случайно не в олимпийской сборной по стрельбе?


 
otido   (2003-08-24 19:19) [14]

честно скажу, не знаю ответа на вопрос, но по-моему слишком жестковато относятся... Вай?


 
Ketmar   (2003-08-24 19:32) [15]

>#12
в голову -- это сразу. а в живот -- долго и мучительно. шоб знал, как оно.

>#13
хоть трижды "не сочинение". ты дома тоже мимо сортира ходишь, потому что "всё равно никто не видит"?

>#14
сказали же: за "код".


 
выарп   (2003-08-24 19:40) [16]

>Ketmar © (24.08.03 19:32) [15]
>#13
>хоть трижды "не сочинение". ты дома тоже мимо сортира ходишь,
>потому что "всё равно никто не видит"?

Убедил. Покажи, как надо. А потом я пойду искать шотган.


 
otido   (2003-08-24 19:42) [17]

... и сам застрелюсь, да?))


 
выарп   (2003-08-24 19:46) [18]

>... и сам застрелюсь, да?))

Сначала по коду Ketmar`а посмотрю, чей живот действительно его достоин.


 
hhhjjjkkk   (2003-08-24 19:54) [19]

TBitmap.LoadFromFile


 
выарп   (2003-08-24 20:01) [20]

>hhhjjjkkk (24.08.03 19:54) [19]
>TBitmap.LoadFromFile

Ну и что? Ты понял формат .bmp? Или мне объяснил этим?


 
wicked   (2003-08-24 20:08) [21]

2 выарп
млин.... для начала почитай в мсдн про BITMAPFILEHEADER, BITMAPINFO, BITMAPINFOHEADER... тогда причеши свой код, а потом мы увидим, будут ли еще у тебя вопросы....


 
dkjfhgjhfkj   (2003-08-24 20:12) [22]

procedure TFastDIB.LoadFromFile(FileName:string);
var
i: DWord;
Buffer: Pointer;
bmInfo: TBMInfo;
hFile: Windows.HFILE;
fBits,xSize,fSize: DWord;
begin
hFile:=CreateFile(PChar(FileName),GENERIC_READ,FILE_SHARE_READ,nil,OPE N_EXISTING,0,0);
fSize:=GetFileSize(hFile,nil);
xSize:=fSize;
if xSize>1078 then xSize:=1078;
GetMem(Buffer,1078);
ReadFile(hFile,Buffer^,xSize,i,nil);
fBits:=LoadHeader(Buffer,bmInfo);
SetSizeIndirect(bmInfo);
SetFilePointer(hFile,fBits-xSize,nil,FILE_CURRENT);
if(bmInfo.Header.Compression=1)or(bmInfo.Header.Compression=2)then xSize:=PDWord(Integer(Buffer)+2)^-fBits else
if fSize-fBits > Size then xSize:=Size else xSize:=fSize-fBits;
if(bmInfo.Header.Compression=0)or(bmInfo.Header.Compression=3)then
ReadFile(hFile,Bits^,xSize,i,nil)else
begin
ReAllocMem(Buffer,xSize);
ReadFile(hFile,Buffer^,xSize,i,nil);
if bmInfo.Header.Compression=1 then DecodeRLE8(Self,Buffer) else DecodeRLE4(Self,Buffer);
end;
CloseHandle(hFile);
FreeMem(Buffer);
end;

function LoadHeader(Data:Pointer;var bmInfo:TBMInfo):Integer;
var
i: Integer;
begin
if PDWord(Ptr(Integer(Data)+14))^=40 then
Move(Ptr(Integer(Data)+14)^,bmInfo,SizeOf(bmInfo))
else if PDWord(Ptr(Integer(Data)+14))^=12 then
with PBitmapCoreInfo(Ptr(Integer(Data)+14))^ do
begin
FillChar(bmInfo,SizeOf(bmInfo),0);
bmInfo.Header.Width:=bmciHeader.bcWidth;
bmInfo.Header.Height:=bmciHeader.bcHeight;
bmInfo.Header.BitCount:=bmciHeader.bcBitCount;
if bmciHeader.bcBitCount<=8 then
for i:=0 to (1 shl bmciHeader.bcBitCount)-1 do
bmInfo.Colors[i]:=PFColorA(@bmciColors[i])^;
end;
Result:=PDWord(Ptr(Integer(Data)+10))^;
end;


 
выарп   (2003-08-24 20:19) [23]

>wicked © (24.08.03 20:08) [21]
Читал. Хочешь я тебе каждый байт заговка 24 bit .bmp объясню.

>dkjfhgjhfkj (24.08.03 20:12) [22]
Читаю...


 
wicked   (2003-08-24 20:35) [24]

2 выарп
плохо читал....
гляди пример на Билдере:

TMemoryStream * ms = new TMemoryStream();
ms->LoadFromFile("<my bmp file>");
ms->Position = 0;
LPBITMAPFILEHEADER bfh = (LPBITMAPFILEHEADER) ms->Memory;
LPBITMAPINFO bi = (LPBITMAPINFO)((LPBYTE)ms->Memory + sizeof(BITMAPFILEHEADER));
StretchDIBits(Handle, 0, 0, Width, Height,
0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
((LPBYTE)ms->Memory + bfh->bfOffBits), bi, DIB_RGB_COLORS, SRCCOPY);
delete ms;


переведи его на паскаль, попробуй.... тогда спрашивай...

ЗЫ минусом данного кода есть то, что он не читает полуосевый .bmp... но кто сейчас про это вспомнит?... ;)


 
wicked   (2003-08-24 20:44) [25]

сори...
вот это:

> StretchDIBits(Handle, 0, 0, Width, Height,
> 0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
> ((LPBYTE)ms->Memory + bfh->bfOffBits), bi, DIB_RGB_COLORS,
> SRCCOPY);

надо читать как

StretchDIBits(Handle, 0, 0, ClientWidth, ClientHeight,
0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
((LPBYTE)ms->Memory + bfh->bfOffBits), bi, DIB_RGB_COLORS,
SRCCOPY);

;)


 
cyborg   (2003-08-24 22:17) [26]


//bfType WORD Содержит ASCII-коды символов «BM»
//bfReserved1 WORD Всегда равен 0
//bfReserved2 WORD Всегда равен 0
//bfOffBits DWORD Смещение в байтах от начала файла до графических данных
PBitmapFileHeader = ^TBitmapFileHeader;
TBitmapFileHeader = packed record
bfType: Word;
bfSize: DWORD;
bfReserved1: Word;
bfReserved2: Word;
bfOffBits: DWORD;
end;

//biSize DWORD Размер данной структуры в байтах
//biWidth DWORD Ширина растра в пикселях
//biHeight DWORD Высота растра в пикселях
//biPlanes WORD Всегда равен 1
//biBitCount WORD Количество битов на пиксель
//biCompression DWORD Тип сжатия: 0 = отсутствует, 1 = RLE-8, 2 = RLE-4
//biSizeImage DWORD Размер растра в байтах
//biXPelsPerMeter DWORD Количество пикселей на метр по горизонтали
//biYPelsPerMeter DWORD Количество пикселей на метр по вертикали
//biClrUsed DWORD Количество использованных цветов
//biClrImportant DWORD Количество значащих цветов
PBitmapInfoHeader = ^TBitmapInfoHeader;
TBitmapInfoHeader = packed record
biSize: DWORD;
biWidth: Longint;
biHeight: Longint;
biPlanes: Word;
biBitCount: Word;
biCompression: DWORD;
biSizeImage: DWORD;
biXPelsPerMeter: Longint;
biYPelsPerMeter: Longint;
biClrUsed: DWORD;
biClrImportant: DWORD;
end;

tagRGBQUAD = packed record
rgbBlue: Byte;
rgbGreen: Byte;
rgbRed: Byte;
rgbReserved: Byte;
end;

PBitmapInfo = ^TBitmapInfo;
TBitmapInfo = packed record
bmiHeader: TBitmapInfoHeader;
bmiColors: array[0..0] of TRGBQuad;
end;


 
выарп   (2003-08-25 10:47) [27]

>cyborg © (24.08.03 22:17) [26]
Спасибо. Но я как бы это знаю. Я хотел было это же wicked`у писать.
Только вот беру я два .bmp файла с совершенно одинаковыми заголовками, один из них отображается корректно, а другой нет.
Может я действительно даун?
В своей программе я сначала считываю из .bmp первые 3072 байта в массив buff (по-любому весь заголовок войдет:)
blockread(bmpfile, buff, sizeof(buff));
Первые два байта меня (пока) не интересуют, я и так знаю, что это bmp. Следующие 4 байта (размер файла) мне тоже по барабану. Пропускаем 4 резервных байта.
Оба файла брались с заголовками в 54 байта, поэтому следующие 8 байтов мне тоже не интересны.
Далее, я читаю размеры картинки:
bmpwidth:=ord(buff[19])+ord(buff[20])*256+ord(buff[21])*256*256+ ord(bu ff[22])*256*256*256;
bmpheight:=ord(buff[23])+ord(buff[24])*256+ord(buff[25])*256*256 +ord(b uff[26])*256*256*256;
Следующие два байта - значение 01 00.
Потом (24bit) - 18 00
Сжатие у обеих картинок: 00 00 00 00
Размер растра: 00 00 00 00 - в обеих так прописано.
количество пикселей на метр: 12 0B 00 00 - и по горизонтали и по вертикали (но мне-то это на кой?).
Далее в заголовке сплошные нули.

Потом, начиная с 55 байта, пошли данные о цвете пикселей. Их я и читаю (т.к. bmp 24bit, rgbReserved - отсутствует):

seek(bmpfile, 54);
x:=1; y:=bmpheight; i:=0;
repeat
blockread(bmpfile, buff, sizeof(buff), numread);
repeat
canvas.Pixels[x,y]:=ord(buff[1+i*3])+ord(buff[2+i*3])*256+ord(buff[3+i *3])*256*256;
inc(i);
inc(x);
if x>bmpwidth then begin x:=1; inc(y,-1) end;
until i=1024;
i:=0;
until numread=0;


 
[lamer]Barmaglot   (2003-08-25 14:56) [28]

Лень смотреть код...
1. По длинне слова выравниваешь?
2. Размеры изображений в студию плиз...


 
Ketmar   (2003-08-25 16:15) [29]

>#16
запросто. 50 USD. забесплатно у меня и более интересные дела есть. окромя создания очередного самоката.

>#28
нихрена там не ровняют, видно же, что нет этого кода.


 
otido   (2003-08-25 16:38) [30]

2 Ketmar (#29)
"А вам слабо?!"


 
Ketmar   (2003-08-25 17:09) [31]

>#30
угу. слабо. зачем?


 
otido   (2003-08-25 17:12) [32]

хм... а просто так... а то 50 уёв..... корыстно как-то....


 
Ketmar   (2003-08-25 17:14) [33]

с бескорыстием -- не ко мне. бескорыстно я могу только застрелить. и то если просящий предоставит оружие и боеприпасы.


 
otido   (2003-08-25 17:21) [34]

во блин....


 
cyborg   (2003-08-25 17:55) [35]

Вот из своего конвертера BMP24to16 повырезал код, может чего забыл:

...
TYPE
TSrcPicture = array[0..0] of byte;
VAR
BitmapFileHeader : TBitmapFileHeader;
BmpInfo : TBitmapInfo;
SrcSize : Cardinal;
SrcFile : File;
SrcPicture : Pointer;

...
//Функция получает адрес с данными пикселей:
Function ProcessPicture(Var SrcPicture : Pointer;
BPP: byte;W,H : Cardinal; Palette : Pointer) : boolean;
Var
Size : Cardinal;
I : Integer;
R,G,B : Byte;
begin
Result:=false;
Size:=(W*H*BPP) div 8;
Case BPP of
24 : begin
//Тут получай свои пиксели:
for I:=0 to (Size div 3)-1 do
begin
R:=TSrcPicture(SrcPicture^)[I*3];
G:=TSrcPicture(SrcPicture^)[I*3+1];
B:=TSrcPicture(SrcPicture^)[I*3+2];
end; //for I:=1 to Size do
end;
end;//case BPP
Result:=True;
end;

...

AssignFile(SrcFile,"file.bmp");
Reset(SrcFile,1);
FillChar(BitmapFileHeader,SizeOf(TBitmapFileHeader),0);

if FileSize(SrcFile)>SizeOf(TBitmapFileHeader) then
BlockRead(SrcFile,BitmapFileHeader,SizeOf(TBitmapFileHeader));
//Тут сделай проверку на загловок, если это BMP, то продолжай
...
BlockRead(SrcFile,BmpInfo.bmiHeader,SizeOf(TBitmapInfoHeader));
Seek(SrcFile,BitmapFileHeader.bfOffBits);
//Вычисляется размер для несжатого файла:
SrcSize:=(BmpInfo.bmiHeader.biWidth*BmpInfo.bmiHeader.biHeight*BmpInfo .bmiHeader.biBitCount) div 8;
//Выделение памяти под пиксели картинки:
GetMem(SrcPicture,SrcSize);
ProcessPicture(SrcPicture,
BmpInfo.bmiHeader.biBitCount,
BmpInfo.bmiHeader.biWidth,
BmpInfo.bmiHeader.biHeight,nil);
FreeMem(SrcPicture,SrcSize); SrcPicture:=nil;
CloseFile(SrcFile);
...


Ещё учти то, что высота, вроде, если имеет отрицательное значение, то строки в файле записаны наоборот, т.е. снизу вверх.

Насчёт выделения памяти под заголовок, нужно не с фонаря размеры брать, а точно, ты же не на картошку поехал :)


 
cyborg   (2003-08-25 18:03) [36]

Сейчас просмотрел, главное забыл :)
после
GetMem(SrcPicture,SrcSize);
нужно вставить
BlockRead(SrcFile,SrcPicture^,SrcSize);


 
выарп   (2003-08-25 19:42) [37]

to cyborg ©
Для твоего кода, тоже bmp-ки не верно отображаются (как у меня).
Я понимаю, что мало чего смыслю в программировании, но
тут мелькнула мысль: .icm как-нибудь может влиять на отбражаемые цвета?
В любом случае, вот мои bmp-ки с твоим кодом:
http://www.sinor.ru/~namenlos/bmp.zip (23,6 КБ)


 
cyborg   (2003-08-25 21:01) [38]

Поменяй местами R и B цвета.


 
выарп   (2003-08-26 08:55) [39]

>cyborg © (25.08.03 21:01) [38]
Спасибо!!!

А ларчик просто открывался...



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2003.09.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.024 c
3-48440
stud
2003-08-25 10:55
2003.09.15
sql запрос ...........


6-48679
SkyWalker
2003-07-10 15:54
2003.09.15
Как из TWebBrowser получить содержимое загруженного html


7-48818
Kalifen
2003-07-01 19:09
2003.09.15
Контроль печати.


1-48596
INTAARI
2003-09-03 16:49
2003.09.15
Как открыть блокнот


3-48401
Anna
2003-08-26 11:36
2003.09.15
Фильтры и диапазоны





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский