procedure SaveToFileBMP(const aBmp: TBitmap; aFileName: String);
var
i, n, m, w: Integer;
f: File;
bmfh: BITMAPFILEHEADER;
bmih: BITMAPINFOHEADER;
p, p1: Pointer;
pSrc: PIntArray;
begin
if ExtractFileExt(aFileName) = '' then
aFileName := aFileName + '.bmp';
if GetDeviceCaps(aBmp.Canvas.Handle, BITSPIXEL) <> 32 then
begin
aBmp.SaveToFile(aFileName);
Exit;
end;
with bmfh do
begin
bfType := Ord('M') shl 8 or Ord('B');
bfSize := sizeOf(bmfh) + sizeOf(bmih) + aBmp.Width * aBmp.Height * 3;
bfReserved1 := 0;
bfReserved2 := 0;
bfOffBits := sizeOf(bmfh) + sizeOf(bmih);
end;
with bmih do
begin
biSize := SizeOf(bmih);
biWidth := aBmp.Width;
biHeight := aBmp.Height;
biPlanes := 1;
biBitCount := 24;
biCompression := BI_RGB;
biSizeImage := 0;
biXPelsPerMeter := 1;
biYPelsPerMeter := 1;
biClrUsed := 0;
biClrImportant := 0;
end;
n := aBmp.Width;
m := n * 3;
if m mod 4 <> 0 then
Inc(m, 4 - (m mod 4));
GetMem(p, m);
w := abmp.Width;
BmpToArray(aBmp, Pointer(pSrc));
AssignFile(f, aFileName);
Rewrite(f, 1);
BlockWrite(f, bmfh, SizeOf(bmfh));
BlockWrite(f, bmih, SizeOf(bmih));
for i := aBmp.Height - 1 downto 0 do
begin
p1 := @pSrc[w * i];
asm
push esi
push edi
mov ecx, n
mov esi, p1
mov edi, p
@L1:
lodsd
stosw
shr eax, 16
stosb
loop @L1
pop edi
pop esi
end;
BlockWrite(f, p^, m);
end;
CloseFile(f);
FreeMem(p);
FreeMem(pSrc);
end;