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 = class(TPRItem)
|
||||
private
|
||||
FSharedName: string;
|
||||
procedure SetStretch(Value: boolean);
|
||||
protected
|
||||
FPicture: TPicture;
|
||||
@ -484,6 +485,7 @@ type
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
property SharedName: string read FSharedName write FSharedName;
|
||||
published
|
||||
property Picture: TPicture read FPicture write SetPicture;
|
||||
property SharedImage: boolean read FSharedImage write FSharedImage;
|
||||
@ -2312,14 +2314,16 @@ var
|
||||
FIdx: integer;
|
||||
begin
|
||||
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;
|
||||
FDoc := ACanvas.PdfCanvas.Doc;
|
||||
if SharedImage then
|
||||
begin
|
||||
FXObjectName := Self.Name;
|
||||
if FXObjectName='' then
|
||||
FXObjectName := FSharedName;
|
||||
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
|
||||
else
|
||||
begin
|
||||
@ -2334,7 +2338,7 @@ begin
|
||||
if FIdx >= MAX_IMAGE_NUMBER then
|
||||
FIdx := 0;
|
||||
end;
|
||||
FDoc.AddXObject(FXObjectName, CreatePdfImage(FPicture.Graphic, 'Pdf-Bitmap'));
|
||||
FDoc.AddXObject(FXObjectName, CreatePdfImage(FPicture.Graphic, 'Pdf-Bitmap', FDoc.ObjectMgr));
|
||||
end;
|
||||
with ARect, ACanvas.PdfCanvas do
|
||||
if FStretch then
|
||||
|
@ -346,6 +346,7 @@ type
|
||||
property Info: TPdfInfo read GetInfo;
|
||||
property Root: TPdfCatalog read GetRoot;
|
||||
property OutlineRoot: TPdfOutlineRoot read GetOutlineRoot;
|
||||
property ObjectMgr: TPdfXRef read FXRef;
|
||||
property DefaultPageWidth: word read FDefaultPageWidth write FDefaultPageWidth;
|
||||
property DefaultPageHeight: word read FDefaultPageHeight write FDefaultPageHeight;
|
||||
property CompressionMethod: TPdfCompressionMethod
|
||||
|
@ -53,23 +53,26 @@ uses
|
||||
type
|
||||
TPdfImageCreator = class(TPersistent)
|
||||
public
|
||||
function CreateImage(AImage: TGraphic): TPdfImage; virtual;
|
||||
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; virtual;
|
||||
end;
|
||||
|
||||
{ TPdfBitmapImage }
|
||||
|
||||
TPdfBitmapImage = class(TPdfImageCreator)
|
||||
private
|
||||
function CreateIndexedColorArray(ABitmap: TBitmap): TPdfArray;
|
||||
function CreateMaskStream(AImage: TFPCustomImage): TPDfImage;
|
||||
public
|
||||
function CreateImage(AImage: TGraphic): TPdfImage; override;
|
||||
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; override;
|
||||
end;
|
||||
|
||||
EPdfInvalidImageFormat = class(Exception);
|
||||
|
||||
function CreatePdfImage(AImage: TGraphic; ImageClassName: string): TPdfImage;
|
||||
function CreatePdfImage(AImage: TGraphic; ImageClassName: string; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||
|
||||
implementation
|
||||
|
||||
function CreatePdfImage(AImage: TGraphic; ImageClassName: string): TPdfImage;
|
||||
function CreatePdfImage(AImage: TGraphic; ImageClassName: string; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||
var
|
||||
PdfImageCreator: TPdfImageCreator;
|
||||
begin
|
||||
@ -82,14 +85,14 @@ begin
|
||||
try
|
||||
if PdfImageCreator = nil then
|
||||
raise Exception.CreateFmt('AddImage --InvalidImageClassName:%s', [ImageClassName]);
|
||||
Result := PdfImageCreator.CreateImage(AImage);
|
||||
Result := PdfImageCreator.CreateImage(AImage, ObjectMgr);
|
||||
finally
|
||||
PdfImageCreator.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TPdfImageCreator }
|
||||
function TPdfImageCreator.CreateImage(AImage: TGraphic): TPdfImage;
|
||||
function TPdfImageCreator.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||
begin
|
||||
result := nil;
|
||||
end;
|
||||
@ -161,7 +164,41 @@ begin
|
||||
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
|
||||
ABitmap: TBitmap;
|
||||
x, y: integer;
|
||||
@ -170,14 +207,17 @@ var
|
||||
{$IFDEF LAZ_POWERPDF}
|
||||
aIntfImage: TLazIntfImage;
|
||||
aColor : TFPColor;
|
||||
Alpha : TFPMemoryImage;
|
||||
maskimage : TPDFImage;
|
||||
hasAlpha : boolean;
|
||||
{$endif}
|
||||
|
||||
{$IFDEF USE_CLX}
|
||||
const
|
||||
{$IFDEF USE_CLX}
|
||||
PIXEL_COLOR_SIZE = 4;
|
||||
{$ELSE}
|
||||
PIXEL_COLOR_SIZE = 3;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
begin
|
||||
|
||||
result := TPdfImage.CreateStream(nil);
|
||||
with result do
|
||||
try
|
||||
@ -197,8 +237,6 @@ begin
|
||||
aIntfImage := TLazIntfImage.Create(0,0);
|
||||
aIntfImage.LoadFromBitmap(aBitmap.Handle, aBitmap.MaskHandle);
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
// if bitmap image has less then 8 bit color, set PixelFormat to 8 bit.
|
||||
if (PixelFormat = pf1bit) or
|
||||
{$IFNDEF USE_CLX}
|
||||
@ -257,7 +295,22 @@ begin
|
||||
Stream.Write(pb[x], 3);
|
||||
x := x + PIXEL_COLOR_SIZE;
|
||||
end;
|
||||
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
||||
end;
|
||||
{$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
|
||||
begin
|
||||
new(pb);
|
||||
@ -268,11 +321,26 @@ begin
|
||||
pb[ 1 ] := acolor.green shr 8;
|
||||
pb[ 2 ] := acolor.blue shr 8;
|
||||
Stream.write(pb[ 0 ], 3);
|
||||
|
||||
b := acolor.alpha shr 8;
|
||||
Alpha.Pixels[x,y] := b;
|
||||
|
||||
if acolor.Alpha<>AlphaOpaque then
|
||||
HasAlpha := true;
|
||||
end;
|
||||
dispose(pb);
|
||||
{$endif}
|
||||
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
||||
end;
|
||||
|
||||
if HasAlpha then begin
|
||||
MaskImage := CreateMaskStream(Alpha);
|
||||
if ObjectMgr<>nil then
|
||||
ObjectMgr.AddObject(MaskImage);
|
||||
Attributes.AddItem('SMask', MaskImage);
|
||||
end;
|
||||
|
||||
Alpha.Free;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
with Attributes do
|
||||
|
@ -35,13 +35,13 @@ type
|
||||
{ TPdfJpegImage }
|
||||
TPdfJpegImage = class(TPdfImageCreator)
|
||||
public
|
||||
function CreateImage(AImage: TGraphic): TPdfImage; override;
|
||||
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// CreateImage
|
||||
function TPdfJpegImage.CreateImage(AImage: TGraphic): TPdfImage;
|
||||
function TPdfJpegImage.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||
begin
|
||||
// check whether specified graphic is valid image.
|
||||
if not (AImage is TJpegImage) then
|
||||
|
Reference in New Issue
Block a user