Unit bmp2pdf.pas:
unit bmp2pdf;
interface
{Unit bmp2pdf.pas}
uses
Windows,Classes, Graphics, SysUtils;
procedure BMPtoPDF(BMP:TBitmap;SaveName:String);
implementation
type
pRGBArray = ^TRGBArray;
TRGBArray = array[0..32768-1] of TRGBTriple;
procedure Write_CrossReferenceTable(AStream: TStream;PosArray : array of Dword;Count:Integer);
Var
i :Integer;
begin
With TStringStream(AStream) do
begin
WriteString('xref'
WriteString(Format('0 %d'
WriteString('0000000000 65535 f '
for i:= 0 to Count-1 do
begin
WriteString(Format('%0.10d',[PosArray[i]])+' 00000 n '
end;
end;
end;
procedure Write_ContentsObject(AStream: TStream;Index : Dword; Width,Height : Integer);
Var
MemoryStream : TMemoryStream;
begin
MemoryStream:=TMemoryStream.Create;
Try
With TStringStream(MemoryStream) do
begin
WriteString('q'
WriteString(Format('%d 0 0 %d 0 0 cm'
WriteString('/Im0 Do'
WriteString('Q'
end;
MemoryStream.Position:=0;
With TStringStream(AStream) do
begin
WriteString(Format('%d 0 obj'
WriteString(Format('<< /Length %d >>'
WriteString('stream'
AStream.CopyFrom(MemoryStream,MemoryStream.Size) ;
WriteString('endstream'
WriteString('endobj'
end;
finally
MemoryStream.Free;
end;
end;
procedure GetBitmapData(AStream :TStream;BMP:TBitmap);
var
tmp :TBitmap;
Buffer : Pointer;
SrcRow,DestRow : pRGBArray;
Row,Col,DestCnt : Integer;
begin
DestCnt:=0;
tmp := TBitmap.Create;
tmp.Assign(BMP);
tmp.PixelFormat:=pf24bit;
GetMem(Buffer,tmp.Width*tmp.height*3);
DestRow :=Buffer;
try
for Row:=0 to tmp.Height-1 do
begin
SrcRow :=tmp.ScanLine[Row];
for Col:=0 to tmp.Width-1 do
begin
DestRow[DestCnt].rgbtBlue := SrcRow[Col].rgbtRed;
DestRow[DestCnt].rgbtGreen := SrcRow[Col].rgbtGreen;
DestRow[DestCnt].rgbtRed := SrcRow[Col].rgbtBlue;
Inc(DestCnt);
end;
end;
AStream.Write(DestRow^,tmp.Width*tmp.Height*3);
finally
tmp.Free;
FreeMem(Buffer);
end;
end;
procedure BMPtoPDF(BMP:TBitmap;SaveName:String);
Var
AStream,BitsData : TStream;
ObjectIndex : Integer;
ObjectPosArray : array [0..10] of Dword;
begin
if BMP=nil then
raise Exception.Create('Bitmap is nil');
if SaveName='' then
raise Exception.Create('SaveName is nil');
ObjectIndex :=0;
AStream :=TFileStream.Create(SaveName,fmCreate) ;
BitsData :=TMemorySTream.Create;
Try
GetBitmapData(BitsData,BMP);
BitsData.Position:=0;
TStringStream(AStream).WriteString('%PDF-1.2'
ObjectPosArray[ObjectIndex] :=AStream.Position;
With TStringStream(AStream) do
begin
WriteString(Format('%d 0 obj'
WriteString('<<'
WriteString('/Type /Catalog'
WriteString('/Pages 2 0 R'
WriteString('/OpenAction [3 0 R /XYZ -32768 -32768 1 ]'
WriteString('>>'
WriteString('endobj'
end;
Inc(ObjectIndex);
ObjectPosArray[ObjectIndex] :=AStream.Position;
With TStringStream(AStream) do
begin
WriteString(Format('%d 0 obj'
WriteString('<<'
WriteString('/Type /Pages'
WriteString('/Kids [ 3 0 R ]'
WriteString('/Count 1'
WriteString('>>'
WriteString('endobj'
end;
Inc(ObjectIndex);
ObjectPosArray[ObjectIndex] :=AStream.Position;
With TStringStream(AStream) do
begin
WriteString(Format('%d 0 obj'
WriteString('<<'
WriteString('/Type /Page'
WriteString('/Parent 2 0 R'
WriteString('/Resources'
WriteString('<<'
WriteString('/XObject << /Im0 4 0 R >>'
WriteString('/ProcSet [ /PDF /ImageC ]'
WriteString('>>'
WriteString(Format('/MediaBox [ 0 0 %d %d ]'
WriteString('/Contents 5 0 R'
WriteString('>>'
WriteString('endobj'
end;
Inc(ObjectIndex);
ObjectPosArray[ObjectIndex] :=AStream.Position;
With TStringStream(AStream) do
begin
WriteString(Format('%d 0 obj'
WriteString('<<'
WriteString('/Type /XObject'
WriteString('/Subtype /Image'
WriteString('/Name /Im0'
WriteString(Format('/Width %d'
WriteString(Format('/Height %d'
WriteString('/BitsPerComponent 8'
WriteString('/Filter []'
WriteString('/ColorSpace /DeviceRGB'
WriteString(Format('/Length %d >>'
WriteString('stream'
AStream.CopyFrom(BitsData,BitsData.Size);
WriteString('endstream'
WriteString('endobj'
end;
Inc(ObjectIndex);
ObjectPosArray[ObjectIndex] :=AStream.Position;
With TStringStream(AStream) do
begin
Write_ContentsObject(AStream,ObjectIndex+1,BMP.Width,BMP.Height);
end;
Inc(ObjectIndex);
ObjectPosArray[ObjectIndex] :=AStream.Position;
Write_CrossReferenceTable(AStream,ObjectPosArray,ObjectIndex);
With TStringStream(AStream) do
begin
WriteString('trailer'
WriteString('<<'
WriteString(Format('/Size %d'
WriteString('/Root 1 0 R'
WriteString('>>'
WriteString('startxref'
WriteString(Format('%d'
WriteString('%%EOF');
end;
finally
AStream.Free;
BitsData.Free;
end;
end;
end.
Beispiel :
uses bmp2pdf
procedure TForm1.Button1Click(Sender: TObject);
var BMP : TBitmap;
begin
BMP := TBitmap.Create;
if OpenDialog1.Execute then begin
try
BMP.LoadFromFile(OpenDialog1.FileName);
BMPtoPDF(BMP, OpenDialog1.FileName + '.pdf');
end;
finally
BMP.Free;
end;
end;
Keine Kommentare:
Kommentar veröffentlichen