📄 frxexportimage.pas
字号:
{******************************************}
{ }
{ FastReport v4.0 }
{ BMP, JPEG, TIFF, GIF export filters }
{ }
{ Copyright (c) 1998-2008 }
{ by Alexander Fediachov, }
{ Fast Reports Inc. }
{ }
{******************************************}
unit frxExportImage;
interface
{$I frx.inc}
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, frxClass, Jpeg
{$IFDEF Delphi6}
, Variants
{$ENDIF};
procedure GIFSaveToStream(const Stream: TStream; const Bitmap: TBitmap);
procedure GIFSaveToFile(const FileName: String; const Bitmap: TBitmap);
type
TfrxCustomImageExport = class(TfrxCustomExportFilter)
private
FBitmap: TBitmap;
FCrop: Boolean;
FCurrentPage: Integer;
FJPEGQuality: Integer;
FMaxX: Integer;
FMaxY: Integer;
FMinX: Integer;
FMinY: Integer;
FMonochrome: Boolean;
FResolution: Integer;
FCurrentRes: Integer;
FSeparate: Boolean;
FYOffset: Integer;
FFileSuffix: String;
FFirstPage: Boolean;
FExportNotPrintable: Boolean;
function SizeOverflow(const Val: Extended): Boolean;
protected
FDiv: Extended;
procedure Save; virtual;
procedure FinishExport; virtual;
public
constructor Create(AOwner: TComponent); override;
function ShowModal: TModalResult; override;
function Start: Boolean; override;
procedure Finish; override;
procedure FinishPage(Page: TfrxReportPage; Index: Integer); override;
procedure StartPage(Page: TfrxReportPage; Index: Integer); override;
procedure ExportObject(Obj: TfrxComponent); override;
property JPEGQuality: Integer read FJPEGQuality write FJPEGQuality default 90;
property CropImages: Boolean read FCrop write FCrop default False;
property Monochrome: Boolean read FMonochrome write FMonochrome default False;
property Resolution: Integer read FResolution write FResolution;
property SeparateFiles: Boolean read FSeparate write FSeparate;
property ExportNotPrintable: Boolean read FExportNotPrintable write FExportNotPrintable;
property OverwritePrompt;
end;
TfrxEMFExport = class(TfrxCustomImageExport)
private
FMetafile: TMetafile;
FMetafileCanvas: TMetafileCanvas;
protected
procedure FinishExport; override;
public
function Start: Boolean; override;
procedure StartPage(Page: TfrxReportPage; Index: Integer); override;
procedure ExportObject(Obj: TfrxComponent); override;
constructor Create(AOwner: TComponent); override;
class function GetDescription: String; override;
published
property CropImages;
property OverwritePrompt;
end;
TfrxBMPExport = class(TfrxCustomImageExport)
protected
procedure Save; override;
public
constructor Create(AOwner: TComponent); override;
class function GetDescription: String; override;
published
property CropImages;
property Monochrome;
property OverwritePrompt;
end;
TfrxTIFFExport = class(TfrxCustomImageExport)
private
procedure SaveTiffToStream(const Stream: TStream; const Bitmap: TBitmap);
protected
procedure Save; override;
public
constructor Create(AOwner: TComponent); override;
class function GetDescription: String; override;
published
property CropImages;
property Monochrome;
property OverwritePrompt;
end;
TfrxJPEGExport = class(TfrxCustomImageExport)
protected
procedure Save; override;
public
constructor Create(AOwner: TComponent); override;
class function GetDescription: String; override;
published
property JPEGQuality;
property CropImages;
property Monochrome;
property OverwritePrompt;
end;
TfrxGIFExport = class(TfrxCustomImageExport)
protected
procedure Save; override;
public
constructor Create(AOwner: TComponent); override;
class function GetDescription: String; override;
published
property CropImages;
property Monochrome;
property OverwritePrompt;
end;
TfrxIMGExportDialog = class(TForm)
OK: TButton;
Cancel: TButton;
GroupPageRange: TGroupBox;
GroupBox1: TGroupBox;
CropPage: TCheckBox;
Label2: TLabel;
Quality: TEdit;
Mono: TCheckBox;
SaveDialog1: TSaveDialog;
DescrL: TLabel;
AllRB: TRadioButton;
CurPageRB: TRadioButton;
PageNumbersRB: TRadioButton;
PageNumbersE: TEdit;
Label1: TLabel;
Resolution: TEdit;
SeparateCB: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure PageNumbersEChange(Sender: TObject);
procedure PageNumbersEKeyPress(Sender: TObject; var Key: Char);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
FFilter: TfrxCustomImageExport;
procedure SetFilter(const Value: TfrxCustomImageExport);
public
property Filter: TfrxCustomImageExport read FFilter write SetFilter;
end;
implementation
uses frxUtils, frxFileUtils, frxRes, frxrcExports;
{$R *.dfm}
type
PDirEntry = ^TDirEntry;
TDirEntry = record
_Tag: Word;
_Type: Word;
_Count: LongInt;
_Value: LongInt;
end;
const
EMF_DIV = 0.911;
TifHeader: array[0..7] of Byte = (
$49, $49, $2A, $00, $08, $00, $00, $00);
MAX_TBITMAP_HEIGHT = 30000;
MAXBITSCODES = 12;
HSIZE = 5003;
NullString: array[0..3] of Byte = ($00, $00, $00, $00);
Software: array[0..9] of AnsiChar = ('F', 'a', 's', 't', 'R', 'e', 'p', 'o', 'r', 't');
code_mask: array [0..16] of cardinal = ($0000, $0001, $0003, $0007, $000F,
$001F, $003F, $007F, $00FF, $01FF, $03FF, $07FF, $0FFF,
$1FFF, $3FFF, $7FFF, $FFFF);
BitsPerSample: array[0..2] of Word = ($0008, $0008, $0008);
D_BW_C: array[0..13] of TDirEntry = (
(_Tag: $00FE; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0100; _Type: $0003; _Count: $00000001; _Value: $00000000),
(_Tag: $0101; _Type: $0003; _Count: $00000001; _Value: $00000000),
(_Tag: $0102; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0103; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0106; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0111; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0115; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0116; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0117; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $011A; _Type: $0005; _Count: $00000001; _Value: $00000000),
(_Tag: $011B; _Type: $0005; _Count: $00000001; _Value: $00000000),
(_Tag: $0128; _Type: $0003; _Count: $00000001; _Value: $00000002),
(_Tag: $0131; _Type: $0002; _Count: $0000000A; _Value: $00000000));
D_COL_C: array[0..14] of TDirEntry = (
(_Tag: $00FE; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0100; _Type: $0003; _Count: $00000001; _Value: $00000000),
(_Tag: $0101; _Type: $0003; _Count: $00000001; _Value: $00000000),
(_Tag: $0102; _Type: $0003; _Count: $00000001; _Value: $00000008),
(_Tag: $0103; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0106; _Type: $0003; _Count: $00000001; _Value: $00000003),
(_Tag: $0111; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0115; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0116; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0117; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $011A; _Type: $0005; _Count: $00000001; _Value: $00000000),
(_Tag: $011B; _Type: $0005; _Count: $00000001; _Value: $00000000),
(_Tag: $0128; _Type: $0003; _Count: $00000001; _Value: $00000002),
(_Tag: $0131; _Type: $0002; _Count: $0000000A; _Value: $00000000),
(_Tag: $0140; _Type: $0003; _Count: $00000300; _Value: $00000008));
D_RGB_C: array[0..14] of TDirEntry = (
(_Tag: $00FE; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0100; _Type: $0003; _Count: $00000001; _Value: $00000000),
(_Tag: $0101; _Type: $0003; _Count: $00000001; _Value: $00000000),
(_Tag: $0102; _Type: $0003; _Count: $00000003; _Value: $00000008),
(_Tag: $0103; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0106; _Type: $0003; _Count: $00000001; _Value: $00000002),
(_Tag: $0111; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0115; _Type: $0003; _Count: $00000001; _Value: $00000003),
(_Tag: $0116; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $0117; _Type: $0004; _Count: $00000001; _Value: $00000000),
(_Tag: $011A; _Type: $0005; _Count: $00000001; _Value: $00000000),
(_Tag: $011B; _Type: $0005; _Count: $00000001; _Value: $00000000),
(_Tag: $011C; _Type: $0003; _Count: $00000001; _Value: $00000001),
(_Tag: $0128; _Type: $0003; _Count: $00000001; _Value: $00000002),
(_Tag: $0131; _Type: $0002; _Count: $0000000A; _Value: $00000000));
{ TfrxCustomImageExport }
constructor TfrxCustomImageExport.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCrop := True;
FJPEGQuality := 90;
FResolution := 96;
FSeparate := True;
FExportNotPrintable := False;
CropImages := False;
end;
function TfrxCustomImageExport.ShowModal: TModalResult;
begin
with TfrxIMGExportDialog.Create(nil) do
begin
Filter := Self;
Quality.Text := IntToStr(FJPEGQuality);
CropPage.Checked := FCrop;
Mono.Checked := FMonochrome;
Quality.Enabled := Self is TfrxJPEGExport;
Mono.Enabled := not (Self is TfrxGIFExport);
Resolution.Text := IntToStr(FResolution);
if OverwritePrompt then
SaveDialog1.Options := SaveDialog1.Options + [ofOverwritePrompt];
if SlaveExport then
begin
SeparateCB.Checked := False;
SeparateCB.Visible := False;
end
else
SeparateCB.Checked := FSeparate;
if (FileName = '') and (not SlaveExport) then
SaveDialog1.FileName := ChangeFileExt(ExtractFileName(frxUnixPath2WinPath(Report.FileName)), SaveDialog1.DefaultExt)
else
SaveDialog1.FileName := FileName;
if PageNumbers <> '' then
begin
PageNumbersE.Text := PageNumbers;
PageNumbersRB.Checked := True;
end;
Result := ShowModal;
if Result = mrOk then
begin
FJPEGQuality := StrToInt(Quality.Text);
FCrop := CropPage.Checked;
FMonochrome := Mono.Checked;
FResolution := StrToInt(Resolution.Text);
FSeparate := SeparateCB.Checked;
PageNumbers := '';
CurPage := False;
if CurPageRB.Checked then
CurPage := True
else if PageNumbersRB.Checked then
PageNumbers := PageNumbersE.Text;
if not SlaveExport then
begin
if DefaultPath <> '' then
SaveDialog1.InitialDir := DefaultPath;
if SaveDialog1.Execute then
FileName := SaveDialog1.FileName else
Result := mrCancel
end;
end;
Free;
end;
end;
function TfrxCustomImageExport.Start: Boolean;
begin
if SlaveExport then
begin
if Report.FileName <> '' then
FileName := ChangeFileExt(GetTemporaryFolder + ExtractFileName(Report.FileName), DefaultExt)
else
FileName := ChangeFileExt(GetTempFile, DefaultExt);
FSeparate := False;
end;
CurPage := False;
FCurrentPage := 0;
FYOffset := 0;
if not FSeparate then
begin
FBitmap := TBitmap.Create;
FCurrentRes := FBitmap.Canvas.Font.PixelsPerInch;
FDiv := FResolution / FCurrentRes;
FBitmap.Canvas.Brush.Color := clWhite;
FBitmap.Monochrome := Monochrome;
FMaxX := 0;
FMaxY := 0;
FFirstPage := True;
end;
Result := (FileName <> '') or (Stream <> nil);
if (ExtractFilePath(FileName) = '') and (DefaultPath <> '') then
FileName := DefaultPath + '\' + FileName;
end;
procedure TfrxCustomImageExport.StartPage(Page: TfrxReportPage; Index: Integer);
var
i: Extended;
begin
Inc(FCurrentPage);
if FSeparate then
begin
FBitmap := TBitmap.Create;
FCurrentRes := FBitmap.Canvas.Font.PixelsPerInch;
FDiv := FResolution / FCurrentRes;
FBitmap.Canvas.Brush.Color := clWhite;
FBitmap.Monochrome := Monochrome;
FBitmap.Width := Round(Page.Width * FDiv);
FBitmap.Height := Round(Page.Height * FDiv);
FMaxX := 0;
FMaxY := 0;
FMinX := FBitmap.Width;
FMinY := FBitmap.Height;
end else
begin
if FFirstpage then
begin
if FBitmap.Width < Round(Page.Width * FDiv) then
FBitmap.Width := Round(Page.Width * FDiv);
i := Page.Height * Report.PreviewPages.Count * FDiv;
if SizeOverflow(i) then
i := MAX_TBITMAP_HEIGHT;
FBitmap.Height := Round(i);
FFirstPage := False;
FMinX := FBitmap.Width;
FMinY := FBitmap.Height;
end;
end;
end;
procedure TfrxCustomImageExport.ExportObject(Obj: TfrxComponent);
var
z: Integer;
begin
if (Obj is TfrxView) and (FExportNotPrintable or TfrxView(Obj).Printable) then
begin
if Obj.Name <> '_pagebackground' then
begin
z := Round(Obj.AbsLeft * FDiv);
if z < FMinX then
FMinX := z;
z := FYOffset + Round(Obj.AbsTop * FDiv);
if z < FMinY then
FMinY := z;
z := Round((Obj.AbsLeft + Obj.Width) * FDiv) + 1;
if z > FMaxX then
FMaxX := z;
z := FYOffset + Round((Obj.AbsTop + Obj.Height) * FDiv) + 1;
if z > FMaxY then
FMaxY := z;
end;
TfrxView(Obj).Draw(FBitmap.Canvas, FDiv, FDiv, 0, FYOffset);
end;
end;
procedure TfrxCustomImageExport.FinishPage(Page: TfrxReportPage; Index: Integer);
begin
if FSeparate then
FinishExport
else
FYOffset := FYOffset + Round(Page.Height * FDiv);
end;
procedure TfrxCustomImageExport.Finish;
begin
if not FSeparate then
FinishExport;
end;
procedure TfrxCustomImageExport.Save;
begin
if FSeparate then
FFileSuffix := '.' + IntToStr(FCurrentPage)
else
FFileSuffix := '';
end;
procedure TfrxCustomImageExport.FinishExport;
var
RFrom, RTo: TRect;
begin
try
if FCrop then
begin
RFrom := Rect(FMinX, FMinY, FMaxX, FMaxY);
RTo := Rect(0, 0, FMaxX - FMinX, FMaxY - FMinY);
FBitmap.Canvas.CopyRect(RTo, FBitmap.Canvas, RFrom);
FBitmap.Width := FMaxX - FMinX;
FBitmap.Height := FMaxY - FMinY;
end;
Save;
finally
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -