feya писал(а):Вопрос: Что за хня?
Ага. Понятно. Строки в БМП файле должны быть выровнены по 4 байта. То есть, если ширина картинки 514 пикселей, то строки на самом деле должны содержать 514 * 3 + (4 - (514*3 mod 4)) байт для (24-х битного цвета). Потому картинки с шириной 512, 516, 520 сохраняются нормально, а всё, что не делится нацело на 4 идёт с перекосом.
Чтобы не осталось непонтятностей с формулами, вот я поправил процедуру:
- Код: Выделить всё
procedure SaveBMP(Sender:TObject; W, H : integer; tPath : string; readcallback:TBMPRead); // Çàïèñü íà äèñê ôàéëà
Var f : file;
i ,nNextLine: integer;
InputArray:PlineRGBb;
TypeBmp:Word;
Header: bmHeader;
begin
Header:=SaveBMPHeader(tPath,W,H);
AssignFile(f,tPath);
ReWrite(f,1);
TypeBmp := $4D42;
BlockWrite(f,TypeBmp,sizeof(TypeBmp));
BlockWrite(f,Header,sizeof(Header));
BMPRead:=readcallback;
getmem(InputArray,(W )*3+1 + (4 - (w*3 mod 4)) );
for nNextLine:=0 to h-1 do
begin
// if not(ThreadScleit(Sender).Fprogress.Visible) then break;
// BMPRead(Sender,nNextLine,InputArray);
for i:=0 to w-1 do
begin
InputArray^[i].b:=i mod 255;
InputArray^[i].g:=i mod 255;
InputArray^[i].r:=nNextLine mod 255;
end;
seek(f, (h - nNextLine - 1) * ((W) * 3 + (4 - (w*3 mod 4)) ) +54);
BlockWrite(f,InputArray^,((W)*3 + (4 - (w*3 mod 4)) ));
end;
FreeMem(InputArray);
CloseFile(F);
end;
Соответственно при подсчёте размера битмапа надо учитывать эти добавки:
- Код: Выделить всё
Result.i.SizI:=(W * 3 + (4 - (w*3 mod 4)) )*H;// размер витмапа
P.S.
А ещё, если мне не изменяет память, там в шапке где-то должна указываться не только ширина картинки, но и какая получается реальная длина строк в байтах с учётом выравнивания по 4 байта. Насчёт этого я точно не помню. Давно очень игрался с этими форматами на ассемблере, теперь уж позабыл все тонкости=).