我需要一些关于Delphi位图和内存流的帮助。 我只是摆弄Debenu PDF库,应该将pdf页面呈现给BMP,然后再将它们读回Image组件:
var
Image1: TImage;
Image2: TImage;
PDF: TDebenuPDFLibrary;
MS: TMemoryStream;
procedure TForm1.Button1Click(Sender: TObject);
begin
PDF.LoadFromFile('D:/something.pdf','');
MS:=TMemoryStream.Create;
PDF.RenderPageToStream(72,1,0,MS);
MS.Position:= 0;
Image1.Picture.Bitmap.LoadFromStream(MS);
Image1.Repaint;
MS.Free;
end;
它有效,到目前为止一切顺利! 但是当我尝试加载多个图像时,我会得到运行时消息:
"Stream read error"
我尝试的代码:
var
Image1: TImage;
Image2: TImage;
PDF: TDebenuPDFLibrary; //To render PDF to bitmaps
MS: TMemoryStream;
procedure TForm1.Button1Click(Sender: TObject);
begin
PDF.LoadFromFile('D:/something.pdf','');
MS:=TMemoryStream.Create;
PDF.RenderPageToStream(72,1,0,MS); //First page
PDF.RenderPageToStream(72,2,0,MS); //Second page
MS.Position:= 0;
Image1.Picture.Bitmap.LoadFromStream(MS);
Image1.Repaint;
Image2.Picture.Bitmap.LoadFromStream(MS);
Image2.Repaint;
MS.Free;
end;
任何帮助?
答案 0 :(得分:1)
您遇到问题的最可能的解释是RenderPageToStream
在写入之前寻找流的开头。可以将位图连接成一个流并通过连续调用TBitmap.LoadFromStream
来读取它们,因此问题必须在于写入流的代码。因此RenderPageToStream
可能是罪魁祸首。
如果是这样,并且应该很容易为程序添加一些诊断程序来检测这一点,那么您应该通过将每个图像放在一个单独的流中来解决问题。或者,重复使用相同的流,但不要尝试一次将多个图像放入其中。或者使用某种形式的复合存储将多个图像放在一个流中,如Remy的回答所示。
答案 1 :(得分:1)
如果要从单个源流加载多个图像,最好在分割流中的图像,然后为每个加载使用单独的流。这使得在流数据中非常清楚一个图像结束并且下一个图像开始。例如:
procedure RenderPDFToStream(PDF: TDebenuPDFLibrary; Page: Integer; Stream: TStream);
var
MS: TMemoryStream;
Size: Integer;
begin
MS := TMemoryStream.Create;
try
PDF.RenderPageToStream(72, Page, 0, MS);
Size := MS.Size;
Stream.WriteBuffer(Size, SizeOf(Size));
if Size > 0 then
Stream.CopyFrom(MS, Size);
finally
MS.Free;
end;
end;
procedure LoadBitmapFromStream(Stream: TStream; Bitmap: TBitmap);
var
MS: TMemoryStream;
Size: Integer;
begin
MS := TMemoryStream.Create;
try
Stream.ReadBuffer(Size, SizeOf(Size));
if Size > 0 then
MS.CopyFrom(Stream, Size);
MS.Position := 0;
Bitmap.LoadFromStream(MS);
finally
MS.Free;
end;
end;
var
Image1: TImage;
Image2: TImage;
PDF: TDebenuPDFLibrary; //To render PDF to bitmaps
procedure TForm1.Button1Click(Sender: TObject);
var
MS: TMemoryStream;
begin
PDF.LoadFromFile('D:/something.pdf','');
MS := TMemoryStream.Create;
try
RenderPDFToStream(PDF, 1, MS);
RenderPDFToStream(PDF, 2, MS);
MS.Position := 0;
LoadBitmapFromStream(MS, Image1.Picture.Bitmap);
LoadBitmapFromStream(MS, Image2.Picture.Bitmap);
finally
MS.Free;
end;
end;