Tôi có một chức năng chuyển đổi TBitmap (mà tôi vẽ) sang TPngImage và sau đó lưu nó vào luồng, vì vậy các phương pháp khác có thể sử dụng nó. Png được sử dụng bởi vì nó tạo ra hình ảnh nhỏ hơn cho đầu ra báo cáo (excel, html). Vấn đề là SaveToStream dường như mất quá nhiều thời gian, nhiều hơn 15 lần so với chuyển đổi TBitmap sang TPngImage hoặc sử dụng TStream với png. Đây là mã:Bất kỳ cách nào để tăng tốc độ SaveToStream trên TPNGImage?
var
BitmapImage: TBitmap;
PNGImage: TPngImage;
PngStream: TStream;
begin
// draw on BitmapImage
...
PNGImage := TPngImage.Create;
PNGStream := TMemoryStream.Create;
Try
PNGImage.Assign(BitmapPicture.Bitmap); // Step 1: assign TBitmap to PNG
PNGImage.SaveToStream(PNGStream); // Step 2: save PNG to stream
WS.Shapes.AddPicture(PNGStream,PNGImage.Width,PNGImage.Height); // Step 3: Add PNG from Stream to Excel
finally
PNGImage.Free;
PNGStream.Free;
end;
...
này được thử nghiệm với 70000 hình ảnh và đây là những timings:
Bước 1: 7 s
Bước 2: 93 s
Bước 3: 6 s
Tại sao lưu vào luồng quá chậm? Bất kỳ đề xuất nào để tối ưu hóa điều này?
Sử dụng Delphi XE7
EDIT
Dưới đây là ví dụ (MCVE) với bmp đơn giản mà được chuyển đổi sang PNG và sau đó lưu vào suối. Chỉ vì mục đích xác minh khác, tôi đã thêm SaveToFile, điều này tất nhiên mất nhiều thời gian hơn, nhưng nó được lưu vào đĩa, vì vậy tôi cho rằng có thể chấp nhận được.
img1.bmp là 49,5KB, PNG đã lưu là 661 byte. liên kết đến img1.bmp = http://www.filedropper.com/img1_1
TMemoryStreamAccess = class(TMemoryStream)
end;
procedure TForm1.Button1Click(Sender: TObject);
var BitmapImage:TBitmap;
PNGImage:TPngImage;
PNGStream:TMemoryStream;//TStream;
i,t1,t2,t3,t4,t5,t6: Integer;
vFileName:string;
begin
BitmapImage:=TBitmap.Create;
BitmapImage.LoadFromFile('c:\tmp\img1.bmp');
t1:=0; t2:=0; t3:=0; t4:=0; t5:=0; t6:=0;
for i := 1 to 70000 do
begin
PNGImage:=TPngImage.Create;
PNGStream:=TMemoryStream.Create;
try
t1:=GetTickCount;
PNGImage.Assign(BitmapImage);
t2:=t2+GetTickCount-t1;
t3:=GetTickCount;
TMemoryStreamAccess(PNGStream).Capacity := 1000;
PNGImage.SaveToStream(PNGStream);
// BitmapImage.SaveToStream(PNGStream); <-- very fast!
t4:=t4+GetTickCount-t3;
finally
PNGImage.Free;
PNGstream.Free
end;
end;
showmessage('Assign = '+inttostr(t2)+' - SaveToStream = '+inttostr(t4));
end;
Sẽ rất tuyệt nếu bạn có thể cung cấp MCVE –
@DavidHeffernan Bạn không chắc chắn MCVE là gì ...? –
Bạn có thể tra cứu bằng tìm kiếm trên web –