Форум: "Потрепаться";
Текущий архив: 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