You've already forked lazarus-ccr
PowerPDF: use fcl-image for image processing.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7602 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
175
components/powerpdf/PdfImageLazTools.pas
Normal file
175
components/powerpdf/PdfImageLazTools.pas
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
unit PdfImageLazTools;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils,
|
||||||
|
FPImage,
|
||||||
|
FPReadBMP, FPReadPNG, FPReadJPEG, // make sure we have the basic readers
|
||||||
|
Graphics, PDFTypes;
|
||||||
|
|
||||||
|
function CreateAlphaImage(const aWidth, aHeight: Integer): TFPMemoryImage;
|
||||||
|
procedure ConvertGraphicToFPImage(AImage: TGraphic; out fpImg: TFPCustomImage);
|
||||||
|
function CreateMaskStream(AImage: TFPCustomImage): TPDfImage;
|
||||||
|
function CreateIndexedColorArray(ABitmap: TFPCustomImage): TPdfArray;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TRasterImageHelper }
|
||||||
|
|
||||||
|
TRasterImageHelper = class helper for TRasterImage
|
||||||
|
public
|
||||||
|
function RequestRawStream(out rawStream: TMemoryStream): boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CreateAlphaImage(const aWidth, aHeight: Integer): TFPMemoryImage;
|
||||||
|
var
|
||||||
|
aColor: TFPColor;
|
||||||
|
x: Integer;
|
||||||
|
begin
|
||||||
|
result := TFPMemoryImage.Create(aWidth, aHeight);
|
||||||
|
result.UsePalette := true;
|
||||||
|
result.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;
|
||||||
|
result.Palette.Color[x]:=aColor;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ConvertGraphicToFPImage(AImage: TGraphic; out fpImg: TFPCustomImage);
|
||||||
|
var
|
||||||
|
rawImgStream: TMemoryStream = nil;
|
||||||
|
useOriginalStream: boolean = false;
|
||||||
|
begin
|
||||||
|
if (AImage is TRasterImage) then
|
||||||
|
useOriginalStream := TRasterImage(AImage).RequestRawStream(rawImgStream);
|
||||||
|
|
||||||
|
if not useOriginalStream then begin
|
||||||
|
rawImgStream := TMemoryStream.Create;
|
||||||
|
AImage.SaveToStream(rawImgStream);
|
||||||
|
rawImgStream.Position := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
try
|
||||||
|
fpImg := TFPMemoryImage.Create(0, 0);
|
||||||
|
fpImg.UsePalette := false;
|
||||||
|
try
|
||||||
|
fpImg.LoadFromStream(rawImgStream);
|
||||||
|
except
|
||||||
|
fpImg.Free;
|
||||||
|
fpImg := nil;
|
||||||
|
raise
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
if not useOriginalStream then
|
||||||
|
rawImgStream.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function 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 CreateIndexedColorArray(ABitmap: TFPCustomImage): TPdfArray;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
ColorTable: TPdfBinary;
|
||||||
|
NumOfColors: integer;
|
||||||
|
S: string;
|
||||||
|
|
||||||
|
procedure AddColor(Red,Green,Blue:byte);
|
||||||
|
begin
|
||||||
|
S := S + IntToHex(Red, 2) +
|
||||||
|
IntToHex(Green, 2) +
|
||||||
|
IntToHex(Blue, 2) +
|
||||||
|
' ';
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// creating color table from palette of bitmap.
|
||||||
|
if (not ABitmap.UsePalette) then
|
||||||
|
raise EPdfInvalidImageFormat.Create('Expected indexed color image');
|
||||||
|
|
||||||
|
NumOfColors := ABitmap.Palette.Count;
|
||||||
|
|
||||||
|
// get/check palette entries
|
||||||
|
if ABitmap.Palette.Count=0 then
|
||||||
|
raise EPdfInvalidImageFormat.Create('failed to get Palette..');
|
||||||
|
|
||||||
|
ColorTable := TPdfBinary.Create;
|
||||||
|
S := '<';
|
||||||
|
|
||||||
|
for i := 0 to NumOfColors - 1 do
|
||||||
|
if i<ABitmap.Palette.Count then
|
||||||
|
with aBitmap.palette.color[i] do
|
||||||
|
AddColor(Red,Green,Blue)
|
||||||
|
else
|
||||||
|
AddColor(0,0,0);
|
||||||
|
|
||||||
|
S := S + '>';
|
||||||
|
ColorTable.Stream.Write(PChar(S)^, Length(S));
|
||||||
|
|
||||||
|
result := TPdfArray.CreateArray(nil);
|
||||||
|
with result do
|
||||||
|
begin
|
||||||
|
AddItem(TPdfName.CreateName('Indexed'));
|
||||||
|
AddItem(TPdfName.CreateName('DeviceRGB'));
|
||||||
|
AddItem(TPdfNumber.CreateNumber(NumOfColors - 1));
|
||||||
|
AddItem(ColorTable);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TRasterImageHelper }
|
||||||
|
|
||||||
|
function TRasterImageHelper.RequestRawStream(out rawStream: TMemoryStream
|
||||||
|
): boolean;
|
||||||
|
begin
|
||||||
|
// make direct use of the saved original stream to avoid re-copying
|
||||||
|
// this should be ok as it is very unlikely to change in the future.
|
||||||
|
rawStream := FSharedImage.SaveStream;
|
||||||
|
result := rawStream<>nil;
|
||||||
|
if result then
|
||||||
|
rawStream.Position := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -23,30 +23,29 @@
|
|||||||
* 2001.09.01 changed the implementation of the image.
|
* 2001.09.01 changed the implementation of the image.
|
||||||
*
|
*
|
||||||
*}
|
*}
|
||||||
{$IFDEF LAZ_POWERPDF}
|
{$IFDEF FPC}
|
||||||
{$H+}
|
{$MODE OBJFPC}{$H+}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
unit PdfImages;
|
unit PdfImages;
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
{$IFDEF UNIX}
|
{$IFDEF UNIX}
|
||||||
{$IFDEF LAZ_POWERPDF}
|
{$IFNDEF FPC}
|
||||||
{$ELSE}
|
|
||||||
{$DEFINE USE_CLX}
|
{$DEFINE USE_CLX}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils,
|
|
||||||
{$IFNDEF USE_CLX}
|
|
||||||
{$IFDEF LAZ_POWERPDF}
|
{$IFDEF LAZ_POWERPDF}
|
||||||
LCLType, LCLIntf, Graphics, FPImage, IntfGraphics, BmpComn,
|
SysUtils, LCLType, LCLIntf, Graphics, FPImage, IntfGraphics, GraphType, PdFImageLazTools,
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
Windows, Graphics,
|
{$IFNDEF USE_CLX}
|
||||||
|
Windows, SysUtils, Graphics,
|
||||||
|
{$ELSE}
|
||||||
|
SysUtils, QGraphics, Qt,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$ELSE}
|
|
||||||
QGraphics, Qt,
|
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Classes, PdfTypes, PdfDoc;
|
Classes, PdfTypes, PdfDoc;
|
||||||
|
|
||||||
@ -60,14 +59,13 @@ type
|
|||||||
|
|
||||||
TPdfBitmapImage = class(TPdfImageCreator)
|
TPdfBitmapImage = class(TPdfImageCreator)
|
||||||
private
|
private
|
||||||
|
{$IFNDEF LAZ_POWERPDF}
|
||||||
function CreateIndexedColorArray(ABitmap: TBitmap): TPdfArray;
|
function CreateIndexedColorArray(ABitmap: TBitmap): TPdfArray;
|
||||||
function CreateMaskStream(AImage: TFPCustomImage): TPDfImage;
|
{$ENDIF}
|
||||||
public
|
public
|
||||||
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; override;
|
function CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
EPdfInvalidImageFormat = class(Exception);
|
|
||||||
|
|
||||||
function CreatePdfImage(AImage: TGraphic; ImageClassName: string; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
function CreatePdfImage(AImage: TGraphic; ImageClassName: string; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -103,6 +101,106 @@ type
|
|||||||
PColorTable = ^TColorTable;
|
PColorTable = ^TColorTable;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF LAZ_POWERPDF}
|
||||||
|
function TPdfBitmapImage.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
|
var
|
||||||
|
fpImg: TFPCustomImage;
|
||||||
|
Alpha: TFPMemoryImage;
|
||||||
|
x, y, z: integer;
|
||||||
|
pb: PByteArray;
|
||||||
|
b: Byte;
|
||||||
|
aColor : TFPColor;
|
||||||
|
HasAlpha: Boolean;
|
||||||
|
MaskImage: TPdfImage;
|
||||||
|
|
||||||
|
procedure AddItems;
|
||||||
|
begin
|
||||||
|
with Result.Attributes do
|
||||||
|
begin
|
||||||
|
AddItem('Width', TPdfNumber.CreateNumber(aImage.Width));
|
||||||
|
AddItem('Height', TPdfNumber.CreateNumber(aImage.Height));
|
||||||
|
AddItem('BitsPerComponent', TPdfNumber.CreateNumber(8));
|
||||||
|
if USE_ZLIB then
|
||||||
|
PdfArrayByName('Filter').AddItem(TPdfName.CreateName('FlateDecode'));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
result := TPdfImage.CreateStream(nil);
|
||||||
|
with result do
|
||||||
|
try
|
||||||
|
|
||||||
|
with Attributes do
|
||||||
|
begin
|
||||||
|
AddItem('Type', TPdfName.CreateName('XObject'));
|
||||||
|
AddItem('Subtype', TPdfName.CreateName('Image'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Convert a LCL TGraphic into a TFPCustomImage
|
||||||
|
ConvertGraphicToFPImage(AImage, fpImg);
|
||||||
|
|
||||||
|
if fpImg.UsePalette and (fpImg.Palette.Count>0) then
|
||||||
|
begin
|
||||||
|
for y := 0 to fpImg.Height - 1 do
|
||||||
|
begin
|
||||||
|
new(pb);
|
||||||
|
for x := 0 to fpImg.Width-1 do
|
||||||
|
pb^[x] := fpImg.Pixels[x,y];
|
||||||
|
Stream.Write(pb^, fpImg.Width);
|
||||||
|
dispose(pb);
|
||||||
|
end;
|
||||||
|
Attributes.AddItem('ColorSpace', CreateIndexedColorArray(fpImg));
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
|
||||||
|
Alpha := CreateAlphaImage(AImage.Width, AImage.Height);
|
||||||
|
hasAlpha := false;
|
||||||
|
|
||||||
|
for y := 0 to fpImg.Height - 1 do
|
||||||
|
begin
|
||||||
|
new(pb);
|
||||||
|
for x := 0 to fpImg.Width-1 do
|
||||||
|
begin
|
||||||
|
aColor := fpImg.Colors[x,y];
|
||||||
|
z:=1;
|
||||||
|
pb^[ 0 ] := acolor.red shr 8;
|
||||||
|
pb^[ z ] := acolor.green shr 8;
|
||||||
|
pb^[ z+1 ] := 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);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if HasAlpha then begin
|
||||||
|
MaskImage := CreateMaskStream(Alpha);
|
||||||
|
if ObjectMgr<>nil then
|
||||||
|
ObjectMgr.AddObject(MaskImage);
|
||||||
|
Attributes.AddItem('SMask', MaskImage);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Alpha.Free;
|
||||||
|
|
||||||
|
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
||||||
|
end;
|
||||||
|
AddItems;
|
||||||
|
|
||||||
|
fpImg.Free;
|
||||||
|
|
||||||
|
except
|
||||||
|
result.free;
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ELSE}
|
||||||
|
|
||||||
function TPdfBitmapImage.CreateIndexedColorArray(ABitmap: TBitmap): TPdfArray;
|
function TPdfBitmapImage.CreateIndexedColorArray(ABitmap: TBitmap): TPdfArray;
|
||||||
var
|
var
|
||||||
{$IFNDEF USE_CLX}
|
{$IFNDEF USE_CLX}
|
||||||
@ -164,54 +262,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
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;
|
function TPdfBitmapImage.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
var
|
var
|
||||||
ABitmap: TBitmap;
|
ABitmap: TBitmap;
|
||||||
x, y: integer;
|
x, y: integer;
|
||||||
pb: PByteArray;
|
pb: PByteArray;
|
||||||
b: Byte;
|
b: Byte;
|
||||||
{$IFDEF LAZ_POWERPDF}
|
|
||||||
aIntfImage: TLazIntfImage;
|
|
||||||
aColor : TFPColor;
|
|
||||||
Alpha : TFPMemoryImage;
|
|
||||||
maskimage : TPDFImage;
|
|
||||||
hasAlpha : boolean;
|
|
||||||
{$endif}
|
|
||||||
|
|
||||||
{$IFDEF USE_CLX}
|
{$IFDEF USE_CLX}
|
||||||
const
|
const
|
||||||
PIXEL_COLOR_SIZE = 4;
|
PIXEL_COLOR_SIZE = 4;
|
||||||
@ -233,10 +289,6 @@ begin
|
|||||||
try
|
try
|
||||||
Assign(AImage);
|
Assign(AImage);
|
||||||
|
|
||||||
{$IFDEF FPC}
|
|
||||||
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 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}
|
||||||
@ -254,35 +306,15 @@ begin
|
|||||||
// translate TBitmap object to pdf image format.
|
// translate TBitmap object to pdf image format.
|
||||||
if PixelFormat = pf8bit then
|
if PixelFormat = pf8bit then
|
||||||
begin
|
begin
|
||||||
{$IFNDEF FPC}
|
|
||||||
for y := 0 to Height - 1 do
|
for y := 0 to Height - 1 do
|
||||||
begin
|
begin
|
||||||
pb := ScanLine[y];
|
pb := ScanLine[y];
|
||||||
Stream.Write(pb^, Width);
|
Stream.Write(pb^, Width);
|
||||||
{$ELSE}
|
|
||||||
for y := 0 to aintfimage.Height - 1 do
|
|
||||||
begin
|
|
||||||
new(pb);
|
|
||||||
|
|
||||||
for x := 0 to aintfimage.Width-1 do
|
|
||||||
begin
|
|
||||||
aColor := aIntfImage.Colors[x,y];
|
|
||||||
{ kleurwaarden worden als 16bits waarden opgeslagen, we kappen er
|
|
||||||
dus 8 van af.
|
|
||||||
red is willekeurig genomen
|
|
||||||
}
|
|
||||||
pb^[x] := acolor.red shr 8;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Stream.Write(pb^, Width);
|
|
||||||
dispose(pb);
|
|
||||||
{$ENDIF}
|
|
||||||
end;
|
end;
|
||||||
Attributes.AddItem('ColorSpace', CreateIndexedColorArray(ABitmap));
|
Attributes.AddItem('ColorSpace', CreateIndexedColorArray(ABitmap));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{$ifndef fpc}
|
|
||||||
for y := 0 to Height - 1 do
|
for y := 0 to Height - 1 do
|
||||||
begin
|
begin
|
||||||
pb := ScanLine[y];
|
pb := ScanLine[y];
|
||||||
@ -297,61 +329,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
Attributes.AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
||||||
end;
|
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);
|
|
||||||
for x := 0 to aintfimage.Width-1 do
|
|
||||||
begin
|
|
||||||
aColor := aIntfImage.Colors[x,y];
|
|
||||||
pb[ 0 ] := acolor.red shr 8;
|
|
||||||
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);
|
|
||||||
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;
|
end;
|
||||||
|
|
||||||
with Attributes do
|
with Attributes do
|
||||||
begin
|
begin
|
||||||
{$IFDEF FPC}
|
|
||||||
AddItem('Width', TPdfNumber.CreateNumber(aintfimage.Width));
|
|
||||||
AddItem('Height', TPdfNumber.CreateNumber(aintfimage.Height));
|
|
||||||
{$ELSE}
|
|
||||||
AddItem('Width', TPdfNumber.CreateNumber(abitmap.Width));
|
AddItem('Width', TPdfNumber.CreateNumber(abitmap.Width));
|
||||||
AddItem('Height', TPdfNumber.CreateNumber(abitmap.Height));
|
AddItem('Height', TPdfNumber.CreateNumber(abitmap.Height));
|
||||||
{$ENDIF}
|
|
||||||
AddItem('BitsPerComponent', TPdfNumber.CreateNumber(8));
|
AddItem('BitsPerComponent', TPdfNumber.CreateNumber(8));
|
||||||
if USE_ZLIB then
|
if USE_ZLIB then
|
||||||
PdfArrayByName('Filter').AddItem(TPdfName.CreateName('FlateDecode'));
|
PdfArrayByName('Filter').AddItem(TPdfName.CreateName('FlateDecode'));
|
||||||
@ -359,15 +342,12 @@ begin
|
|||||||
finally
|
finally
|
||||||
Free;
|
Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$IFDEF FPC}
|
|
||||||
aIntfImage.Free();
|
|
||||||
{$ENDIF}
|
|
||||||
except
|
except
|
||||||
result.Free;
|
result.Free;
|
||||||
raise;
|
raise;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
{$IFDEF LAZ_POWERPDF}
|
{$IFDEF LAZ_POWERPDF}
|
||||||
|
@ -27,10 +27,12 @@ interface
|
|||||||
uses
|
uses
|
||||||
SysUtils, Classes, Graphics, PdfTypes, PdfDoc, PdfImages
|
SysUtils, Classes, Graphics, PdfTypes, PdfDoc, PdfImages
|
||||||
{$IFDEF LAZ_POWERPDF}
|
{$IFDEF LAZ_POWERPDF}
|
||||||
|
,FPImage, FPReadJPEG, PdfImageLazTools
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
,JPEG
|
,JPEG
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
;
|
;
|
||||||
|
|
||||||
type
|
type
|
||||||
{ TPdfJpegImage }
|
{ TPdfJpegImage }
|
||||||
TPdfJpegImage = class(TPdfImageCreator)
|
TPdfJpegImage = class(TPdfImageCreator)
|
||||||
@ -41,7 +43,48 @@ type
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
// CreateImage
|
// CreateImage
|
||||||
|
|
||||||
|
{$IFDEF LAZ_POWERPDF}
|
||||||
function TPdfJpegImage.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
function TPdfJpegImage.CreateImage(AImage: TGraphic; ObjectMgr: TPdfObjectMgr=nil): TPdfImage;
|
||||||
|
var
|
||||||
|
fpImg: TFPCustomImage;
|
||||||
|
begin
|
||||||
|
// check whether specified graphic is valid image.
|
||||||
|
if not (AImage is TJpegImage) then
|
||||||
|
raise EPdfInvalidValue.Create('only jpeg image is allowed.');
|
||||||
|
|
||||||
|
result := TPdfImage.CreateStream(nil);
|
||||||
|
try
|
||||||
|
ConvertGraphicToFPImage(AImage, fpImg);
|
||||||
|
|
||||||
|
TJpegImage(AImage).SaveToStream(result.Stream);
|
||||||
|
|
||||||
|
with result.Attributes do
|
||||||
|
begin
|
||||||
|
AddItem('Type', TPdfName.CreateName('XObject'));
|
||||||
|
AddItem('Subtype', TPdfName.CreateName('Image'));
|
||||||
|
if TJPegImage(AImage).GrayScale then
|
||||||
|
AddItem('ColorSpace', TPdfName.CreateName('DeviceGray'))
|
||||||
|
else
|
||||||
|
AddItem('ColorSpace', TPdfName.CreateName('DeviceRGB'));
|
||||||
|
AddItem('Width', TPdfNumber.CreateNumber(fpImg.Width));
|
||||||
|
AddItem('Height', TPdfNumber.CreateNumber(fpImg.Height));
|
||||||
|
AddItem('BitsPerComponent', TPdfNumber.CreateNumber(8));
|
||||||
|
PdfArrayByName('Filter').AddItem(TPdfName.CreateName('DCTDecode'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
fpImg.Free;
|
||||||
|
|
||||||
|
except
|
||||||
|
result.Free;
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ELSE}
|
||||||
|
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
|
||||||
@ -70,6 +113,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
|
@ -283,6 +283,7 @@ type
|
|||||||
|
|
||||||
EPdfInvalidValue = class(Exception);
|
EPdfInvalidValue = class(Exception);
|
||||||
EPdfInvalidOperation = class(Exception);
|
EPdfInvalidOperation = class(Exception);
|
||||||
|
EPdfInvalidImageFormat = class(Exception);
|
||||||
|
|
||||||
{*
|
{*
|
||||||
* utility functions.
|
* utility functions.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<CONFIG>
|
<CONFIG>
|
||||||
<Package Version="4">
|
<Package Version="5">
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<Name Value="pack_powerpdf"/>
|
<Name Value="pack_powerpdf"/>
|
||||||
<Type Value="RunAndDesignTime"/>
|
<Type Value="RunAndDesignTime"/>
|
||||||
@ -21,8 +21,8 @@
|
|||||||
<CustomOptions Value="-dLAZ_POWERPDF"/>
|
<CustomOptions Value="-dLAZ_POWERPDF"/>
|
||||||
</Other>
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Version Minor="9" Release="15"/>
|
<Version Minor="9" Release="16"/>
|
||||||
<Files Count="12">
|
<Files Count="13">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="PdfTypes.pas"/>
|
<Filename Value="PdfTypes.pas"/>
|
||||||
<UnitName Value="PdfTypes"/>
|
<UnitName Value="PdfTypes"/>
|
||||||
@ -72,7 +72,12 @@
|
|||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
<UnitName Value="PowerPdf"/>
|
<UnitName Value="PowerPdf"/>
|
||||||
</Item12>
|
</Item12>
|
||||||
|
<Item13>
|
||||||
|
<Filename Value="PdfImageLazTools.pas"/>
|
||||||
|
<UnitName Value="PdfImageLazTools"/>
|
||||||
|
</Item13>
|
||||||
</Files>
|
</Files>
|
||||||
|
<CompatibilityMode Value="True"/>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
<PackageName Value="LCL"/>
|
<PackageName Value="LCL"/>
|
||||||
@ -87,7 +92,6 @@
|
|||||||
</UsageOptions>
|
</UsageOptions>
|
||||||
<PublishOptions>
|
<PublishOptions>
|
||||||
<Version Value="2"/>
|
<Version Value="2"/>
|
||||||
<IgnoreBinaries Value="False"/>
|
|
||||||
</PublishOptions>
|
</PublishOptions>
|
||||||
</Package>
|
</Package>
|
||||||
</CONFIG>
|
</CONFIG>
|
||||||
|
@ -10,7 +10,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
PdfTypes, PdfDoc, PdfJpCMap, PdfJPFonts, PdfGBFonts, PdfFonts, PdfImages,
|
PdfTypes, PdfDoc, PdfJpCMap, PdfJPFonts, PdfGBFonts, PdfFonts, PdfImages,
|
||||||
PReport, PdfJpegImage, PRJpegImage, PRAnnotation, PowerPdf,
|
PReport, PdfJpegImage, PRJpegImage, PRAnnotation, PowerPdf,
|
||||||
LazarusPackageIntf;
|
PdfImageLazTools, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user