You've already forked lazarus-ccr
PowerPDF, support for images with transparency/alfa channel
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1394 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -473,6 +473,7 @@ type
|
|||||||
{ TPRImage }
|
{ TPRImage }
|
||||||
TPRImage = class(TPRItem)
|
TPRImage = class(TPRItem)
|
||||||
private
|
private
|
||||||
|
FSharedName: string;
|
||||||
procedure SetStretch(Value: boolean);
|
procedure SetStretch(Value: boolean);
|
||||||
protected
|
protected
|
||||||
FPicture: TPicture;
|
FPicture: TPicture;
|
||||||
@ -484,6 +485,7 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
property SharedName: string read FSharedName write FSharedName;
|
||||||
published
|
published
|
||||||
property Picture: TPicture read FPicture write SetPicture;
|
property Picture: TPicture read FPicture write SetPicture;
|
||||||
property SharedImage: boolean read FSharedImage write FSharedImage;
|
property SharedImage: boolean read FSharedImage write FSharedImage;
|
||||||
@ -2312,14 +2314,16 @@ var
|
|||||||
FIdx: integer;
|
FIdx: integer;
|
||||||
begin
|
begin
|
||||||
if (FPicture = nil) or (FPicture.Graphic = nil) or
|
if (FPicture = nil) or (FPicture.Graphic = nil) or
|
||||||
(FPicture.Graphic.Empty) or not (FPicture.Graphic is TBitmap) then
|
(FPicture.Graphic.Empty) {or not (FPicture.Graphic is TFPImageBitmap)} then
|
||||||
Exit;
|
Exit;
|
||||||
FDoc := ACanvas.PdfCanvas.Doc;
|
FDoc := ACanvas.PdfCanvas.Doc;
|
||||||
if SharedImage then
|
if SharedImage then
|
||||||
begin
|
begin
|
||||||
FXObjectName := Self.Name;
|
FXObjectName := Self.Name;
|
||||||
|
if FXObjectName='' then
|
||||||
|
FXObjectName := FSharedName;
|
||||||
if FDoc.GetXObject(FXObjectName) = nil then
|
if FDoc.GetXObject(FXObjectName) = nil then
|
||||||
FDoc.AddXObject(FXObjectName, CreatePdfImage(FPicture.Graphic, 'Pdf-Bitmap'));
|
FDoc.AddXObject(FXObjectName, CreatePdfImage(FPicture.Graphic, 'Pdf-Bitmap', FDoc.ObjectMgr));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -2334,7 +2338,7 @@ begin
|
|||||||
if FIdx >= MAX_IMAGE_NUMBER then
|
if FIdx >= MAX_IMAGE_NUMBER then
|
||||||
FIdx := 0;
|
FIdx := 0;
|
||||||
end;
|
end;
|
||||||
FDoc.AddXObject(FXObjectName, CreatePdfImage(FPicture.Graphic, 'Pdf-Bitmap'));
|
FDoc.AddXObject(FXObjectName, CreatePdfImage(FPicture.Graphic, 'Pdf-Bitmap', FDoc.ObjectMgr));
|
||||||
end;
|
end;
|
||||||
with ARect, ACanvas.PdfCanvas do
|
with ARect, ACanvas.PdfCanvas do
|
||||||
if FStretch then
|
if FStretch then
|
||||||
|
@ -346,6 +346,7 @@ type
|
|||||||
property Info: TPdfInfo read GetInfo;
|
property Info: TPdfInfo read GetInfo;
|
||||||
property Root: TPdfCatalog read GetRoot;
|
property Root: TPdfCatalog read GetRoot;
|
||||||
property OutlineRoot: TPdfOutlineRoot read GetOutlineRoot;
|
property OutlineRoot: TPdfOutlineRoot read GetOutlineRoot;
|
||||||
|
property ObjectMgr: TPdfXRef read FXRef;
|
||||||
property DefaultPageWidth: word read FDefaultPageWidth write FDefaultPageWidth;
|
property DefaultPageWidth: word read FDefaultPageWidth write FDefaultPageWidth;
|
||||||
property DefaultPageHeight: word read FDefaultPageHeight write FDefaultPageHeight;
|
property DefaultPageHeight: word read FDefaultPageHeight write FDefaultPageHeight;
|
||||||
property CompressionMethod: TPdfCompressionMethod
|
property CompressionMethod: TPdfCompressionMethod
|
||||||
|
@ -53,23 +53,26 @@ uses
|
|||||||
type
|
type
|
||||||
TPdfImageCreator = class(TPersistent)
|
TPdfImageCreator = class(TPersistent)
|
||||||
public
|
public
|
||||||
function CreateImage(AImage: TGraphic): TPdfImage; virtual;
|
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; virtual;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TPdfBitmapImage }
|
||||||
|
|
||||||
TPdfBitmapImage = class(TPdfImageCreator)
|
TPdfBitmapImage = class(TPdfImageCreator)
|
||||||
private
|
private
|
||||||
function CreateIndexedColorArray(ABitmap: TBitmap): TPdfArray;
|
function CreateIndexedColorArray(ABitmap: TBitmap): TPdfArray;
|
||||||
|
function CreateMaskStream(AImage: TFPCustomImage): TPDfImage;
|
||||||
public
|
public
|
||||||
function CreateImage(AImage: TGraphic): TPdfImage; override;
|
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
EPdfInvalidImageFormat = class(Exception);
|
EPdfInvalidImageFormat = class(Exception);
|
||||||
|
|
||||||
function CreatePdfImage(AImage: TGraphic; ImageClassName: string): TPdfImage;
|
function CreatePdfImage(AImage: TGraphic; ImageClassName: string; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function CreatePdfImage(AImage: TGraphic; ImageClassName: string): TPdfImage;
|
function CreatePdfImage(AImage: TGraphic; ImageClassName: string; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
var
|
var
|
||||||
PdfImageCreator: TPdfImageCreator;
|
PdfImageCreator: TPdfImageCreator;
|
||||||
begin
|
begin
|
||||||
@ -82,14 +85,14 @@ begin
|
|||||||
try
|
try
|
||||||
if PdfImageCreator = nil then
|
if PdfImageCreator = nil then
|
||||||
raise Exception.CreateFmt('AddImage --InvalidImageClassName:%s', [ImageClassName]);
|
raise Exception.CreateFmt('AddImage --InvalidImageClassName:%s', [ImageClassName]);
|
||||||
Result := PdfImageCreator.CreateImage(AImage);
|
Result := PdfImageCreator.CreateImage(AImage, ObjectMgr);
|
||||||
finally
|
finally
|
||||||
PdfImageCreator.Free;
|
PdfImageCreator.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TPdfImageCreator }
|
{ TPdfImageCreator }
|
||||||
function TPdfImageCreator.CreateImage(AImage: TGraphic): TPdfImage;
|
function TPdfImageCreator.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
begin
|
begin
|
||||||
result := nil;
|
result := nil;
|
||||||
end;
|
end;
|
||||||
@ -161,7 +164,41 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPdfBitmapImage.CreateImage(AImage: TGraphic): TPdfImage;
|
function TPdfBitmapImage.CreateMaskStream(AImage: TFPCustomImage): TPDfImage;
|
||||||
|
var
|
||||||
|
pb: PByteArray;
|
||||||
|
y: Integer;
|
||||||
|
x: Integer;
|
||||||
|
begin
|
||||||
|
result := TPdfImage.CreateStream(nil);
|
||||||
|
with result do
|
||||||
|
try
|
||||||
|
with Attributes do
|
||||||
|
begin
|
||||||
|
AddItem('Type', TPdfName.CreateName('XObject'));
|
||||||
|
AddItem('Subtype', TPdfName.CreateName('Image'));
|
||||||
|
AddItem('Width', TPdfNumber.CreateNumber(aImage.Width));
|
||||||
|
AddItem('Height', TPdfNumber.CreateNumber(aImage.Height));
|
||||||
|
AddItem('BitsPerComponent', TPdfNumber.CreateNumber(8));
|
||||||
|
AddItem('ColorSpace',TPdfName.CreateName('DeviceGray'));
|
||||||
|
if USE_ZLIB then
|
||||||
|
PdfArrayByName('Filter').AddItem(TPdfName.CreateName('FlateDecode'));
|
||||||
|
|
||||||
|
new(pb);
|
||||||
|
for y := 0 to AImage.Height - 1 do
|
||||||
|
begin
|
||||||
|
for x := 0 to AImage.Width-1 do
|
||||||
|
pb^[x] := AImage.Pixels[x,y];
|
||||||
|
Stream.Write(pb^, AImage.Width);
|
||||||
|
end;
|
||||||
|
dispose(pb);
|
||||||
|
end;
|
||||||
|
|
||||||
|
finally
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPdfBitmapImage.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
var
|
var
|
||||||
ABitmap: TBitmap;
|
ABitmap: TBitmap;
|
||||||
x, y: integer;
|
x, y: integer;
|
||||||
@ -170,14 +207,17 @@ var
|
|||||||
{$IFDEF LAZ_POWERPDF}
|
{$IFDEF LAZ_POWERPDF}
|
||||||
aIntfImage: TLazIntfImage;
|
aIntfImage: TLazIntfImage;
|
||||||
aColor : TFPColor;
|
aColor : TFPColor;
|
||||||
|
Alpha : TFPMemoryImage;
|
||||||
|
maskimage : TPDFImage;
|
||||||
|
hasAlpha : boolean;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
{$IFDEF USE_CLX}
|
||||||
const
|
const
|
||||||
{$IFDEF USE_CLX}
|
|
||||||
PIXEL_COLOR_SIZE = 4;
|
PIXEL_COLOR_SIZE = 4;
|
||||||
{$ELSE}
|
{$ENDIF}
|
||||||
PIXEL_COLOR_SIZE = 3;
|
|
||||||
{$ENDIF}
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
result := TPdfImage.CreateStream(nil);
|
result := TPdfImage.CreateStream(nil);
|
||||||
with result do
|
with result do
|
||||||
try
|
try
|
||||||
@ -197,8 +237,6 @@ begin
|
|||||||
aIntfImage := TLazIntfImage.Create(0,0);
|
aIntfImage := TLazIntfImage.Create(0,0);
|
||||||
aIntfImage.LoadFromBitmap(aBitmap.Handle, aBitmap.MaskHandle);
|
aIntfImage.LoadFromBitmap(aBitmap.Handle, aBitmap.MaskHandle);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
// if bitmap image has less then 8 bit color, set PixelFormat to 8 bit.
|
// if bitmap image has less then 8 bit color, set PixelFormat to 8 bit.
|
||||||
if (PixelFormat = pf1bit) or
|
if (PixelFormat = pf1bit) or
|
||||||
{$IFNDEF USE_CLX}
|
{$IFNDEF USE_CLX}
|
||||||
@ -257,7 +295,22 @@ begin
|
|||||||
Stream.Write(pb[x], 3);
|
Stream.Write(pb[x], 3);
|
||||||
x := x + PIXEL_COLOR_SIZE;
|
x := x + PIXEL_COLOR_SIZE;
|
||||||
end;
|
end;
|
||||||
|
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
||||||
|
end;
|
||||||
{$else}
|
{$else}
|
||||||
|
Alpha := TFPMemoryImage.Create(AImage.Width, AImage.Height);
|
||||||
|
Alpha.UsePalette := true;
|
||||||
|
Alpha.Palette.Count := 256;
|
||||||
|
for x:=0 to $FF do
|
||||||
|
begin
|
||||||
|
aColor.Red:=x;
|
||||||
|
aColor.Red:=(aColor.Red shl 8) + aColor.Red;
|
||||||
|
aColor.Green:=aColor.Red;
|
||||||
|
aColor.Blue:=aColor.Red;
|
||||||
|
Alpha.Palette.Color[x]:=aColor;
|
||||||
|
end;
|
||||||
|
HasAlpha := false;
|
||||||
|
|
||||||
for y := 0 to aintfimage.Height - 1 do
|
for y := 0 to aintfimage.Height - 1 do
|
||||||
begin
|
begin
|
||||||
new(pb);
|
new(pb);
|
||||||
@ -268,11 +321,26 @@ begin
|
|||||||
pb[ 1 ] := acolor.green shr 8;
|
pb[ 1 ] := acolor.green shr 8;
|
||||||
pb[ 2 ] := acolor.blue shr 8;
|
pb[ 2 ] := acolor.blue shr 8;
|
||||||
Stream.write(pb[ 0 ], 3);
|
Stream.write(pb[ 0 ], 3);
|
||||||
|
|
||||||
|
b := acolor.alpha shr 8;
|
||||||
|
Alpha.Pixels[x,y] := b;
|
||||||
|
|
||||||
|
if acolor.Alpha<>AlphaOpaque then
|
||||||
|
HasAlpha := true;
|
||||||
end;
|
end;
|
||||||
dispose(pb);
|
dispose(pb);
|
||||||
{$endif}
|
|
||||||
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if HasAlpha then begin
|
||||||
|
MaskImage := CreateMaskStream(Alpha);
|
||||||
|
if ObjectMgr<>nil then
|
||||||
|
ObjectMgr.AddObject(MaskImage);
|
||||||
|
Attributes.AddItem('SMask', MaskImage);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Alpha.Free;
|
||||||
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
with Attributes do
|
with Attributes do
|
||||||
|
@ -35,13 +35,13 @@ type
|
|||||||
{ TPdfJpegImage }
|
{ TPdfJpegImage }
|
||||||
TPdfJpegImage = class(TPdfImageCreator)
|
TPdfJpegImage = class(TPdfImageCreator)
|
||||||
public
|
public
|
||||||
function CreateImage(AImage: TGraphic): TPdfImage; override;
|
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
// CreateImage
|
// CreateImage
|
||||||
function TPdfJpegImage.CreateImage(AImage: TGraphic): TPdfImage;
|
function TPdfJpegImage.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
begin
|
begin
|
||||||
// check whether specified graphic is valid image.
|
// check whether specified graphic is valid image.
|
||||||
if not (AImage is TJpegImage) then
|
if not (AImage is TJpegImage) then
|
||||||
|
Reference in New Issue
Block a user