BSOne.SFC/EM.Lib/ImageEn_SRC/Source/iemio.pas

5620 lines
188 KiB
Plaintext

(* ImageEn Build 7.0.0.06.2637 @ 7-4-17 14:58:42.679 *)
(*
Copyright (c) 1998-2017 by Carlotta Calandra. All rights reserved.
Copyright (c) 2011-2017 by Xequte Software.
This software comes without express or implied warranty.
In no case shall the author be liable for any damage or unwanted behavior of any
computer hardware and/or software.
Author grants you the right to include the component
in your application, whether COMMERCIAL, SHAREWARE, or FREEWARE.
ImageEn, IEvolution and ImageEn ActiveX may not be included in any
commercial, shareware or freeware libraries or components.
www.ImageEn.com
*)
(*
File version 1040
Doc revision 1001
*)
unit iemio;
{$R-}
{$Q-}
{$I ie.inc}
{$IFDEF IEINCLUDEMULTIVIEW}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Printers,
{$ifdef IEHASUITYPES} System.UITypes, {$endif}
ImageEnView, ImageEnProc, ExtCtrls, hyiedefs, ImageEnIO, ieview, hyieutils,
{$IFDEF IEINCLUDEIEXACQUIRE}
ietwain, iexAcquire, iexDCIM, iewia,
{$ENDIF}
iexBitmaps, pcxfilter;
const
IEM_SELECTED_IMAGES = -9; // Quick reference to all selected images in the TImageEnMView
IEM_ALL_IMAGES = -7; // Quick reference to all images in the TImageEnMView
type
{!!
<FS>TImageEnMIO
<FM>Description<FN>
TImageEnMIO provides input/output support to ImageEn when working with images containing multiple frames (TIFF, GIF, DICOM, AVI, etc):
- <L TImageEnMIO.LoadFromFile>Loading</L> and <L TImageEnMIO.SaveToFile>saving</L> multi-frame images
- Access to <L TImageEnMIO.Params>image properties and meta-data</L>
- <L TImageEnMIO.Acquire>Acquisition</L> of multiple images from cameras and scanners
- <L TImageEnMIO.DoPrintPreviewDialog>Printing</L> of thumbnails and images
ImageEn supports loading and saving multiple frames from GIF, TIFF, AVI, DCX, DICOM and ICO formats. It can also load from CUR format, and save to PDF and PS format (loading of PDF is supported if a <L TImageEnMIO.LoadFromFilePDF>relevant plug-in</L> is installed).
Generally you will not add a TImageEnMIO component directly to your project. It is accessed via the following methods:
<FM>1. Using the <A TImageEnMView.MIO> property of a <A TImageEnMView><FN>
ImageEnMView1.MIO.LoadFromFile('C:\MyImage.tiff');
ImageEnMView1.MIO.DoPrintPreviewDialog;
<FM>2. Attached to a <A TIEMultiBitmap> in code<FN>
MyMBitmap := TIEMultiBitmap.create;
AnImageEnMIO := TImageEnMIO.CreateFromIEMBitmap(MyMBitmap);
AnImageEnMIO.LoadFromFile('C:\input.gif');
...
AnImageEnMIO.Free;
MyMBitmap.Free;
<FM>Notes<FN>
- Ensure you do not call any TImageEnMIO methods before it is actually attached to an image container (<A TImageEnMView>, <A TIEMultiBitmap>, etc)
- Users often attach a <A TImageEnIO> component to <A TImageEnMView> component. This is not correct. The TImageEnMIO component must be attached only to a <A TImageEnMView> component.
See also <A TImageEnIO>, which works with single-frame images, such as JPEG, BMP, etc.
<FM>Methods and Properties<FN>
<FI>Connected Component<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.AttachedIEMBitmap></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.AttachedMView></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.CreateFromIEMBitmap></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.IEMBitmap></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.Update></C> </R>
</TABLE>
<FI>Generic Input/Output<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.Aborting></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.AllowMalformedPages></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.AutoAdjustDPI></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.DefaultDitherMethod></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.DuplicateCompressionInfo></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.ExecuteOpenDialog></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.ExecuteSaveDialog></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.FilteredAdjustDPI></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromBuffer></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileAuto></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFiles></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStream></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromURL></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.NativePixelFormat></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.Params></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.ParamsCount></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ParamsFromBuffer></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ParamsFromFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ParamsFromStream></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStream></C> </R>
</TABLE>
<FI>Dialogs<FN>
<TABLE2>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.DialogsMeasureUnit></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.DoPreviews></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.PreviewFont></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.PreviewFontEnabled></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.PreviewsParams></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnMIO.SimplifiedParamsDialogs></C> </R>
</TABLE>
<FI>Image Acquisition (Twain/WIA)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.Acquire></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SelectAcquireSource></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.SelectedAcquireSource></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SetAcquireSource></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.AcquireParams></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.DCIMParams></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.TwainParams></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.TwainAcquireOpen></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.TwainAcquireClose></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.WIAParams></C> </R>
</TABLE>
<FI>Printing<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.DoPrintPreviewDialog></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.PrintImage></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.PrintImagePos></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.PrintImages></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.PrintImagesToFile></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.PrintingFilterOnSubsampling></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnMIO.PrintPreviewParams></C> </R>
</TABLE>
<FI>AVI Videos<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileAVI></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFileAVI></C> </R>
</TABLE>
<FI>Cursor Resources (CUR)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileCUR></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStreamCUR></C> </R>
</TABLE>
<FI>DCX (Multipage PCX)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileDCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStreamDCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFileDCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStreamDCX></C> </R>
</TABLE>
<FI>GIF<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStreamGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFileGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStreamGIF></C> </R>
</TABLE>
<FI>Icons (ICO)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileICO></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStreamICO></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFileICO></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStreamICO></C> </R>
</TABLE>
<FI>TIFF<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStreamTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFileTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStreamTIFF></C> </R>
</TABLE>
<FI>DirectShow Media Files<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromMediaFile></C> </R>
</TABLE>
<FI>Adobe PDF<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFilePDF> (Requires Plug-In)</C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStreamPDF> (Requires Plug-In)</C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFilePDF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStreamPDF></C> </R>
</TABLE>
<FI>PostScript (PS)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFilePS></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStreamPS></C> </R>
</TABLE>
<FI>DICOM Medical Imaging Format<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromFileDICOM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.LoadFromStreamDICOM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToFileDICOM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnMIO.SaveToStreamDICOM></C> </R>
</TABLE>
<FM>Events<FN>
<TABLE2>
<R> <C_IMG_EVENT> <C><A TImageEnMIO.OnAcquireBitmap></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnMIO.OnAcquireClose></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnMIO.OnAfterAcquireBitmap></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnMIO.OnDoPreviews></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnMIO.OnFinishWork></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnMIO.OnProgress></C> </R>
</TABLE>
!!}
{$ifdef IEHASPLATFORMATTRIBUTE}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$endif}
TImageEnMIO = class(TComponent)
private
{ Private declarations }
fImageEnMView: TIEView;
fImageEnMViewBitmapChangeHandle: pointer; // bitmap change handler (nil=none)
fIEMBitmap: TIECustomMultiBitmap;
fIEMBitmapCreated: boolean; // true is fIEMBitmap is created by TImageEnMIO
fSimplifiedParamsDialogs: boolean;
{$IFDEF IEINCLUDEIEXACQUIRE}
fAcquireParams : TIEAcquireParams;
fTwainParams: TIETwainParams;
fWIA: TIEWia;
{$ENDIF}
{$IFDEF IEINCLUDEWPD}
fDCIMParams : TIEDcimAcquire;
{$ENDIF}
fPreviewsParams: TIOPreviewsParams;
fPreviewFont: TFont;
fPreviewFontEnabled: Boolean;
{$IFDEF IEINCLUDEIEXACQUIRE}
fTwainNextToInsert: integer; // index of next image to insert (twain multipage acq.)
{$ENDIF}
fAutoAdjustDPI: boolean;
fFilteredAdjustDPI: boolean;
fDefaultDitherMethod: TIEDitherMethod;
fResetPrinter: boolean;
fDialogsMeasureUnit: TIEDialogsMeasureUnit;
fNativePixelFormat: boolean;
fPrintingFilterOnSubsampling: TResampleFilter;
fOnDoPreviews: TIEDoPreviewsEvent;
fLoadingFileName: string; // used when a LoadFromFile calls LoadFromStream to fill Params.FileName
fLastFilename : string; // the last file we loaded using LoadFromFile
fAllowMalformedPages: boolean;
// Twain modeless
fgrec: pointer;
// proxy settings
{$IFDEF IEINCLUDEPRINTDIALOGS}
fPrintPreviewParams: TIOPrintPreviewParams;
{$ENDIF}
//
procedure SetAttachedMView(v: TIEView);
function GetIEMBitmap: TIECustomMultiBitmap;
procedure SetIEMBitmap(mbmp: TIECustomMultiBitmap);
procedure SetAttachedIEMBitmap(mbmp: TIECustomMultiBitmap);
function GetParams(idx: integer): TIOParams;
procedure SetPreviewFont(f: TFont);
procedure SetPreviewFontEnabled(Value: Boolean);
function GetParamsCount: integer;
procedure SetIOPreviewParams(v: TIOPreviewsParams);
function GetIOPreviewParams: TIOPreviewsParams;
procedure PrintImagesEx(PrtCanvas: TCanvas; dpix, dpiy: integer; pagewidth, pageheight: double; bPreview: Boolean; Columns: integer; Rows: integer; HorizSpace: double; VertSpace: double; PrintSelected: boolean; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; DrawBox: boolean; DrawText: boolean; DrawShadow: boolean; BoxColor: TColor = clBlack; iPageNo : Integer = 0);
function GetImageEnVersion: string;
procedure SetImageEnVersion(Value: string);
procedure SetAborting(Value: Boolean);
procedure fImageEnMView_LockPaint;
procedure fImageEnMView_UnlockPaint;
function NextInsertionIndex() : Integer;
procedure Attached_InsertImage(idx: Integer);
procedure Attached_DeleteImage(idx: Integer);
procedure Attached_SetIEBitmap(idx: Integer; bmp: TIEBaseBitmap);
procedure Attached_CopyToIEBitmap(idx: Integer; bmp: TIEBitmap);
function Attached_GetTIEBitmap(idx: Integer): TIEBitmap;
procedure Attached_ReleaseBitmap(idx: Integer; SaveChanges: Boolean = True);
function IsAttached: Boolean;
function GetParamsList: TIOMultiParams;
function ParamsFromFileOrStream(const FileName: WideString; Stream: TStream; Format: TIOFileType): Boolean;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-08)
function GetProxyAddress: WideString;
function GetProxyUser: WideString;
function GetProxyPassword: WideString;
procedure SetProxyAddress(Value: WideString);
procedure SetProxyUser(Value: WideString);
procedure SetProxyPassword(Value: WideString);
{$ENDIF}
protected
{ Protected declarations }
fAborting: boolean;
fOnProgress: TIEProgressEvent;
fOnAcquireBitmap: TIEAcquireBitmapEvent;
fOnAcquireClose: TNotifyEvent;
fOnAfterAcquireBitmap: TIEAfterAcquireBitmapEvent;
fOnFinishWork: TNotifyEvent;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure OnBitmapChange(Sender: TObject; destroying: boolean);
procedure UpdateAttachedBitmapParams(Sender : TObject; Operation: Integer; Idx : integer; ExtraParam: Integer);
procedure DoFinishWork; virtual;
procedure CheckDPI(p: TIOParams);
{$ifdef IEINCLUDEIEXACQUIRE}
procedure TWMultiCallBack(Bitmap: TIEBitmap; var IOParams: TObject; ImDpiX, ImDpiY: integer); virtual;
procedure TWCloseCallBack; virtual;
function GetWIAParams: TIEWia; virtual;
function WiaOnProgress(Percentage: integer): boolean;
function GetSelectedAcquireSource : TIEAcquireSource;
{$endif}
public
{ Public declarations }
fParamsList : TIOMultiParams; // IO params of all images
constructor Create(Owner: TComponent); override;
constructor CreateFromIEMBitmap(MBitmap: TIECustomMultiBitmap);
destructor Destroy; override;
procedure Update;
{!!
<FS>TImageEnMIO.DefaultDitherMethod
<FM>Declaration<FC>
property DefaultDitherMethod: <A TIEDitherMethod>;
<FM>Description<FN>
Specifies the dithering method to apply when a color image needs to be converted to black/white.
Default: ieThreshold
!!}
property DefaultDitherMethod: TIEDitherMethod read fDefaultDitherMethod write fDefaultDitherMethod;
// Other
property Params[idx: integer]: TIOParams read GetParams;
property ParamsCount: integer read GetParamsCount;
procedure DuplicateCompressionInfo;
property IEMBitmap: TIECustomMultiBitmap read GetIEMBitmap write SetIEMBitmap;
// The last file that was loaded using LoadFromFile, etc.
property LastFilename : string read fLastFilename;
{!!
<FS>TImageEnMIO.AllowMalformedPages
<FM>Declaration<FC>
property AllowMalformedPages: boolean;
<FM>Description<FN>
If true, malformed pages (due to loading a corrupted or non-standard TIFF) will be loaded (where possible).
Default: False (loading is aborted if malformed page is encountered)
!!}
property AllowMalformedPages: boolean read fAllowMalformedPages write fAllowMalformedPages;
{$IFDEF IEINCLUDEDIALOGIO}
function DoPreviews(idx: integer; pp: TPreviewParams = [ppAll]): boolean;
{$ENDIF}
{!!
<FS>TImageEnMIO.AcquireParams
<FM>Declaration<FC>
property AcquireParams : <A TIEAcquireParams>;
<FM>Description<FN>
AcquireParams is a powerful interface that provides generic access to all image acquistion APIs: Twain, WIA and Portable Devices (WPD). AcquireParams accesses <A TImageEnMIO.TwainParams>, <A TImageEnMIO.WIAParams> and <A TImageEnMIO.DCIMParams>.
If you have called <A TImageEnMIO.SelectAcquireSource> or <A TImageEnMIO.Acquire> then you can access common parameters for the device without having to know the <L TIEAcquireApi>API</L>
See the <FC>TIEAcquireParams<FN> object for more details.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\AllAcquire\AllAcquire.dpr </C> </R>
</TABLE>
!!}
{$IFDEF IEINCLUDEIEXACQUIRE}
property AcquireParams: TIEAcquireParams read fAcquireParams;
{$ENDIF}
{!!
<FS>TImageEnMIO.TwainParams
<FM>Declaration<FC>
property TwainParams: <A TIETwainParams>;
<FM>Description<FN>
TwainParams provides access to properties for acquisition from Twain scanners and cameras. You can enable/disable the standard user interface, set pixeltype (Grayscale, RGB...), DPI, etc.
Note: Use TwainParams only when you need access to Twain specific parameters and functionality (when <A TImageEnMIO.SelectedAcquireSource>.Api is ieaTwain). For generic access to all image acquisitions sources (Twain, WIA, etc.) use <A TImageEnMIO.AcquireParams> instead.
<FM>Example<FC>
// Acquire a black/white (1bit) image from the default Twain device
ImageEnMView1.MIO.TwainParams.PixelType.CurrentValue := 0;
If ImageEnMView1.MIO.SetSource(ieaTwain, Default_Device) then
ImageEnMView1.MIO.Acquire;
<FM>See Also<FN>
- <A TIETwainParams>
- <A TImageEnMIO.AcquireParams>
- <A TImageEnMIO.SelectedAcquireSource>
!!}
{$IFDEF IEINCLUDEIEXACQUIRE}
property TwainParams: TIETwainParams read fTwainParams;
{$ENDIF}
{!!
<FS>TImageEnMIO.DCIMParams
<FM>Declaration<FC>
property DCIMParams: <A TIEDcimAcquire>;
<FM>Description<FN>
Use the DCIMParams property to handle retrieval of images from camera cards and connected devices (using the Windows Portable Devices API).
Note: Use DCIMParams only when you need access to DCIM specific functionality (when <A TImageEnMIO.SelectedAcquireSource>.Api is ieaDCIM). For generic access to all image acquisitions sources (Twain, WIA, etc.) use <A TImageEnMIO.AcquireParams> instead.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\Twain\TwainDemo.dpr </C> </R>
</TABLE>
<FM>See Also<FN>
- <A TIEDcimAcquire>
- <A TImageEnMIO.AcquireParams>
- <A TImageEnMIO.SelectedAcquireSource>
!!}
{$IFDEF IEINCLUDEWPD}
property DCIMParams: TIEDcimAcquire read fDCIMParams;
{$ENDIF}
{$IFDEF IEINCLUDEIEXACQUIRE}
property WIAParams: TIEWia read GetWIAParams;
{$ENDIF}
function ParamsFromFile(const FileName: WideString; Format: TIOFileType = ioUnknown): Boolean; overload;
function ParamsFromFile(const FileName: WideString; bUseExtension: Boolean): Boolean; overload;
function ParamsFromStream(Stream: TStream; Format: TIOFileType = ioUnknown): Boolean;
function ParamsFromBuffer(Buffer: Pointer; BufferSize: Integer; Format: TIOFileType = ioUnknown): Boolean;
{!!
<FS>TImageEnMIO.Aborting
<FM>Declaration<FC>
property Aborting: boolean;
<FM>Description<FN>
Applications can abort save/load processing by assigning True to the Aborting property. On loading, the image will be truncated. On saving, the file will be closed and truncated (and will be unreadable).
You can also read the <A TImageEnMIO.Aborting> property to know when aborting has occured (e.g. due to a failed load).
Note: The result from all LoadFromFile() methods returns false if Aborting has occured
<FM>Example<FC>
MyImageEnMView.LoadFromFileGIF('C:\MyGif.gif');
MyImageEnMView.Aborting then...
Which is the same as:
If MyImageEnMView.LoadFromFileGIF('C:\MyGif.gif') = False then...
!!}
property Aborting: boolean read fAborting write SetAborting;
// GIF
function LoadFromFileGIF(const FileName: string): Boolean;
function LoadFromStreamGIF(Stream: TStream): Boolean;
procedure SaveToFileGIF(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStreamGIF(Stream: TStream; SelectedOnly: Boolean = False);
// CUR
function LoadFromFileCUR(const FileName: string): Boolean;
function LoadFromStreamCUR(Stream: TStream): Boolean;
// DCX
function LoadFromFileDCX(const FileName: string): Boolean;
function LoadFromStreamDCX(Stream: TStream): Boolean;
procedure SaveToFileDCX(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStreamDCX(Stream: TStream; SelectedOnly: Boolean = False);
// DICOM
{$ifdef IEINCLUDEDICOM}
function LoadFromFileDICOM(const FileName: string): Boolean;
function LoadFromStreamDICOM(Stream: TStream): Boolean;
procedure SaveToFileDICOM(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStreamDICOM(Stream: TStream; SelectedOnly: Boolean = False);
{$endif}
// TIFF
function LoadFromFileTIFF(const FileName: string): Boolean;
function LoadFromStreamTIFF(Stream: TStream): Boolean;
procedure SaveToFileTIFF(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStreamTIFF(Stream: TStream; SelectedOnly: Boolean = False);
// AVI
function LoadFromFileAVI(const FileName: string): Boolean;
procedure SaveToFileAVI(const FileName: string; const Codec: AnsiString = ''; SelectedOnly: Boolean = False);
// PostScript (PS)
procedure SaveToFilePS(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStreamPS(Stream: TStream; SelectedOnly: Boolean = False);
// Adobe PDF
{$IFDEF IEINCLUDEMISCPLUGINS}
// PDF Plugins
function LoadFromFilePDF(const FileName: string): Boolean;
function LoadFromStreamPDF(Stream: TStream): Boolean;
{$endif}
{$ifdef IEINCLUDEPDFWRITING}
procedure SaveToFilePDF(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStreamPDF(Stream: TStream; SelectedOnly: Boolean = False);
{$endif}
// ICO
function LoadFromFileICO(const FileName: string): Boolean;
function LoadFromStreamICO(Stream: TStream): Boolean;
procedure SaveToFileICO(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStreamICO(Stream: TStream; SelectedOnly: Boolean = False);
// URL
function LoadFromURL(URL: string): Boolean;
// DirectShow media
{$ifdef IEINCLUDEDIRECTSHOW}
function LoadFromMediaFile(const FileName: string): Boolean;
{$endif}
// TWAIN
{$IFDEF IEINCLUDEIEXACQUIRE}
function Acquire : boolean;
function SelectAcquireSource(Apis : TIEAcquireApis = [ieaTwain, ieaWIA, ieaDCIM]): boolean;
function SetAcquireSource(Api: TIEAcquireApi; Location : Variant) : boolean;
property SelectedAcquireSource : TIEAcquireSource read GetSelectedAcquireSource;
function TwainAcquireOpen: boolean;
procedure TwainAcquireClose;
function AcquireOpen: boolean;
procedure AcquireClose;
// Internal use only
procedure InitializeAcquireSource(bIncludeWIA : Boolean);
{$ENDIF}
// General
procedure LoadFromBuffer(Buffer: pointer; BufferSize: integer; Format: TIOFileType = ioUnknown);
function LoadFromFile(const FileName: string; bCheckUnknown: Boolean = False): Boolean; overload;
function LoadFromFile(const FileName: string; FileFormat: TIOFileType): Boolean; overload;
procedure LoadFromFiles(const FileName: string; AutoDetect: boolean=false; LoadWhenViewed: boolean=false);
procedure SaveToFile(const FileName: string; SelectedOnly: Boolean = False);
procedure SaveToStream(Stream: TStream; FileFormat: TIOFileType; SelectedOnly: Boolean = False);
function LoadFromFileAuto(const FileName: string): Boolean;
function LoadFromStream(Stream: TStream; FileFormat: TIOFileType = ioUnknown): Boolean;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function LoadFromFileFormat(const FileName: string; FileFormat: TIOFileType): Boolean; {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use LoadFromFile instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
function LoadFromStreamFormat(Stream: TStream; FileFormat: TIOFileType): Boolean; {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use LoadFromStream instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
{$endif}
{$IFDEF IEINCLUDEOPENSAVEDIALOGS}
function ExecuteOpenDialog(const InitialDir : WideString = ''; const InitialFileName : WideString = ''; AlwaysAnimate : boolean = False;
FilterIndex: integer = 0; const ExtendedFilters : WideString = ''; MultiSelect : boolean = False;
const Title : WideString = ''; const Filter : WideString = ''; DefaultFilter : TIOFileType = -1;
LimitToFileType : TIOFileType = -1) : String; overload;
function ExecuteOpenDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False; MultiSelect : boolean = False) : String; overload;
function ExecuteSaveDialog(const InitialDir : WideString = ''; const InitialFileName : WideString = ''; AlwaysAnimate : boolean = False;
FilterIndex: integer = 0; const ExtendedFilters : WideString = ''; const Title : WideString = '';
const Filter : WideString = ''; DefaultFilter : TIOFileType = -1; LimitToFileType : TIOFileType = -1) : String; overload;
function ExecuteSaveDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False) : String; overload;
{$ENDIF}
{$IFDEF IEINCLUDEPRINTDIALOGS}
function DoPrintPreviewDialog(const TaskName: string = ''; PrintAnnotations: boolean=false; const Caption: string=''; ThumbnailPrinting: Boolean = False): boolean;
{$ENDIF}
property ResetPrinter: boolean read fResetPrinter write fResetPrinter;
{!!
<FS>TImageEnMIO.PrintPreviewParams
<FM>Declaration<FC>
property PrintPreviewParams: <A TIOPrintPreviewParams>;
<FM>Description<FN>
Provides access to parameters of the Print Preview dialog.
All measure units are specified by <A TImageEnMIO.DialogsMeasureUnit> property.
!!}
{$IFDEF IEINCLUDEPRINTDIALOGS}
property PrintPreviewParams: TIOPrintPreviewParams read fPrintPreviewParams;
{$ENDIF}
{!!
<FS>TImageEnMIO.NativePixelFormat
<FM>Declaration<FC>
property NativePixelFormat: boolean;
<FM>Description<FN>
When True, paletted and gray scale images are not converted to 24 bit.
By default, ImageEn converts all paletted images to 24 bit (true color). Only black/white images are stored in the original format with 1 bit per pixel.
Note: If you sett NativePixelFormat=True, you will be unable to execute some image processing operations
!!}
property NativePixelFormat: boolean read fNativePixelFormat write fNativePixelFormat;
{!!
<FS>TImageEnMIO.PrintingFilterOnSubsampling
<FM>Declaration<FC>
property PrintingFilterOnSubsampling: <A TResampleFilter>;
<FM>Description<FN>
Specifies a filter when printing an image and it must be resampled. Filtering enhances the image quality but slows processing.
!!}
property PrintingFilterOnSubsampling: TResampleFilter read fPrintingFilterOnSubsampling write fPrintingFilterOnSubsampling;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-08)
// NOTE: Now handled by IEGlobalSettings()
property ProxyAddress: WideString read GetProxyAddress write SetProxyAddress;
property ProxyUser: WideString read GetProxyUser write SetProxyUser;
property ProxyPassword: WideString read GetProxyPassword write SetProxyPassword;
{$ENDIF}
procedure PrintImagePos(ImageIndex: integer; PrtCanvas: TCanvas; x, y: double; Width, Height: double; GammaCorrection: double = 1; PrintAnnotations: boolean = False);
procedure PrintImage(ImageIndex : integer; PrtCanvas : TCanvas = nil; MarginLeft : double = 1; MarginTop : double = 1; MarginRight : double = 1; MarginBottom : double = 1; VerticalPos : TIEVerticalPos = ievpCenter; HorizontalPos : TIEHorizontalPos = iehpCenter; Size : TIESize = iesFitToPage; SpecWidth : double = 0; SpecHeight : double = 0; GammaCorrection : double = 1; PrintAnnotations: boolean = False);
procedure PrintImages(Columns: integer=2; Rows: integer=2; HorizSpace: double=0.5; VertSpace: double=0.5; PrintSelected: boolean=false; MarginLeft: double=0; MarginTop: double=0; MarginRight: double=0; MarginBottom: double=0; DrawBox: boolean=true; DrawText: boolean=true; DrawShadow: boolean=false; BoxColor: TColor = clBlack);
procedure PreviewPrintImages(DestBitmap: TBitmap; MaxBitmapWidth, MaxBitmapHeight: integer; PrinterObj: TPrinter; Columns: integer; Rows: integer; HorizSpace: double; VertSpace: double; PrintSelected: boolean; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; DrawBox: boolean; DrawText: boolean; DrawShadow: boolean; BoxColor: TColor = clBlack; iPageNo : Integer = 0);
procedure PrintImagesToFile(const sFilename : string; iJpegQuality : Integer; iImageWidth, iImageHeight: integer; iColumns : integer; iRows : integer; iHorzSpace : Integer = 6; iVertSpace : Integer = 6; bPrintSelectedOnly: Boolean = False; iHorzMargin : Integer = 12; iVertMargin : Integer = 12; bDrawBox : Boolean = False; bDrawText : Boolean = True; bDrawShadow : Boolean = True; BackgroundColor : TColor = clWhite; BoxColor: TColor = clBlack; iPageNo : Integer = -1);
property AttachedIEMBitmap: TIECustomMultiBitmap read fIEMBitmap write SetAttachedIEMBitmap;
published
{ Published declarations }
property AttachedMView: TIEView read fImageEnMView write SetAttachedMView;
{!!
<FS>TImageEnMIO.OnProgress
<FM>Declaration<FC>
property OnProgress: <A TIEProgressEvent>;
<FM>Description<FN>
Occurs on input/output operations. If you are using it to update a progress bar then you can reset it in the <A TImageEnMView.OnFinishWork> event.
!!}
property OnProgress: TIEProgressEvent read fOnProgress write fOnProgress;
{!!
<FS>TImageEnMIO.OnAcquireBitmap
<FM>Declaration<FC>
property OnAcquireBitmap: <A TIEAcquireBitmapEvent>;
<FM>Description<FN>
Occurs whenever the scanner acquires an image.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C>Sender</C> <C>Will be either a TImageEnIO or TImageEnMIO control</C> </R>
<R> <C>ABitmap</C> <C>A <A TIEBitmap> object that contains the acquired image</C> </R>
<R> <C>DpiX, DpiY</C> <C>Tne DPI of the acquired image</C> </R>
<R> <C>Handled</C> <C>Setting Handled to True causes ImageEn to ignore this image (i.e. the current image won't be inserted into the <A TImageEnMView> control, if attached). Handled has no effect when acquiring via a TImageEnView/TImageEnIO</C> </R>
</TABLE>
Note: Handled defaults to False.
<FM>Example<FC>
procedure TForm1.ImageEnMView1AcquireBitmap(Sender: TObject; ABitmap: TIEBitmap; DpiX, DpiY: Integer; var Handled: boolean);
begin
// Skip retrieval of images that are less than 500x500 pixels
If ( ABitmap.Width < 500 ) or ( ABitmap.Height < 500 ) then
Handled := True;
end;
!!}
property OnAcquireBitmap: TIEAcquireBitmapEvent read fOnAcquireBitmap write fOnAcquireBitmap;
{!!
<FS>TImageEnMIO.OnAcquireClose
<FM>Declaration<FC>
property OnAcquireClose: TNotifyEvent;
<FM>Description<FN>
Occurs when the user closes the acquire dialog, open using <A TImageEnMIO.TwainAcquireOpen>.
!!}
property OnAcquireClose: TNotifyEvent read fOnAcquireClose write fOnAcquireClose;
{!!
<FS>TImageEnMIO.OnAfterAcquireBitmap
<FM>Declaration<FC>
property OnAfterAcquireBitmap: <A TIEAfterAcquireBitmapEvent>;
<FM>Description<FN>
Occurs after an image is acquired from a scanner and added to the image list.
!!}
property OnAfterAcquireBitmap: TIEAfterAcquireBitmapEvent read fOnAfterAcquireBitmap write fOnAfterAcquireBitmap;
property PreviewsParams: TIOPreviewsParams read GetIOPreviewParams write SetIOPreviewParams default [];
property PreviewFont: TFont read fPreviewFont write SetPreviewFont;
property PreviewFontEnabled: Boolean read fPreviewFontEnabled write SetPreviewFontEnabled default false;
{!!
<FS>TImageEnMIO.AutoAdjustDPI
<FM>Declaration<FC>
property AutoAdjustDPI: boolean;
<FM>Description<FN>
When True and the last loaded/scanned image has a horizontal DPI not equal to its vertical DPI, ImageEn resizes the image to make DPIX=DPIY.
Default: False
!!}
property AutoAdjustDPI: boolean read fAutoAdjustDPI write fAutoAdjustDPI default false;
{!!
<FS>TImageEnMIO.FilteredAdjustDPI
<FM>Declaration<FC>
property FilteredAdjustDPI: boolean;
<FM>Description<FN>
The FilteredAdjustDPI property is valid when <A TImageEnMIO.AutoAdjustDPI> is true. If set to True, ImageEn applies a resampling filter to the image to enhance quality.
It can slow down the loading process.
!!}
property FilteredAdjustDPI: boolean read fFilteredAdjustDPI write fFilteredAdjustDPI default false;
{!!
<FS>TImageEnMIO.SimplifiedParamsDialogs
<FM>Declaration<FC>
property SimplifiedParamsDialogs: boolean;
<FM>Description<FN>
If True, the "Advanced" button of open/save dialogs will show a simplified set of parameters.
Default: True
!!}
property SimplifiedParamsDialogs: boolean read fSimplifiedParamsDialogs write fSimplifiedParamsDialogs default true;
{!!
<FS>TImageEnMIO.OnFinishWork
<FM>Declaration<FC>
property OnFinishWork: TNotifyEvent;
<FM>Description<FN>
Occurs when an input/output task ends. It is useful for resetting progress bars, or to know when a thread ends in asynchronous mode.
!!}
property OnFinishWork: TNotifyEvent read fOnFinishWork write fOnFinishWork;
{!!
<FS>TImageEnMIO.DialogsMeasureUnit
<FM>Declaration<FC>
property DialogsMeasureUnit: <A TIEDialogsMeasureUnit>
<FM>Description<FN>
Specifies the measurement unit used in the print preview dialog (see <A TImageEnMIO.DoPrintPreviewDialog>).
<FM>Example<FC>
ImageEnView.MIO.DialogsMeasureUnit := ieduCm;
ImageEnView.MIO.DoPrintPreviewDialog('');
!!}
property DialogsMeasureUnit: TIEDialogsMeasureUnit read fDialogsMeasureUnit write fDialogsMeasureUnit default ieduInches;
{!!
<FS>TImageEnMIO.OnDoPreviews
<FM>Declaration<FC>
property OnDoPreviews: <A TIEDoPreviewsEvent>;
<FM>Description<FN>
Occurs before DoPreviews is called or the "Advanced" button is clicked (Save dialog).
You can avoid displaying the dialog by setting the Handled parameter to True (and displaying a custom dialog).
!!}
property OnDoPreviews: TIEDoPreviewsEvent read fOnDoPreviews write fOnDoPreviews;
property ImageEnVersion: string read GetImageEnVersion write SetImageEnVersion stored false;
// Not documented: List of all params
property ParamsList: TIOMultiParams read GetParamsList;
end;
// Returns true if the specified file type can be saved by TImageEnMIO
function IsMultiFrameSaveFormat(FileType : TIOFileType) : Boolean;
implementation
uses
Dialogs, GIFFilter, TIFFilt, IEVfw, imscan, iopreviews, IEMView, IEOpenSaveDlg, bmpfilt, ieprnform3, ieds,
iedicom, iewic, iesettings, iemiscplugins;
{$R-}
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.AttachedMView
<FM>Declaration<FC>
property AttachedMView: <A TImageEnMView>;
<FM>Description<FN>
Specifies the attached TImageEnMView component.
Note: To use a TImageEnMIO, you must attach it to a <A TImageEnMView> or a <A TIEMultiBitmap>.
<FM>See Also<FN>
- <A TImageEnMIO.AttachedIEMBitmap>
!!}
procedure TImageEnMIO.SetAttachedMView(v: TIEView);
begin
if assigned( fIEMBitmap ) then
fIEMBitmap.OnUpdateParams := nil;
if assigned(fImageEnMView) then
fImageEnMView.RemoveBitmapChangeEvent(fImageEnMViewBitmapChangeHandle); // remove previous, if exists
fImageEnMView := v;
if assigned(fImageEnMView) then
begin // fImageEnMView now could be "nil"
if fIEMBitmapCreated then
begin
fIEMBitmapCreated := false;
FreeAndNil( fIEMBitmap );
end;
fImageEnMView.FreeNotification(self);
fImageEnMViewBitmapChangeHandle := fImageEnMView.RegisterBitmapChangeEvent(OnBitmapChange);
// synchronize parameters count
fParamsList.Allocate( GetIEMBitmap.Count );
end
else
begin
fIEMBitmap := TIEMultiBitmap.Create;
fIEMBitmapCreated := true; // we create fIEMBitmap
end;
end;
{!!
<FS>TImageEnMIO.IEMBitmap
<FM>Declaration<FC>
property IEMBitmap: <A TIECustomMultiBitmap>
<FM>Description<FN>
Contains the attached <A TIEMultiBitmap> object or the <A TImageEnMView.IEMBitmap> of the attached <A TImageEnMView>.
Note: Unlike <A TImageEnMIO.AttachedIEMBitmap>, <FC>IEMBitmap<FN> is never nil.
!!}
function TImageEnMIO.GetIEMBitmap: TIECustomMultiBitmap;
begin
if assigned( fImageEnMView ) then
Result := ( fImageEnMView as TImageEnMView ).IEMBitmap
else
Result := fIEMBitmap;
end;
procedure TImageEnMIO.SetIEMBitmap(mbmp: TIECustomMultiBitmap);
begin
if assigned( fIEMBitmap ) then
fIEMBitmap.OnUpdateParams := nil;
if fIEMBitmapCreated then
FreeAndNil( fIEMBitmap );
fIEMBitmapCreated := false;
fIEMBitmap := mbmp;
end;
{!!
<FS>TImageEnMIO.AttachedIEMBitmap
<FM>Declaration<FC>
property AttachedIEMBitmap: <A TIECustomMultiBitmap>
<FM>Description<FN>
Attach a <A TIEMultiBitmap> object to the TImageEnMIO. Will be nil if the TImageEnIO is attached to a <A TImageEnMView>.
<FM>Example<FC>
// Print all images in a TIFF file
MyMBitmap := TIEMultiBitmap.create;
AnImageEnMIO := TImageEnMIO.Create( nil );
AnImageEnMIO.AttachedIEMBitmap := MyMBitmap;
AnImageEnMIO.DoPrintPreviewDialog( '' );
...
AnImageEnMIO.Free;
MyMBitmap.Free;
<FM>See Also<FN>
- <A TImageEnMIO.AttachedMView>
!!}
procedure TImageEnMIO.SetAttachedIEMBitmap(mbmp: TIECustomMultiBitmap);
begin
if assigned(fImageEnMView) then
fImageEnMView.RemoveBitmapChangeEvent(fImageEnMViewBitmapChangeHandle); // remove previous if exists
if (not assigned(mbmp)) and assigned(fImageEnMView) then
exit; // error
SetIEMBitmap(mbmp);
if assigned(mbmp) then
fImageEnMView := nil;
if assigned( fIEMBitmap ) then
fIEMBitmap.OnUpdateParams := UpdateAttachedBitmapParams;
// synchronize parameters count
if assigned( fIEMBitmap ) then
fParamsList.Allocate( fIEMBitmap.Count );
end;
/////////////////////////////////////////////////////////////////////////////////////
procedure TImageEnMIO.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = fImageEnMView) and (Operation = opRemove) then
begin
fImageEnMView.RemoveBitmapChangeEvent(fImageEnMViewBitmapChangeHandle);
fImageEnMView := nil;
end;
end;
/////////////////////////////////////////////////////////////////////////////////////
constructor TImageEnMIO.Create(Owner: TComponent);
begin
inherited Create(Owner);
//
fIEMBitmap := TIEMultiBitmap.Create;
fIEMBitmapCreated := true; // we create fIEMBitmap
fImageEnMViewBitmapChangeHandle := nil;
fAborting := false;
fImageEnMView := nil;
fOnProgress := nil;
fOnFinishWork := nil;
fParamsList := TIOMultiParams.Create;
{$IFDEF IEINCLUDEIEXACQUIRE}
fAcquireParams := TIEAcquireParams.Create(Self);
fTwainParams := TIETwainParams.Create(Self);
{$ENDIF}
{$IFDEF IEINCLUDEWPD}
fDCIMParams := TIEDcimAcquire.Create(Self);
{$ENDIF}
fPreviewsParams := [];
fPreviewFont := TFont.Create;
fPreviewFontEnabled := False;
fAutoAdjustDPI := false;
fFilteredAdjustDPI := false;
fOnAcquireBitmap := nil;
fOnAcquireClose := nil;
fOnAfterAcquireBitmap := nil;
fOnDoPreviews := nil;
fgrec := nil;
fDefaultDitherMethod := ieThreshold;
SimplifiedParamsDialogs := true;
{$IFDEF IEINCLUDEIEXACQUIRE}
fWIA := nil;
{$ENDIF}
fResetPrinter := true;
fDialogsMeasureUnit := ieduInches;
fNativePixelFormat := false;
fPrintingFilterOnSubsampling := rfFastLinear;
{$IFDEF IEINCLUDEPRINTDIALOGS}
fPrintPreviewParams := TIOPrintPreviewParams.Create;
{$ENDIF}
fLoadingFileName := '';
fLastFilename := '';
fAllowMalformedPages := false;
end;
/////////////////////////////////////////////////////////////////////////////////////
destructor TImageEnMIO.Destroy;
begin
if assigned(fImageEnMView) then
fImageEnMView.RemoveBitmapChangeEvent(fImageEnMViewBitmapChangeHandle);
if assigned( fIEMBitmap ) then
fIEMBitmap.OnUpdateParams := nil;
FreeAndNil(fParamsList);
{$IFDEF IEINCLUDEIEXACQUIRE}
FreeAndNil(fAcquireParams);
FreeAndNil(fTwainParams);
{$ENDIF}
{$IFDEF IEINCLUDEWPD}
FreeAndNil(fDCIMParams);
{$ENDIF}
if fIEMBitmapCreated then
FreeAndNil( fIEMBitmap );
{$IFDEF IEINCLUDEIEXACQUIRE}
if assigned(fWia) then
FreeAndNil(fWia);
{$ENDIF}
FreeAndNil(fPreviewFont);
{$IFDEF IEINCLUDEPRINTDIALOGS}
FreeAndNil(fPrintPreviewParams);
{$ENDIF}
inherited;
end;
{!!
<FS>TImageEnMIO.CreateFromIEMBitmap
<FM>Declaration<FC>
constructor CreateFromBitmap(MBitmap: <A TIEMultiBitmap>);
<FM>Description<FN>
Creates a new instance of TImageEnMIO, assigning the property <A TImageEnMIO.AttachedIEMBitmap>.
<FM>Example<FC>
// Print all images in a TIFF file
MyMBitmap := TIEMultiBitmap.create;
AnImageEnMIO := TImageEnMIO.CreateFromIEMBitmap( MyMBitmap );
AnImageEnMIO.DoPrintPreviewDialog( '' );
...
AnImageEnMIO.Free;
MyMBitmap.Free;
!!}
constructor TImageEnMIO.CreateFromIEMBitmap(MBitmap: TIECustomMultiBitmap);
begin
Create(nil);
AttachedIEMBitmap := MBitmap;
end;
{!!
<FS>TImageEnMIO.Update
<FM>Declaration<FC>
procedure Update;
<FM>Description<FN>
Calls the Update method of the <L TImageEnMIO.AttachedMView>attached TImageEnMView</L> component.
!!}
procedure TImageEnMIO.Update;
begin
if assigned(fImageEnMView) then
with fImageEnMView do
begin
Update;
ImageChange;
end;
end;
// called after registering using RegisterBitmapChangeEvent
// Realign I/O parameters with TImageEnMView
procedure TImageEnMIO.OnBitmapChange(Sender: TObject; destroying: boolean);
var
grp: TIEArrayOfInteger;
begin
if destroying then
fImageEnMView := nil
else
if assigned(fImageEnMView) then
with fImageEnMView as TImageEnMView do
begin
SetLength(grp, 0);
grp := (fImageEnMView as TImageEnMView).GetLastOpGroup();
fParamsList.UpdateEx( GetLastOp(), GetLastOpIdx(), GetLastOpP1(), grp );
end;
end;
// Called from attached TIEMultiBitmap (but not TImageEnMView) when the params need to realigned
procedure TImageEnMIO.UpdateAttachedBitmapParams(Sender : TObject; Operation: Integer; Idx : integer; ExtraParam: Integer);
begin
fParamsList.UpdateEx( Operation, Idx, ExtraParam );
end;
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.ParamsCount
<FM>Declaration<FC>
property ParamsCount: integer;
<FM>Description<FN>
Returns the number of elements in the Params property (which will be equivalent to the number of images contained in the attached <A TImageEnMView> or <A TIEMultiBitmap>).
Read-only
!!}
function TImageEnMIO.GetParamsCount: integer;
begin
if ( GetIEMBitmap <> nil ) and GetIEMBitmap.ParamsEnabled then
Result := GetIEMBitmap.Count
else
result := fParamsList.Count;
end;
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.LoadFromFileGIF
<FM>Declaration<FC>
function LoadFromFileGIF(const FileName: string): Boolean;
<FM>Description<FN>
Load a GIF file into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
Result will be false if the file is not GIF format (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: Existing content is <FB>not<FN> cleared
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageEditing\AnimatedGIF\AnimatedGIF.dpr </C> </R>
</TABLE>
!!}
function TImageEnMIO.LoadFromFileGIF(const FileName: string) : Boolean;
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fLoadingFileName := FileName;
Result := LoadFromStreamGIF(fs);
finally
fLoadingFileName := '';
fLastFilename := Filename;
FreeAndNil(fs);
end;
end;
// Lock paint on attached TImageEnMView
procedure TImageEnMIO.fImageEnMView_LockPaint;
begin
if assigned( fImageEnMView ) then
(fImageEnMView as TImageEnMView).LockPaint;
end;
// Unlock paint on attached TImageEnMView
procedure TImageEnMIO.fImageEnMView_UnlockPaint;
begin
if assigned( fImageEnMView ) then
(fImageEnMView as TImageEnMView).UnlockPaint;
end;
// Return the selection position if assigned to a TImageEnMView, otherwise the image count (i.e. add to end)
function TImageEnMIO.NextInsertionIndex() : Integer;
begin
Result := -1;
if assigned( fImageEnMView ) then
Result := (fImageEnMView as TImageEnMView).SelectedImage;
if ( Result = -1 ) and ( GetIEMBitmap <> nil ) then
Result := GetIEMBitmap.Count;
end;
// Call fImageEnMView.InsertImageEx() or fIEMBitmap.InsertImage()
procedure TImageEnMIO.Attached_InsertImage(idx: Integer);
begin
if assigned( fImageEnMView ) then
( fImageEnMView as TImageEnMView ).InsertImageEx( idx )
else
fIEMBitmap.InsertImage( idx );
end;
// Call fImageEnMView.DeleteImage() or fIEMBitmap.DeleteImage()
procedure TImageEnMIO.Attached_DeleteImage(idx: Integer);
begin
if assigned( fImageEnMView ) then
( fImageEnMView as TImageEnMView ).DeleteImage( idx )
else
fIEMBitmap.DeleteImage( idx );
end;
// Call fImageEnMView.SetIEBitmapEx() or fIEMBitmap.SetImage()
procedure TImageEnMIO.Attached_SetIEBitmap(idx: Integer; bmp: TIEBaseBitmap);
begin
if assigned( fImageEnMView ) then
( fImageEnMView as TImageEnMView ).SetIEBitmapEx( idx, bmp )
else
fIEMBitmap.SetImage( idx, bmp );
end;
// Call fImageEnMView.CopyToIEBitmap() or fIEMBitmap.CopyToIEBitmap()
procedure TImageEnMIO.Attached_CopyToIEBitmap(idx: Integer; bmp: TIEBitmap);
begin
if assigned( fImageEnMView ) then
( fImageEnMView as TImageEnMView ).CopyToIEBitmap( Idx, bmp )
else
fIEMBitmap.CopyToIEBitmap( idx, bmp );
end;
// Call fImageEnMView.GetTIEBitmap() or fIEMBitmap.GetTIEBitmap()
function TImageEnMIO.Attached_GetTIEBitmap(idx: Integer): TIEBitmap;
begin
if assigned( fImageEnMView ) then
Result := ( fImageEnMView as TImageEnMView ).GetTIEBitmap( Idx )
else
Result := fIEMBitmap.GetTIEBitmap( idx );
end;
// Call fImageEnMView.ReleaseBitmap() or fIEMBitmap.ReleaseBitmap()
procedure TImageEnMIO.Attached_ReleaseBitmap(idx: Integer; SaveChanges: Boolean = True);
begin
if assigned( fImageEnMView ) then
( fImageEnMView as TImageEnMView ).ReleaseBitmap( idx, SaveChanges )
else
fIEMBitmap.ReleaseBitmap( idx, False );
end;
{!!
<FS>TImageEnMIO.LoadFromStreamGIF
<FM>Declaration<FC>
function LoadFromStreamGIF(Stream: TStream): Boolean;
<FM>Description<FN>
Load a GIF from a stream into the attached <A TImageEnMView> (at <A TImageEnMView.SelectedImage>) or <A TIEMultiBitmap>.
The result will be false if an error is encountered, e.g. the file in the stream is not GIF format (<A TImageEnMIO.Aborting> will be true).
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromStreamGIF(Stream: TStream): Boolean;
var
bmp, xbmp, merged, prev: TIEBitmap;
p1: int64;
numi, idx: integer;
Progress, Progress2: TProgressRec;
Param: TIOParams;
ld, im: integer; // last delay
tempAlphaChannel: TIEMask;
dummy2, dummy3: pinteger;
act: TIEGIFAction;
backx, backy, backw, backh: integer;
dx, dy: integer;
OriginalPixelFormat: TIEPixelFormat;
begin
Result := False;
if not IsAttached() then
exit;
merged := nil;
xbmp := nil;
bmp := nil;
prev := nil;
try
fImageEnMView_LockPaint();
fAborting := False;
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress2 := NullProgressRec( fAborting );
p1 := Stream.Position;
idx := NextInsertionIndex;
ld := 100; // 10ms default
im := 0;
merged := TIEBitmap.Create;
merged.Location := ieMemory;
act := ioGIF_None;
backw := 0;
backh := 0;
backx := 0;
backy := 0;
repeat
Attached_InsertImage( idx );
bmp := TIEBitmap.Create;
try
Param := fParamsList.Params[idx];
Stream.position := p1;
Param.GIF_ImageIndex := im;
Param.IsNativePixelFormat := fNativePixelFormat;
tempAlphaChannel := nil;
ReadGIFStream(Stream, bmp, numi, Param, Progress2, False, tempAlphaChannel, false);
if (bmp.Width = 0) or (bmp.Height = 0) then
fAborting := true;
OriginalPixelFormat := bmp.PixelFormat;
dx := imax(Param.GIF_WinWidth, bmp.Width);
dy := imax(Param.GIF_WinHeight, bmp.Height);
if assigned(tempAlphaChannel) then
begin
bmp.AlphaChannel.CopyFromTIEMask(tempAlphaChannel);
FreeAndNil(tempAlphaChannel);
end;
if fAutoAdjustDPI then
xbmp := IEAdjustDPI(bmp, Param, fFilteredAdjustDPI)
else
xbmp := bmp;
finally
if bmp <> xbmp then
FreeAndNil(bmp);
end;
bmp := xbmp;
if numi > 1 then
begin
if Param.GIF_Action = ioGIF_RestorePrev then
begin
// saves current state
if not assigned(prev) then
prev := TIEBitmap.Create();
prev.Assign(merged);
end;
if act = ioGIF_RestorePrev then
begin
// restore previous state
if assigned(prev) then
merged.Assign(prev);
end;
if act = ioGIF_DrawBackground then
begin
merged.FillRect(backx, backy, backx + backw - 1, backy + backh - 1, TRGB2TColor(param.GIF_Background));
merged.AlphaChannel.FillRect(backx, backy, backx + backw - 1, backy + backh - 1, 0); //*
end;
if (merged.Width = 0) then
begin
//merged.Allocate(dx, dy, bmp.PixelFormat);
merged.Allocate(dx, dy, ie24RGB);
merged.Fill(TRGB2TColor(param.GIF_Background));
merged.AlphaChannel.Fill(0);//*
end;
if merged.PixelFormat<>ie24RGB then
merged.PixelFormat := ie24RGB;
if (dx > merged.Width) or (dy > merged.Height) then
merged.Resize(dx, dy, TRGB2TColor(param.GIF_Background), 255, iehLeft, ievTop);
dummy2 := nil;
dummy3 := nil;
bmp.RenderToTIEBitmap(merged, dummy2, dummy3, nil, Param.GIF_XPos, Param.GIF_YPos, bmp.Width, bmp.Height, 0, 0, bmp.Width, bmp.Height, true, false, 255, rfNone, true, ielNormal);
bmp.MergeAlphaRectTo(merged, 0, 0, Param.GIF_XPos, Param.GIF_YPos, bmp.Width, bmp.Height);
merged.AlphaChannel.Full := false;
backw := bmp.Width;
backh := bmp.Height;
backx := Param.GIF_XPos;
backy := Param.GIF_YPos;
if bmp = xbmp then
xbmp := nil;
FreeAndNil(bmp);
bmp := merged;
act := param.GIF_Action; // act refers to the action of next image
Param.GIF_Action := ioGIF_DrawBackground;
Param.GIF_XPos := 0;
Param.GIF_YPos := 0;
end;
Param.ImageIndex := idx;
Param.FileType := ioGIF;
Param.FileName := WideString(fLoadingFileName);
if fAborting then
begin
Attached_DeleteImage( idx );
if bmp <> merged then
begin
if bmp = xbmp then
xbmp := nil;
FreeAndNil(bmp);
end;
break;
end;
if numi = 0 then
Attached_DeleteImage( idx )
else
begin
Progress.per1 := 100 / numi;
bmp.PixelFormat := originalPixelFormat;
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageBackground[idx] := TRGB2TColor(Param.GIF_Background);
if Param.GIF_DelayTime > 0 then
begin
GetIEMBitmap.ImageDelayTime[idx] := Param.GIF_DelayTime * 10;
ld := Param.GIF_DelayTime * 10;
end
else
GetIEMBitmap.ImageDelayTime[idx] := ld;
end;
if bmp <> merged then
begin
if bmp = xbmp then
xbmp := nil;
FreeAndNil(bmp);
end
else
begin
if bmp = xbmp then
xbmp := nil;
bmp := nil;
end;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting then
break;
inc(idx);
inc(im);
until im >= numi;
GetIEMBitmap.Modified := False;
finally
if bmp = xbmp then
xbmp := nil;
if bmp = merged then
bmp := nil;
bmp.Free();
xbmp.Free();
merged.Free();
prev.Free();
Update;
fImageEnMView_UnlockPaint();
DoFinishWork;
end;
Result := Not fAborting;
end;
{!!
<FS>TImageEnMIO.SaveToFileGIF
<FM>Declaration<FC>
procedure SaveToFileGIF(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> as a GIF file.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageEditing\AnimatedGIF\AnimatedGIF.dpr </C> </R>
</TABLE>
<FM>See Also<FN>
- <A IEOptimizeGIF>
!!}
procedure TImageEnMIO.SaveToFileGIF(const FileName: string; SelectedOnly: Boolean = False);
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmCreate);
try
SaveToStreamGIF(fs, SelectedOnly);
finally
FreeAndNil(fs);
end;
_GIFMakeAnimate(FileName, 0, 0, 0);
end;
{!!
<FS>TImageEnMIO.SaveToStreamGIF
<FM>Declaration<FC>
procedure SaveToStreamGIF(Stream: TStream; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a stream in GIF format.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToStreamGIF(Stream: TStream; SelectedOnly: Boolean = False);
var
p1: int64;
Param: TIOParams;
Progress: TProgressRec;
bmp: TIEBitmap;
NullProgress: TProgressRec;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
Param := fParamsList.Params[ImgIdx];
Param.GIF_ImageIndex := FileIdx;
Stream.position := p1;
Attached_CopyToIEBitmap( ImgIdx, bmp );
if bmp.HasAlphaChannel then
begin
bmp.AlphaChannel.SyncFull;
if bmp.AlphaChannel.Full then
bmp.RemoveAlphaChannel;
end;
bmp.DefaultDitherMethod := fDefaultDitherMethod;
if FileIdx = 0 then
WriteGIFStream(Stream, bmp, Param, NullProgress)
else
_InsertGIFImStream(Stream, bmp, Param, NullProgress);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i, imgCount: integer;
begin
bmp := nil;
try
fAborting := False;
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
NullProgress := NullProgressRec( Progress.Aborting );
p1 := Stream.Position;
Progress.per1 := 100 / imgCount;
bmp := TIEBitmap.Create;
i := 0;
while not fAborting and (i < imgCount) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
finally
FreeAndNil(bmp);
DoFinishWork;
end;
end;
{!!
<FS>TImageEnMIO.LoadFromFileTIFF
<FM>Declaration<FC>
function LoadFromFileTIFF(const FileName: string): Boolean;
<FM>Description<FN>
Load a TIFF file into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
Result will be false if the file is not TIFF format (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromFileTIFF(const FileName: string): Boolean;
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fLoadingFileName := FileName;
Result := LoadFromStreamTIFF(fs);
finally
fLoadingFileName := '';
fLastFilename := Filename;
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromStreamTIFF
<FM>Declaration<FC>
function LoadFromStreamTIFF(Stream: TStream): Boolean;
<FM>Description<FN>
Load a TIFF from a stream into the attached <A TImageEnMView> (at <A TImageEnMView.SelectedImage>) or <A TIEMultiBitmap>.
The result will be false if an error is encountered, e.g. the file in the stream is not TIFF format (<A TImageEnMIO.Aborting> will be true).
Note: Existing content is <FB>not<FN> cleared
!!}
// default delay is 100ms
function TImageEnMIO.LoadFromStreamTIFF(Stream: TStream): Boolean;
var
p1: int64;
xbmp, bmp: TIEBitmap;
numi, idx: integer;
Progress, Progress2: TProgressRec;
Param: TIOParams;
im: integer;
tempAlphaChannel: TIEMask;
begin
Result := False;
fAborting := False;
if not IsAttached() then
exit;
try
fImageEnMView_LockPaint();
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress2 := NullProgressRec( fAborting );
p1 := Stream.Position;
idx := NextInsertionIndex;
im := 0;
repeat
Attached_InsertImage( idx );
bmp := TIEBitmap.Create;
try
Param := fParamsList.Params[idx];
Stream.position := p1;
Param.TIFF_ImageIndex := im;
Param.IsNativePixelFormat := fNativePixelFormat;
tempAlphaChannel := nil;
TIFFReadStream(bmp, Stream, numi, Param, Progress2, false, tempAlphaChannel, true, false, false, false);
CheckDPI(Param);
if assigned(tempAlphaChannel) then
begin
bmp.AlphaChannel.CopyFromTIEMask(tempAlphaChannel);
FreeAndNil(tempAlphaChannel);
end;
if fAutoAdjustDPI then
begin
xbmp := IEAdjustDPI(bmp, Param, fFilteredAdjustDPI);
if bmp <> xbmp then
begin
FreeAndNil(bmp);
bmp := xbmp
end;
end;
Param.ImageIndex := idx;
Param.FileType := ioTIFF;
Param.FileName := WideString(fLoadingFileName);
if fAborting and not fAllowMalformedPages then
begin
Attached_DeleteImage( idx );
break;
end;
if fAborting then
fAborting := false;
if numi = 0 then
Attached_DeleteImage( idx )
else
begin
Progress.per1 := 100 / numi;
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageDelayTime[idx] := 100;
end;
finally
FreeAndNil(bmp);
end;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting and not fAllowMalformedPages then
break;
inc(idx);
inc(im);
until im >= numi;
Update;
GetIEMBitmap.Modified := False;
finally
fImageEnMView_UnlockPaint();
DoFinishWork;
end;
Result := Not fAborting;
end;
{!!
<FS>TImageEnMIO.SaveToFileTIFF
<FM>Declaration<FC>
procedure SaveToFileTIFF(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> as a TIFF file.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToFileTIFF(const FileName: string; SelectedOnly: Boolean = False);
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmCreate);
try
SaveToStreamTIFF(fs, SelectedOnly);
finally
FreeAndNil(fs);
end;
end;
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.SaveToStreamTIFF
<FM>Declaration<FC>
procedure SaveToStreamTIFF(Stream: TStream; SaveSelected: boolean=false);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a stream in TIFF format.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToStreamTIFF(Stream: TStream; SelectedOnly: Boolean = False);
var
p1: int64;
Param: TIOParams;
Progress: TProgressRec;
bmp: TIEBitmap;
NullProgress: TProgressRec;
imgCount: integer;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
Stream.position := p1;
Attached_CopyToIEBitmap( ImgIdx, bmp );
Param := fParamsList.Params[ImgIdx]; // must stay after CopyToIEBitmap (to allow to load images on demand)
Param.TIFF_ImageIndex := FileIdx;
bmp.DefaultDitherMethod := fDefaultDitherMethod;
if FileIdx = 0 then
TIFFWriteStream(Stream, false, bmp, Param, NullProgress)
else
TIFFWriteStream(Stream, true, bmp, Param, NullProgress);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i: integer;
begin
bmp := nil;
try
fAborting := False;
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
NullProgress := NullProgressRec( Progress.Aborting );
bmp := TIEBitmap.Create;
p1 := Stream.Position;
Progress.per1 := 100 / imgCount;
i := 0;
while not fAborting and (i < imgCount) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
finally
FreeAndNil(bmp);
DoFinishWork;
end;
end;
{!!
<FS>TImageEnMIO.LoadFromFileAVI
<FM>Declaration<FC>
function LoadFromFileAVI(const FileName: string): Boolean;
<FM>Description<FN>
Load an AVI file into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
Result will be false if the file is not AVI format (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Notes:
- Existing content is <FB>not<FN> cleared
- You can alternatively use <A TImageEnMIO.LoadFromMediaFile>
!!}
function TImageEnMIO.LoadFromFileAVI(const FileName: string): Boolean;
var
avf: PAVIFILE;
avs: PAVISTREAM;
gf: PGETFRAME;
pt: pointer;
ln, idx, im: integer;
Progress: TProgressRec;
bmp: TIEDibBitmap;
Param: TIOParams;
psi: TAVISTREAMINFO;
dt: integer;
bitcount: integer;
trymediafile: boolean;
iBitsPerSample, iSamplesPerPixel: Integer;
begin
Result := False;
trymediafile := false;
try
fImageEnMView_LockPaint();
fAborting := False;
if not IsAttached() then
exit;
if not gAVIFILEinit then
begin
AVIFileInit;
gAVIFILEinit := true;
end;
Progress := ProgressRec( Self, fOnProgress, fAborting );
//
if AVIFileOpen(avf, pchar(FileName), OF_READ, nil) <> 0 then
begin
fAborting := True;
exit;
end;
if AVIFileGetStream(avf, avs, streamtypeVIDEO, 0) <> 0 then
begin
AVIFileRelease(avf);
fAborting := True;
trymediafile := true;
exit;
end;
if AVIStreamInfo(avs, psi, sizeof(TAVISTREAMINFO)) <> 0 then
begin
AVIFileRelease(avf);
AVIStreamRelease(avs);
fAborting := True;
trymediafile := true;
exit;
end;
gf := AVIStreamGetFrameOpen(avs, nil);
if gf = nil then
begin
AVIFileRelease(avf);
AVIStreamRelease(avs);
fAborting := True;
trymediafile := true;
exit;
end;
//
ln := psi.dwLength;
dt := trunc((1 / (psi.dwRate / psi.dwScale)) * 1000);
Progress.per1 := 100 / ln;
idx := NextInsertionIndex;
bmp := TIEDibBitmap.Create;
for im := 0 to ln - 1 do
begin
pt := AVIStreamGetFrame(gf, im);
if pt <> nil then
begin
Attached_InsertImage( idx );
Param := fParamsList.Params[idx];
bitcount := _IECopyDIB2Bitmap2Ex(integer(pt), bmp, nil, true); // uses drawdibdraw
Attached_SetIEBitmap( idx, bmp );
if im = 0 then
GetIEMBitmap.PrepareSpaceFor(bmp.Width, bmp.Height, BitCount, ln - 1);
GetIEMBitmap.ImageDelayTime[idx] := dt;
Param.GIF_DelayTime := dt;
BitCountToBPSAndSPP( BitCount, False, iBitsPerSample, iSamplesPerPixel );
Param.BitsPerSample := iBitsPerSample;
Param.SamplesPerPixel := iSamplesPerPixel;
Param.ImageIndex := idx;
Param.DpiX := IEGlobalSettings().DefaultDPIX;
Param.DpiY := IEGlobalSettings().DefaultDPIY;
Param.Width := bmp.Width;
Param.Height := bmp.Height;
Param.FileName := WideString(FileName);
Param.FileType := ioAVI;
Param.FreeColorMap;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
end
else
fAborting := true;
if fAborting then
break;
inc(idx);
end;
FreeAndNil(bmp);
AVIStreamGetFrameClose(gf);
AVIStreamRelease(avs);
AVIFileRelease(avf);
Update;
GetIEMBitmap.Modified := False;
finally
fImageEnMView_UnlockPaint();
if trymediafile then
begin
{$ifdef IEINCLUDEDIRECTSHOW}
LoadFromMediaFile(FileName);
{$endif}
end
else
DoFinishWork;
end;
Result := Not fAborting;
end;
{!!
<FS>TImageEnMIO.SaveToFileAVI
<FM>Declaration<FC>
procedure SaveToFileAVI(const FileName: string; const Codec: AnsiString = ''; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> as an AVI file.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: All images in the <A TImageEnMView>/<A TIEMultiBitmap> must be of the same size.
<FC>Codec<FN> specifies the compression codec to use (must be installed on system) as a four character string. Examples:
'cvid' : cinepak by Radius
'msvc' : Microsoft Video 1
'mp42' : Microsoft MPEG4 V2
More codecs are listed at <L http://www.fourcc.org>www.fourcc.org</L> or by searching for registered fourcc codes and wave formats on <L http://msdn.microsoft.com>MSDN</L>
If a codec is not specified, a dialog box appears to allow the user to select a compression.
!!}
procedure TImageEnMIO.SaveToFileAVI(const FileName: string; const Codec: AnsiString = ''; SelectedOnly: Boolean = False);
var
io: TImageEnIO;
Progress: TProgressRec;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
io.AttachedIEBitmap := Attached_GetTIEBitmap( ImgIdx );
io.SaveToAVI;
Attached_ReleaseBitmap( ImgIdx, false);
io.AttachedIEBitmap := nil;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i, imgCount: Integer;
begin
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress.per1 := 100 / imgCount;
io := TImageEnIO.Create(nil);
try
io.Params.Width := GetIEMBitmap.ImageWidth[0];
io.Params.Height := GetIEMBitmap.ImageHeight[0];
io.Params.BitsPerSample := Params[0].BitsPerSample;
io.Params.SamplesPerPixel := Params[0].SamplesPerPixel;
io.CreateAVIFile(FileName, 1.0 / (dmax( GetIEMBitmap.ImageDelayTime[0], 1.0 ) / 1000.0), codec);
if io.Aborting then
exit;
i := 0;
while not fAborting and (i < imgCount) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
io.CloseAVIFile;
finally
FreeAndNil(io);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromFile
<FM>Declaration<FC>
function LoadFromFile(const FileName: string; bCheckUnknown: Boolean = False): Boolean; overload;
function LoadFromFile(const FileName: string; FileFormat: <A TIOFileType>): Boolean; overload;
<FM>Description<FN>
Load a multi-image file into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
With first overload the format is detected from the filename extension (e.g. ".gif" files will be loaded as GIF). With second, you can force loading of the file as a specific type.
<FC>FileName<FN> is the file name including extension.
<FC>FileFormat<FN> specifies the image format. If specified as ioUnknown, it will use the file's extension.
<FC>bCheckUnknown<FN> if the file extension is not known or is incorrect (e.g. a GIF file named MyImage.jpg), then loading will be attempted by analyzing the file content (in the same way as <A TImageEnIO.LoadFromFileAuto>)
Result will be false if the file is not a recognized file type (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
However, if you set <FC>bCheckUnknown<FN> to true, ImageEn will try to load the file even if it has an unknown or incorrect file extension.
ImageEn supports loading of multiple frames from GIF, TIFF, AVI, DCX, DICOM, ICO and CUR formats. Loading of PDF format is also supported if a <L TImageEnMIO.LoadFromFilePDF>relevant plug-in</L> is installed.
Note: Existing content is <FB>not<FN> cleared
<FM>Example<FC>
// Load an AVI into our TImageEnMView
ImageEnMView1.Clear;
ImageEnMView1.MIO.LoadFromFile('C:\film.avi');
// Load a file (which is probably a TIFF but may have the wrong extension)
ImageEnMView1.MIO.LoadFromFile('C:\pages.tiff', True);
// Show an error on load failure
if ImageEnMView1.MIO.LoadFromFile(sFilename) = False then
ShowMessage('This is not a supported file type');
// Load file as a .GIF
ImageEnMView1.MIO.LoadFromFile('C:\myimage.xyz', ioGIF);
<FM>See Also<FN>
- <A TImageEnMIO.LoadFromFileAuto>
!!}
function TImageEnMIO.LoadFromFile(const FileName: string; bCheckUnknown: Boolean = False): Boolean;
var
ff, nf: TIOFileType;
begin
Result := False;
fAborting := true;
if FileName = '' then
exit;
// FIRST LOAD - get type from extension
ff := IEFilenameToInternalFileType(FileName, True);
// Handle PDF plug-ins
if ( ff = ioUnknown ) and IEFilenameInExtensions( FileName, '*.pdf;*.pdfa;*.epdf;') then
begin
if IEFileFormatGetInfo( iomscWPPDF ) <> nil then
ff := iomscWPPDF
{$IFDEF IEINCLUDEMISCPLUGINS}
else
if IEFileFormatGetInfo( iomscPDF ) <> nil then
ff := iomscPDF;
{$ENDIF}
end;
if ff <> ioUnknown then
Result := LoadFromFile(FileName, ff);
// SECOND LOAD - get type from content
if bCheckUnknown and (Result = False) then
begin
nf := FindFileFormat(FileName, ffFallbackToExtension);
if (nf <> ioUnknown) and (ff <> nf) then
Result := LoadFromFile(FileName, nf);
end;
end;
function TImageEnMIO.LoadFromFile(const FileName: string; FileFormat: TIOFileType): Boolean;
var
idx: Integer;
begin
Result := False;
if FileName = '' then
begin
fAborting := True;
DoFinishWork();
exit;
end;
if IEGetURLTypeW(FileName) <> ieurlUNKNOWN then
begin
Result := LoadFromURL(FileName);
exit;
end;
if FileFormat = ioUnknown then
FileFormat := FindFileFormat(FileName, ffContentOnly);
if FileFormat = ioUnknown then
begin
fAborting := True;
DoFinishWork();
exit;
end;
case FileFormat of
ioGIF : Result := LoadFromFileGIF(FileName);
ioTIFF : Result := LoadFromFileTIFF(FileName);
ioAVI : Result := LoadFromFileAVI(FileName);
ioICO : Result := LoadFromFileICO(FileName);
ioCUR : Result := LoadFromFileCUR(FileName);
ioDCX : Result := LoadFromFileDCX(FileName);
{$ifdef IEINCLUDEDICOM}
ioDICOM : Result := LoadFromFileDICOM(FileName);
{$endif}
{$IFDEF IEINCLUDEMISCPLUGINS}
iomscWPPDF,
iomscPDF: Result := LoadFromFilePDF(FileName);
{$endif}
else begin
// NOT A SUPPORTED MULTI-FRAME FORMAT
// Fall back to loading as a single image if the extension is recognized
if FileFormat <> ioUnknown then
begin
// try single image
try
idx := NextInsertionIndex;
Attached_InsertImage( idx );
if assigned(fImageEnMView) then
Result := (fImageEnMView as TImageEnMView).SetImageFromFile(idx, WideString(FileName), 0, FileFormat)
else
Result := GetIEMBitmap.SetImageFromStreamOrFile( idx, nil, WideString(FileName), 0, FileFormat, Self );
GetIEMBitmap.Modified := False;
finally
DoFinishWork();
fAborting := not Result;
end;
end
else
begin
{$ifdef IEINCLUDEDIRECTSHOW}
Result := LoadFromMediaFile(FileName)
{$else}
Result := False;
fAborting := True;
{$endif}
end;
end;
end;
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function TImageEnMIO.LoadFromFileFormat(const FileName: string; FileFormat: TIOFileType): Boolean;
begin
Result := LoadFromFile( Filename, FileFormat );
end;
{$endif}
{!!
<FS>TImageEnMIO.LoadFromFileAuto
<FM>Declaration<FC>
function LoadFromFileAuto(const FileName: string): Boolean;
<FM>Description<FN>
Load an image from file into the attached <A TImageEnMView> or <A TIEMultiBitmap>. To detect the file format it analyzes the file content, it does not use the filename extension.
Result will be false if the file is not a recognized file type (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
ImageEn supports loading of multiple frames from GIF, TIFF, AVI, DCX, DICOM, ICO and CUR formats. Loading of PDF format is also supported if a <L TImageEnMIO.LoadFromFilePDF>relevant plug-in</L> is installed.
Note: Existing content is <FB>not<FN> cleared
<FM>Example<FC>
ImageEnMView1.MIO.LoadFromFileAuto('input.dat');
ImageEnMView1.MIO.LoadFromFileAuto('input.tif'); // a tiff or a RAW?
if ImageEnMView1.MIO.LoadFromFileAuto(sFilename) = False then
ShowMessage('Not a supported file type!');
<FM>See Also<FN>
- <A TImageEnMIO.LoadFromFile>
!!}
function TImageEnMIO.LoadFromFileAuto(const FileName: string): Boolean;
var
ff: TIOFileType;
begin
ff := FindFileFormat(FileName, ffFallbackToExtension);
if ( ff = ioUnknown ) and IEFileExtInExtensions( string(IEExtractFileExtW( FileName )), Supported_MPEG_File_Extensions ) then
ff := ioMPEG
else
if ( ff = ioUnknown ) and IEFileExtInExtensions( string(IEExtractFileExtW( FileName )), Supported_WMV_File_Extensions) then
ff := ioWMV;
Result := LoadFromFile(FileName, ff);
end;
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.SaveToFile
<FM>Declaration<FC>
procedure SaveToFile(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a multi-image format: GIF, TIFF, DCX, ICO, AVI, DICOM, PDF or PS. It detects the file format from the extension.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output to file.
Notes:
- Only multi-frame formats are supported. Saving to a single frame format, such as JPEG, will result in an error (<A TImageEnMIO.Aborting> will return true). To save single frames of a TImageEnMView you can use <A TIEBitmap.Write> for the relevant frame.
- If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
ImageEn supports saving of multiple frames to GIF, TIFF, AVI, DCX, DICOM, ICO, PDF and PS formats.
!!}
procedure TImageEnMIO.SaveToFile(const FileName: string; SelectedOnly: Boolean = False);
begin
if Trim(FileName) = '' then
begin
fAborting := true;
exit;
end;
fAborting := False;
// NOTE: ENSURE THIS ALIGNS WITH IsMultiFrameSaveFormat
case IEFilenameToInternalFileType( FileName, True ) of
ioGIF : SaveToFileGIF(FileName, SelectedOnly);
ioTIFF : SaveToFileTIFF(FileName, SelectedOnly);
ioAVI : SaveToFileAVI(FileName, '', SelectedOnly);
ioPS : SaveToFilePS(FileName, SelectedOnly);
{$ifdef IEINCLUDEPDFWRITING}
iomscWPPDF,
ioPDF : SaveToFilePDF(FileName, SelectedOnly);
{$endif}
ioDCX : SaveToFileDCX(FileName, SelectedOnly);
ioICO : SaveToFileICO(FileName, SelectedOnly);
{$ifdef IEINCLUDEDICOM}
ioDICOM : SaveToFileDICOM(FileName, SelectedOnly);
{$endif}
else fAborting := True;
end;
end;
// Returns true if the specified file type can be saved by TImageEnMIO
function IsMultiFrameSaveFormat(FileType : TIOFileType) : Boolean;
begin
Result := ( FileType = iomscWPPDF ) or // NB: Outside bounds
( FileType in [
ioGIF
, ioTIFF
, ioAVI
, ioPS
{$ifdef IEINCLUDEPDFWRITING}
, ioPDF
{$endif}
, ioDCX
, ioICO
{$ifdef IEINCLUDEDICOM}
, ioDICOM
{$endif}
]);
end;
{!!
<FS>TImageEnMIO.SaveToStream
<FM>Declaration<FC>
procedure SaveToStream(Stream: TStream; FileFormat: <A TIOFileType>; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a multi-image format: GIF, TIFF, DCX, ICO, AVI, DICOM, PDF or PS.
You must specify a <L TIOFileType>file format</L>, which should be one of: ioGIF, ioTIFF, ioPS, ioPDF, ioDICOM, ioDCX, ioICO, ioUnknown (if ioUnknown is specified, the current file type</L is used if it is a multi-image format).
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output to file.
Notes:
- Only multi-frame formats are supported. Saving to a single frame format, such as JPEG, will result in an error (<A TImageEnMIO.Aborting> will return true). To save single frames of a TImageEnMView you can use <A TIEBitmap.Write> for the relevant frame
- If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception
- AVI is <FB>not<FN> supported
!!}
procedure TImageEnMIO.SaveToStream(Stream: TStream; FileFormat: TIOFileType; SelectedOnly: Boolean = False);
begin
if FileFormat = ioUnknown then
begin
FileFormat := IEFilenameToInternalFileType( fLastFilename );
if IsMultiFrameSaveFormat( FileFormat ) = False then
FileFormat := ioTIFF;
end;
fAborting := False;
case FileFormat of
ioGIF : SaveToStreamGIF(Stream, SelectedOnly);
ioTIFF : SaveToStreamTIFF(Stream, SelectedOnly);
// ioAVI : SaveToStreamAVI(Stream, '', SelectedOnly);
ioPS : SaveToStreamPS(Stream, SelectedOnly);
{$ifdef IEINCLUDEPDFWRITING}
iomscWPPDF,
ioPDF : SaveToStreamPDF(Stream, SelectedOnly);
{$endif}
ioDCX : SaveToStreamDCX(Stream, SelectedOnly);
ioICO : SaveToStreamICO(Stream, SelectedOnly);
{$ifdef IEINCLUDEDICOM}
ioDICOM : SaveToStreamDICOM(Stream, SelectedOnly);
{$endif}
else fAborting := True;
end;
end;
/////////////////////////////////////////////////////////////////////////////////////
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnMIO.SelectAcquireSource
<FM>Declaration<FC>
function SelectAcquireSource(Apis : <A TIEAcquireApis> = [ieaTwain, ieaWIA, ieaDCIM]): boolean;
<FM>Description<FN>
Prompt the user with a dialog to select a Twain, WIA or portable device.
Use <FC>Apis<FN> to specify which sources are available to the user. Any combination of the following can be used:
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>ieaTwain</C> <C>Acquire from Twain device</C> </R>
<R> <C>ieaWIA</C> <C>Acquire using WIA (scanners or camera)</C> </R>
<R> <C>ieaDCIM</C> <C>Read from any connected device containing a DCIM folder (e.g. camera card in a slot or a USB connected camera) using the WPD API</C> </R>
</TABLE>
Note: If your location is only [ieTwain] or [ieWIA] then the default Twain/WIA selector is shown. Otherwise a custom device selector is used (Use <A TIEImageEnGlobalSettings.MsgLanguage> to control the language in the custom dialog).
Returns False if user presses the "Cancel" button.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\AllAcquire\AllAcquire.dpr </C> </R>
</TABLE>
<FM>Example<FC>
if ImageEn1.IO.SelectAcquireSource([ieaTwain, ieaWIA, ieaDCIM]) then
ImageEn1.IO.Acquire;
!!}
function TImageEnMIO.SelectAcquireSource(Apis : TIEAcquireApis = [ieaTwain, ieaWIA, ieaDCIM]): boolean;
// NPC: 16/11/11
begin
Result := fAcquireParams.SelectSource(Apis);
end;
{!!
<FS>TImageEnMIO.SetAcquireSource
<FM>Declaration<FC>
function SetAcquireSource(Api : <A TIEAcquireApi>; Location : Variant) : boolean;
<FM>Description<FN>
Programatically set the selected acquisition source by an API type and device. The selected device will be used for subsequent calls to <A TImageEnMIO.Acquire>.
Result is false if the device cannot be selected (i.e. is not connected or does not exist).
The API can be one of the following:
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>ieaTwain</C> <C>Acquire from Twain device</C> </R>
<R> <C>ieaWIA</C> <C>Acquire using WIA (scanners or camera)</C> </R>
<R> <C>ieaDCIM</C> <C>Read from any connected device containing a DCIM folder (e.g. camera card in a slot or a USB connected camera) using the WPD API</C> </R>
</TABLE>
Location can be one of the following:
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>Default_Device</C> <C>The default device for that API type will be selected</C> </R>
<R> <C>Index</C> <C>An index of a device, e.g. 0 for the first device (ieaTwain/ieaWIA/ieaDCIM)</C> </R>
<R> <C>Name</C> <C>The name of a device, e.g. 'CanoScan FB620' (ieaTwain/ieaWIA/ieaDCIM)</C> </R>
<R> <C>Path</C> <C>The path of a DCIM folder, e.g. 'I:\DCIM\' (ieaDCIM)</C> </R>
<R> <C>Drive Letter</C> <C>The letter of a connected camera card or device containing a DCIM folder, e.g. 'I' (ieaDCIM)</C> </R>
</TABLE>
<FM>See Also<FN>
- <A TImageEnMIO.Acquire>
- <A TImageEnMIO.SelectedAcquireSource>
<FM>Examples<FC>
// Acquire from the default Twain device
if ImageEnMView1.MIO.SetAcquireSource(ieaTwain, Default_Device) then
ImageEnMView1.MIO.Acquire;
// Select a Twain scanner by name
ImageEnMView1.MIO.SetAcquireSource(ieaTwain, 'CanoScan FB620');
// Select the second WIA device
ImageEnMView1.MIO.SetAcquireSource(ieaWIA, 1);
// Acquire from the camera card on H drive
if ImageEnMView1.MIO.SetAcquireSource(ieaDCIM, 'H') then
ImageEnMView1.MIO.Acquire;
// Read and restore a source
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
..
// Read the selected device
sDevice := AcquireSourceToStr(ImageEnMView1.MIO.SelectedAcquireSource);
..
end;
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
..
// Restore the device selection
ADevice := StrToAcquireSource(sDevice);
ImageEnMView1.MIO.SetAcquireSource(ADevice.Api, ADevice.Location);
..
end;
!!}
function TImageEnMIO.SetAcquireSource(Api: TIEAcquireApi; Location : Variant) : boolean;
// NPC: 16/11/11
begin
Result := fAcquireParams.SetSource(Api, Location);
end;
{!!
<FS>TImageEnMIO.SelectedAcquireSource
<FM>Declaration<FC>
property SelectedAcquireSource : <A TIEAcquireSource>; (Read-only)
<FM>Description<FN>
Return the acquisition source that is currently active due to selection by the user with <A TImageEnMIO.SelectAcquireSource> or programatically using <A TImageEnMIO.SetAcquireSource>.
A <A TIEAcquireSource> record is returned that provides meta information about the device (SelectedAcquireSource.Name, SelectedAcquireSource.DeviceType) and technical details (SelectedAcquireSource.Api, SelectedAcquireSource.Location).
If no device is selected then SelectedAcquireSource.Api will be ieaNone.
<FM>See Also<FN>
- <A TImageEnMIO.SelectAcquireSource>
- <A TImageEnMIO.SetAcquireSource>
<FM>Examples<FC>
// Display the selected source
if ImageEnMView1.MIO.SelectedAcquireSource.Api = ieaNone then
ShowMessage('No device is selected')
else
ShowMessage('The selected device is ' + ImageEnMView1.MIO.SelectedAcquireSource.Name);
// Read and restore the selected source
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
..
// Read the selected device
sDevice := AcquireSourceToStr(ImageEnMView1.MIO.SelectedAcquireSource);
..
end;
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
..
// Restore the device selection
ADevice := StrToAcquireSource(sDevice);
ImageEnMView1.MIO.SetAcquireSource(ADevice.Api, ADevice.Location);
..
end;
!!}
function TImageEnMIO.GetSelectedAcquireSource : TIEAcquireSource;
// NPC: 16/11/11
begin
Result := fAcquireParams.SelectedSource;
end;
procedure TImageEnMIO.InitializeAcquireSource(bIncludeWIA : Boolean);
// NPC: 16/11/11
begin
AcquireParams.AttachedTwainParams := fTwainParams;
{$IFDEF IEINCLUDEWPD}
AcquireParams.AttachedDCIMParams := fDcimParams;
{$ENDIF}
if bIncludeWIA then
AcquireParams.AttachedWIAParams := WIAParams;
end;
procedure TImageEnMIO.TWMultiCallBack(Bitmap: TIEBitmap; var IOParams: TObject; ImDpiX, ImDpiY: integer);
var
bHandled: boolean; // Flag indicating whether the user has handled the acquired bitmap themselves
bmp: TIEBitmap;
begin
bHandled := false;
if assigned(fOnAcquireBitmap) then
fOnAcquireBitmap(Self, Bitmap, ImDpiX, imDpiY, bHandled);
if bHandled = false then
begin
fTwainNextToInsert := imax(imin(fTwainNextToInsert, GetIEMBitmap.Count), 0);
Attached_InsertImage( fTwainNextToInsert );
IOParams := Params[fTwainNextToInsert];
if (ImDpiX <> 0) and (ImDpiY <> 0) then
begin
Params[fTwainNextToInsert].DpiX := ImDpiX;
Params[fTwainNextToInsert].DpiY := ImDpiY;
end;
if fAutoAdjustDPI then
bmp := IEAdjustDPI(Bitmap, IOParams as TIOParams, fFilteredAdjustDPI)
else
bmp := Bitmap;
Attached_SetIEBitmap( fTwainNextToInsert, bmp );
if bmp <> Bitmap then
FreeAndNil(bmp);
GetIEMBitmap.ImageDelayTime[fTwainNextToInsert] := 100;
if assigned(fOnAfterAcquireBitmap) then
fOnAfterAcquireBitmap(Self, fTwainNextToInsert);
inc(fTwainNextToInsert);
end;
end;
{$endif}
/////////////////////////////////////////////////////////////////////////////////////
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnMIO.Acquire
<FM>Declaration<FC>
function Acquire : boolean;
<FM>Description<FN>
Perform a multiple image acquisition from the <A TImageEnMIO.SelectedAcquireSource>, which may be a camera card, Twain or WIA device.
<A TImageEnMIO.SelectedAcquireSource> is set when the user chooses a source if you have called <A TImageEnMIO.SelectAcquireSource> or manually set a source using <A TImageEnMIO.SetAcquireSource>.
If no image is selected (see <A TImageEnMView.Deselect>) then Acquire will append after the last image.
Returns True if the acquisition succeeds.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\AllAcquire\AllAcquire.dpr </C> </R>
</TABLE>
<FM>Examples<FN>
// Prompt the user to choose a scanner source and then acquire
if ImageEnMView1.MIO.SelectAcquireSource([ieaTwain, ieaWIA, ieaDCIM]) then
ImageEnMView1.MIO.Acquire;
// capture from the default WIA device
if ImageEnMView1.MIO.SetSource(ieaWIA, Default_Device) then
ImageEnMView1.MIO.Acquire;
// select the second Twain device and capture
if ImageEnMView1.MIO.SetSource(ieaTwain, 1) then
ImageEnMView1.MIO.Acquire;
// Capture from the Twain device named, CanoScan FB620
if ImageEnMView1.MIO.SetSource(ieaTwain, 'CanoScan FB620') then
ImageEnMView1.MIO.Acquire;
// Retrieve from the camera card listed as H:\ drive
if ImageEnMView1.MIO.SetSource(ieaDCIM, 'H') then
ImageEnMView1.MIO.Acquire;
// Capture without a dialog
ImageEnMView1.MIO.AcquireParams.VisibleDialog := False;
ImageEnMView1.MIO.Acquire;
!!}
function TImageEnMIO.Acquire : boolean;
begin
result := true;
// calling Acquire after TwainAcquireOpen!!!!
if assigned(fgrec) then
exit; // there is already a scanner dialog open
try
fAborting := False;
if assigned(fImageEnMView) and (( fImageEnMView as TImageEnMView ).SelectedImage >= 0 ) then
fTwainNextToInsert := (fImageEnMView as TImageEnMView).SelectedImage
else
fTwainNextToInsert := GetIEMBitmap.Count;
result := fAcquireParams.Acquire(TWMultiCallBack, fOnProgress, fNativePixelFormat);
Update;
except
result := false;
end;
DoFinishWork();
end;
{$ENDIF}
/////////////////////////////////////////////////////////////////////////////////////
// show the input/output parameters preview dialog
// return True if the user press OK
// if idx=-1 applies the some compression parameters to all images
{$IFDEF IEINCLUDEDIALOGIO}
{!!
<FS>TImageEnMIO.DoPreviews
<FM>Declaration<FC>
function DoPreviews(idx: integer; pp: <A TPreviewParams> = [ppAll]): boolean;
<FM>Description<FN>
Executes the Previews dialog for the image <FC>idx<FN> allowing the user to view and change the parameters of image file formats.
<FC>idx<FN> can also be IEM_ALL_IMAGES to act on all images or IEM_SELECTED_IMAGES to act on the selected images in the attached <A TImageEnMView>.
<FC>pp<FN> is the set of the image format parameters to be displayed by the dialog.
<FM>Example<FC>
ImageEnMView1.Clear; // Clear TImageEnMView
ImageEnMView1.MIO.LoadFromFile( 'C:\myimage.gif' ); // Load GIF image
ImageEnMView1.MIO.DoPreviews( IEM_ALL_IMAGES, [ppGIF] ); // Set GIF parameters (background, transparency...) for ALL images
ImageEnMView1.MIO.SaveToFile( 'D:\newimage.gif' ); // Save image with new parameters
!!}
function TImageEnMIO.DoPreviews(idx: integer; pp: TPreviewParams = [ppAll]): boolean;
var
fIOPreviews: TfIOPreviews;
SrcBitmap: TBitmap;
Handled: boolean;
begin
result := False;
Handled := false;
if assigned(fOnDoPreviews) then
fOnDoPreviews(self, Handled);
if Handled then
exit;
if GetIEMBitmap.Count = 0 then
exit;
if (idx <> IEM_ALL_IMAGES) and assigned( fImageEnMView ) and
((fImageEnMView as TImageEnMView).SelectedImage < 0) then
(fImageEnMView as TImageEnMView).SelectedImage := 0;
if idx = IEM_ALL_IMAGES then
idx := -1 { just in case }
else
if idx = IEM_SELECTED_IMAGES then
begin
if not assigned(fImageEnMView) then
exit;
if (fImageEnMView as TImageEnMView).DisplayMode = mdSingle then
idx := (fImageEnMView as TImageEnMView).VisibleFrame
else
idx := (fImageEnMView as TImageEnMView).SelectedImage;
if idx < 0 then
exit;
end;
SrcBitmap := Attached_GetTIEBitmap( iMax( 0, idx )).VclBitmap;
if not assigned( SrcBitmap ) then
exit;
fIOPreviews := TfIOPreviews.Create(self);
fIOPreviews.DefaultLockPreview := ioppDefaultLockPreview in PreviewsParams;
fIOPreviews.btnApply.Visible := ioppApplyButton in PreviewsParams;
fIOPreviews.Simplified := fSimplifiedParamsDialogs;
fIOPreviews.fDefaultDitherMethod := fDefaultDitherMethod;
fIOPreviews.Params := Params[ iMax( 0, idx ) ];
//
fIOPreviews.UpdateLanguage();
if fPreviewFontEnabled then
fIOPreviews.Font.Assign(fPreviewFont)
else
fIOPreviews.Font.Assign(IEGetDefaultDialogFont);
// Use same mouse wheel settings as owner component
if assigned( fImageEnMView ) and ( fImageEnMView is TImageEnMView ) then
with TImageEnMView( fImageEnMView ) do
begin
fIOPreviews.ienSource. MouseWheelParams.Assign( MouseWheelParams );
fIOPreviews.ienPreview.MouseWheelParams.Assign( MouseWheelParams );
end;
with fIOPreviews.ienSource do
begin
IECopyBitmap(SrcBitmap, Bitmap);
Update;
end;
if fIOPreviews.SetPreviewParams(pp) then
result := fIOPreviews.ShowModal = mrOk
else
result := false;
fIOPreviews.Release;
// duplicate compression parameters
if idx < 0 then
DuplicateCompressionInfo;
Update;
end;
{$ENDIF}
{!!
<FS>TImageEnMIO.DuplicateCompressionInfo
<FM>Declaration<FC>
procedure DuplicateCompressionInfo;
<FM>Description<FN>
Clone the compression information of page 0 to all pages.
!!}
procedure TImageEnMIO.DuplicateCompressionInfo;
begin
fParamsList.DuplicateCompressionInfo;
end;
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.PreviewFont
<FM>Declaration<FC>
property PreviewFont: TFont;
<FM>Description<FN>
If <A TImageEnMIO.PreviewFontEnabled> is set to True then PreviewFont specifies the font used in the Previews dialog. Ensure the size of font matches the labels length.
<FM>Example<FC>
ImageEnMIO1.PreviewFont.Name := 'MS Times New Roman';
ImageEnMIO1.PreviewFontEnabled := True;
!!}
procedure TImageEnMIO.SetPreviewFont(f: TFont);
begin
fPreviewFont.assign(f);
end;
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.PreviewFontEnabled
<FM>Declaration<FC>
property PreviewFontEnabled: Boolean;
<FM>Description<FN>
When True, you can use <A TImageEnMIO.PreviewFont> to specify a custom font for the Preview dialogs.
<FM>Example<FC>
ImageEnMIO1.PreviewFont.Name := 'MS Times New Roman';
ImageEnMIO1.PreviewFontEnabled := True;
!!}
procedure TImageEnMIO.SetPreviewFontEnabled(Value : Boolean);
begin
fPreviewFontEnabled := Value;
end;
/////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.PreviewsParams
<FM>Declaration<FC>
property PreviewsParams: <A TIOPreviewsParams>;
<FM>Description<FN>
Specifies the features of the input/output preview dialog.
<FM>Example<FC>
// Show preview by default
ImageEnMView1.MIO.PreviewsParams := ImageEnMView1.MIO.PreviewsParams + [ ioppDefaultLockPreview ];
!!}
procedure TImageEnMIO.SetIOPreviewParams(v: TIOPreviewsParams);
begin
fPreviewsParams := v;
end;
/////////////////////////////////////////////////////////////////////////////////////
function TImageEnMIO.GetIOPreviewParams: TIOPreviewsParams;
begin
result := fPreviewsParams;
end;
{!!
<FS>TImageEnMIO.ImageEnVersion
<FM>Declaration<FC>
property ImageEnVersion: string;
<FM>Description<FN>
A published property returning the ImageEn version as string.
!!}
function TImageEnMIO.GetImageEnVersion: string;
begin
result := IEMAINVERSION;
end;
procedure TImageEnMIO.SetImageEnVersion(Value: string);
begin
// this is a read-only property, but it must be displayed in object inspector
end;
{$IFDEF IEINCLUDEIEXACQUIRE}
procedure TImageEnMIO.TWCloseCallBack;
begin
fgrec := nil;
if assigned(fOnAcquireClose) then
fOnAcquireClose(self);
end;
{!!
<FS>TImageEnMIO.TwainAcquireOpen
<FM>Declaration<FC>
function TwainAcquireOpen : boolean;
<FM>Description<FN>
Opens a connection to the selected scanner. It is useful for modeless acquisition. Result is false if the method fails.
Whenever ImageEn gets an image the <A TImageEnMIO.OnAcquireBitmap> and <A TImageEnMIO.OnAfterAcquireBitmap> events occur.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\Twain\TwainDemo.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnMIO.TwainAcquireOpen;
..
ImageEnMIO.TwainAcquireClose;
!!}
function TImageEnMIO.TwainAcquireOpen: boolean;
var
tempio: TIOParams;
aParent: TWinControl;
begin
result := false;
if assigned(fgrec) then
exit; // Twain dialog already exists
if assigned(fImageEnMView) and (( fImageEnMView as TImageEnMView ).SelectedImage >= 0 ) then
fTwainNextToInsert := (fImageEnMView as TImageEnMView).SelectedImage
else
fTwainNextToInsert := GetIEMBitmap.Count;
fAborting := false;
fTwainParams.FreeResources;
tempio := TIOParams.Create( nil );
aParent := nil;
if assigned( fImageEnMView ) then
aParent := fImageEnMView;
fgrec := IETWAINAcquireOpen(TWCloseCallBack, TWMultiCallBack, fTwainParams, @fTwainParams.TwainShared, tempio, aParent, fNativePixelFormat);
FreeAndNil(tempio);
result := fgrec <> nil;
end;
// Legacy interface to TwainAcquireOpen
function TImageEnMIO.AcquireOpen: boolean;
begin
result := TwainAcquireOpen;
end;
{$ENDIF}
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnMIO.TwainAcquireClose
<FM>Declaration<FC>
procedure TwainAcquireClose;
<FM>Description<FN>
Closes a connection opened with <A TImageEnMIO.TwainAcquireOpen>. It is useful for modeless acquisition.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\Twain\TwainDemo.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnMIO.TwainAcquireOpen;
..
ImageEnMIO.TwainAcquireClose;
!!}
procedure TImageEnMIO.TwainAcquireClose;
begin
if fgrec <> nil then
begin
IETWAINAcquireClose(fgrec);
fgrec := nil;
end;
end;
// Legacy interface to TwainAcquireClose
procedure TImageEnMIO.AcquireClose;
begin
TwainAcquireClose;
end;
{$ENDIF}
procedure TImageEnMIO.DoFinishWork;
begin
if assigned(fOnProgress) then
fOnProgress(self, 100);
if assigned(fOnFinishWork) then
fOnFinishWork(self);
end;
{$IFDEF IEINCLUDEOPENSAVEDIALOGS}
{!!
<FS>TImageEnMIO.ExecuteOpenDialog
<FM>Declaration<FC>
function ExecuteOpenDialog(const InitialDir : WideString = ''; const InitialFileName : WideString = ''; AlwaysAnimate : boolean = False;
FilterIndex: integer = 0; const ExtendedFilters : WideString = ''; MultiSelect : boolean = False;
const Title : WideString = ''; const Filter : WideString = ''; DefaultFilter : <A TIOFileType> = -1;
LimitToFileType : <A TIOFileType> = -1) : String; overload;
function ExecuteOpenDialog(const Title : WideString; DefaultFilter : <A TIOFileType>; LimitToFileType : <A TIOFileType> = -1; AlwaysAnimate : boolean = False; MultiSelect : boolean = False) : String; overload;
<FM>Description<FN>
Prompts the user with the open dialog to select an image to load. It encapsulates the <A TOpenImageEnDialog> component.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C>InitialDir</C> <C>Folder displayed on opening (leave as '' for no default)</C> </R>
<R> <C>InitialFileName</C> <C>Default file name with extension (leave as '' for no default)</C> </R>
<R> <C>AlwaysAnimate</C> <C>Enable to animate GIF and AVI (without user needing to click the play button). Default is False</C> </R>
<R> <C>FilterIndex</C> <C>The index of the default selected item in the filter (one-based). Default is 0.
Note: While this can change, the first five items are generally:
1: Common graphics formats
2: All Graphics formats
3: JPEG
4: TIFF
5: GIF
However, it is generally safer to use the <FC>DefaultFilter<FN> parameter instead</C> </R>
<R> <C>ExtendedFilters</C> <C>Any additional file formats to add to the filter (example: 'Fun Bitmap|*.fun;*.fan')</C> </R>
<R> <C>MultiSelect</C> <C>Allow selection of multiple files. The returned string will contain a list of filename separated by the "|" character (e.g. 'C:\one.jpg|C:\two.jpg')</C> </R>
<R> <C>Title</C> <C>The dialog title. If unspecified the Windows default title is used</C> </R>
<R> <C>Filter</C> <C>Override the default filter with a custom one (e.g. 'JPEG Image (JPG)|*.jpg|GIF Image (GIF)|*.gif')</C> </R>
<R> <C>DefaultFilter</C> <C>Specify the <L TIOFileType>file type</L> that is displayed by default. This setting overrides <FC>FilterIndex<FN>, but is ignored if you have specified <FC>InitialFileName<FN>. Default is -1</C> </R>
<R> <C>LimitToFileType</C> <C>Limits the filter to a specified <L TIOFileType>ImageEn file type</L>, plus "All Supported Types" and "All Files" (only relevant if Filter is not set)</C> </R>
</TABLE>
Returns a null string ('') if the user clicks Cancel.
<FM>Examples<FC>
// Prompt to load a file into an ImageEnMView
sFilename := ImageEnMView1.MIO.ExecuteOpenDialog;
if sFilename <> '' then
ImageEnMView1.MIO.LoadFromFile(sFileName);
// Prompt to load a file, defaulting to AVI format (second overloaded method)
sFilename := ImageEnMView1.MIO.ExecuteOpenDialog('Select your video', ioAVI);
if sFilename <> '' then
ImageEnMView1.MIO.LoadFromFile(sFileName);
// Prompt to load a file, forcing GIF format (second overloaded method)
sFilename := ImageEnMView1.MIO.ExecuteOpenDialog('Select an Image', -1, ioGIF);
if sFilename <> '' then
ImageEnMView1.MIO.LoadFromFile(sFileName);
!!}
function TImageEnMIO.ExecuteOpenDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False; MultiSelect : boolean = False) : String;
begin
Result := ExecuteOpenDialog('', '', AlwaysAnimate, 0, '', MultiSelect, Title, '', DefaultFilter, LimitToFileType);
end;
function TImageEnMIO.ExecuteOpenDialog(const InitialDir : WideString = ''; const InitialFileName : WideString = ''; AlwaysAnimate : boolean = False;
FilterIndex: integer = 0; const ExtendedFilters : WideString = ''; MultiSelect : boolean = False;
const Title : WideString = ''; const Filter : WideString = ''; DefaultFilter : TIOFileType = -1;
LimitToFileType : TIOFileType = -1) : String;
var
fOpenImageEnDialog: TOpenImageEnDialog;
i: integer;
begin
fOpenImageEnDialog := TOpenImageEnDialog.create(self);
fOpenImageEnDialog.InitialDir := InitialDir;
fOpenImageEnDialog.FileName := InitialFileName;
fOpenImageEnDialog.AlwaysAnimate := AlwaysAnimate;
if Filter<>'' then
begin
fOpenImageEnDialog.AutoSetFilter := false;
fOpenImageEnDialog.Filter := Filter;
end;
fOpenImageEnDialog.AutoSetFilterFileType := LimitToFileType;
fOpenImageEnDialog.FilterDefault := DefaultFilter;
fOpenImageEnDialog.FilterIndex := FilterIndex;
fOpenImageEnDialog.AutoAdjustDPI := AutoAdjustDPI;
fOpenImageEnDialog.FilteredAdjustDPI := FilteredAdjustDPI;
fOpenImageEnDialog.ExtendedFilters := ExtendedFilters;
if MultiSelect then
fOpenImageEnDialog.Options := fOpenImageEnDialog.Options+[ofAllowMultiSelect];
if Title<>'' then
fOpenImageEnDialog.Title := Title;
result := '';
if fOpenImageEnDialog.Execute then
begin
if MultiSelect then
for i := 0 to fOpenImageEnDialog.Files.Count-1 do
begin
result := result+fOpenImageEnDialog.Files[i];
if i<fOpenImageEnDialog.Files.Count-1 then
result := result+'|';
end
else
result := fOpenImageEnDialog.FileName;
end;
FreeAndNil(fOpenImageEnDialog);
end;
{$ENDIF}
{$IFDEF IEINCLUDEOPENSAVEDIALOGS}
{!!
<FS>TImageEnMIO.ExecuteSaveDialog
<FM>Declaration<FC>
function ExecuteSaveDialog(const InitialDir : WideString = ''; const InitialFileName : WideString = ''; AlwaysAnimate : boolean = False;
FilterIndex: integer = 0; const ExtendedFilters : WideString = ''; const Title : WideString = '';
const Filter : WideString = ''; DefaultFilter : <A TIOFileType> = -1; LimitToFileType : <A TIOFileType> = -1) : String; overload;
function ExecuteSaveDialog(const Title : WideString; DefaultFilter : <A TIOFileType>; LimitToFileType : <A TIOFileType> = -1; AlwaysAnimate : boolean = False) : String; overload;
<FM>Description<FN>
Prompts the user with a save dialog to specify a save filename. It encapsulates the <A TSaveImageEnDialog> component.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C>InitialDir</C> <C>Folder displayed on opening (leave as '' for no default)</C> </R>
<R> <C>InitialFileName</C> <C>Default file name with extension (leave as '' for no default)</C> </R>
<R> <C>AlwaysAnimate</C> <C>Enable to animate GIF and AVI (without user needing to click the play button). Default is False</C> </R>
<R> <C>FilterIndex</C> <C>The index of the default selected item in the filter (one-based). Default is 0.
Note: While this can change, the first five items are generally:
1: Common graphics formats
2: All Graphics formats
3: JPEG
4: TIFF
5: GIF
However, it is generally safer to use the <FC>DefaultFilter<FN> parameter instead</C> </R>
<R> <C>ExtendedFilters</C> <C>Any additional file formats to add to the filter (example: 'Fun Bitmap|*.fun;*.fan')</C> </R>
<R> <C>Title</C> <C>The dialog title. If unspecified the Windows default title is used</C> </R>
<R> <C>Filter</C> <C>Override the default filter with a custom one (e.g. 'JPEG Image (JPG)|*.jpg|GIF Image (GIF)|*.gif')</C> </R>
<R> <C>DefaultFilter</C> <C>Specify the <L TIOFileType>file type</L> that is displayed by default. This setting overrides <FC>FilterIndex<FN>, but is ignored if you have specified <FC>InitialFileName<FN>. Default is -1</C> </R>
<R> <C>LimitToFileType</C> <C>Limits the filter to a specified <L TIOFileType>ImageEn file type. Default is -1</L></C> </R>
</TABLE>
Returns a null string ('') if the user clicks Cancel.
<FM>Examples<FC>
// Prompt to save a file in an ImageEnMView
sFilename := ImageEnMView1.MIO.ExecuteSaveDialog;
if sFilename <> '' then
ImageEnMView1.MIO.SaveToFile(sFileName);
// Prompt to save a file, defaulting to TIFF format (second overloaded method)
sFilename := ImageEnMView1.MIO.ExecuteSaveDialog('Save your File', ioTIFF);
if sFilename <> '' then
ImageEnMView1.MIO.SaveToFile(sFileName);
// Prompt to save a file, forcing GIF format (second overloaded method)
sFilename := ImageEnMView1.MIO.ExecuteSaveDialog('Save your File', -1, ioGIF);
if sFilename <> '' then
ImageEnMView1.MIO.SaveToFile(sFileName);
!!}
function TImageEnMIO.ExecuteSaveDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False) : String;
begin
Result := ExecuteSaveDialog('', '', AlwaysAnimate, 0, '', Title, '', DefaultFilter, LimitToFileType);
end;
function TImageEnMIO.ExecuteSaveDialog(const InitialDir : WideString = ''; const InitialFileName : WideString = ''; AlwaysAnimate : boolean = False;
FilterIndex: integer = 0; const ExtendedFilters : WideString = ''; const Title : WideString = '';
const Filter : WideString = ''; DefaultFilter : TIOFileType = -1; LimitToFileType : TIOFileType = -1) : String;
var
fSaveImageEnDialog: TSaveImageEnDialog;
begin
fSaveImageEnDialog := TSaveImageEnDialog.create(self);
fSaveImageEnDialog.InitialDir := InitialDir;
fSaveImageEnDialog.FileName := TFileName(InitialFileName);
fSaveImageEnDialog.AlwaysAnimate := AlwaysAnimate;
fsaveImageEnDialog.AttachedImageEnIO := self;
if Filter<>'' then
begin
fSaveImageEnDialog.AutoSetFilter := false;
fSaveImageEnDialog.Filter := Filter;
end;
fSaveImageEnDialog.AutoSetFilterFileType := LimitToFileType;
fSaveImageEnDialog.FilterDefault := DefaultFilter;
fSaveImageEnDialog.FilterIndex := FilterIndex;
fSaveImageEnDialog.AutoAdjustDPI := AutoAdjustDPI;
fSaveImageEnDialog.FilteredAdjustDPI := FilteredAdjustDPI;
fSaveImageEnDialog.ExtendedFilters := ExtendedFilters;
if Title<>'' then
fSaveImageEnDialog.Title := Title;
if fSaveImageEnDialog.Execute then
result := fSaveImageEnDialog.FileName
else
result := '';
FreeAndNil(fSaveImageEnDialog);
end;
{$ENDIF}
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnMIO.WIAParams
<FM>Declaration<FC>
property WIAParams: <A TIEWia>;
<FM>Description<FN>
Provides access to parameters, dialogs and methods of connected WIA devices.
Note: Use WIAParams only when you need access to WIA specific functionality (when <A TImageEnMIO.SelectedAcquireSource>.Api is ieaWIA). For generic access to all image acquisitions sources (Twain, WIA, etc.) use <A TImageEnMIO.AcquireParams> instead.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\WIAScanner\WIAScanner.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// Acquire an image with a horizontal resolution of 150 dpi from the default WIA device
ImageEnMView1.MIO.SetItemProperty(WIA_IPS_XRES, 150);
if ImageEnMView1.MIO.SetSource(ieaWIA, Default_Device) then
ImageEnMView1.MIO.Acquire;
<FM>See Also<FN>
- <A TIEWia>
- <A TImageEnMIO.AcquireParams>
- <A TImageEnMIO.SelectedAcquireSource>
!!}
function TImageEnMIO.GetWIAParams: TIEWia;
begin
if not assigned(fWIA) then
begin
fWIA := TIEWia.Create(self);
fWIA.OnProgress := WiaOnProgress;
end;
result := fWIA;
end;
function TImageEnMIO.WiaOnProgress(Percentage: integer): boolean;
begin
if assigned(fOnProgress) then
fOnProgress(self, Percentage);
result := not fAborting;
end;
{$ENDIF} // end of IEINCLUDEIEXACQUIRE
{!!
<FS>TImageEnMIO.SaveToStreamPS
<FM>Declaration<FC>
procedure SaveToStreamPS(Stream: TStream);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a stream in PostScript format.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToStreamPS(Stream: TStream; SelectedOnly: Boolean = False);
var
Param: TIOParams;
Progress: TProgressRec;
bmp: TIEBitmap;
NullProgress: TProgressRec;
han: pointer;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
Param := fParamsList.Params[ImgIdx];
if FileIdx = 0 then
han := IEPostScriptCreate(Stream, Param);
Attached_CopyToIEBitmap( ImgIdx, bmp );
bmp.DefaultDitherMethod := fDefaultDitherMethod;
IEPostScriptSave(han, Stream, bmp, Param, NullProgress);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i, imgCount: Integer;
begin
try
fAborting := False;
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
NullProgress := NullProgressRec( Progress.Aborting );
Progress.per1 := 100 / imgCount;
bmp := TIEBitmap.Create;
han := nil;
i := 0;
while not fAborting and (i < imgCount) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
IEPostScriptClose(han, Stream);
FreeAndNil(bmp);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnMIO.SaveToFilePS
<FM>Declaration<FC>
procedure SaveToFilePS(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Creates a multi-page PostScript file with all images in the attached <A TImageEnMView> or <A TIEMultiBitmap>.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output to file.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
// load a multipage TIFF and save back to a multipage PostScript file
ImageEnMView.MIO.LoadFromFile('C:\multipage.tiff');
ImageEnMView.MIO.SaveToFilePS('D:\output.ps');
!!}
procedure TImageEnMIO.SaveToFilePS(const FileName: string; SelectedOnly: Boolean = False);
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmCreate);
try
SaveToStreamPS(fs, SelectedOnly);
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.SaveToStreamPDF
<FM>Declaration<FC>
procedure SaveToStreamPDF(Stream : TStream; SelectedOnly: boolean = false);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a stream in Adobe PDF format.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnMIO.SaveToStreamPDF(Stream: TStream; SelectedOnly : boolean = false);
var
Param: TIOParams;
Progress: TProgressRec;
bmp: TIEBitmap;
NullProgress: TProgressRec;
han: pointer;
imgCount: integer;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
Param := fParamsList.Params[ImgIdx];
if FileIdx = 0 then
han := IEPDFCreate(Param);
Attached_CopyToIEBitmap( ImgIdx, bmp );
bmp.DefaultDitherMethod := fDefaultDitherMethod;
IEPDFSave(han, bmp, Param, NullProgress);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i: integer;
begin
try
fAborting := False;
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
NullProgress := NullProgressRec( Progress.Aborting );
Progress.per1 := 100 / imgCount;
bmp := TIEBitmap.Create;
han := nil;
i := 0;
while not fAborting and (i < imgCount) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
if imgCount > 0 then
Param := fParamsList.Params[0];
IEPDFClose(han, Stream, Param);
FreeAndNil(bmp);
finally
DoFinishWork;
end;
end;
{$endif}
{!!
<FS>TImageEnMIO.SaveToFilePDF
<FM>Declaration<FC>
procedure SaveToFilePDF(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Creates a multipage Adobe PDF file with all images in the attached <A TImageEnMView> or <A TIEMultiBitmap>.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
// load a multipage TIFF and save it as a PDF file
ImageEnMView.MIO.LoadFromFile('C:\multipage.tiff');
ImageEnMView.MIO.SaveToFilePDF('D:\output.pdf');
!!}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnMIO.SaveToFilePDF(const FileName: string; SelectedOnly: Boolean = False);
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmCreate);
try
SaveToStreamPDF(fs, SelectedOnly);
finally
FreeAndNil(fs);
end;
end;
{$endif}
{$IFDEF IEINCLUDEPRINTDIALOGS}
{!!
<FS>TImageEnMIO.DoPrintPreviewDialog
<FM>Declaration<FC>
function DoPrintPreviewDialog(const TaskName: string; PrintAnnotations: boolean; const Caption: string; ThumbnailPrinting: Boolean): boolean;
<FM>Description<FN>
Executes the multi-page print preview dialog. This function is like DoPrintPreviewDialog of <A TImageEnIO>, but allows working with multiple pages.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C>FC>TaskName<FN></C> Specifes the text that describes the task in the Print Manager and network header pages <C> </C> </R>
<R> <C>FC>PrintAnnotations<FN></C> <C> If true and the image contains <L TIOParams.ImagingAnnot>imaging</L> or <L TIOParams.ImageEnAnnot>ImageEn</L> annotations they will be printed </C> </R>
<R> <C>FC>Caption<FN></C> <C> Specifies the caption of the Print Preview dialog </C> </R>
<R> <C>FC>ThumbnailPrinting<FN></C> <C> If true then it defaults to printing of thumbnails, otherwise the default is read from <A TImageEnMIO.PrintPreviewParams> </C> </R>
</TABLE>
Note: The language used in the dialog is controlled by <A TIEImageEnGlobalSettings.MsgLanguage>. The styling can also be adjusted using <A TIEImageEnGlobalSettings.UseButtonGlyphsInDialogs>
<FM>See Also<FN>
- <A TImageEnMIO.PrintPreviewParams>
- <A TImageEnMIO.DialogsMeasureUnit>
<FM>Example<FC>
ImageEnMView1.MIO.DoPrintPreviewDialog('');
!!}
function TImageEnMIO.DoPrintPreviewDialog(const TaskName: string; PrintAnnotations: boolean; const Caption: string; ThumbnailPrinting: Boolean): boolean;
var
fieprnform: tfieprnform3;
begin
if fResetPrinter then
try
IEResetPrinter();
except
MessageDlg('The Print Preview could not be displayed because a printer has not been configured on this computer.', mtError, [mbOK], 0);
result := false;
exit;
end;
fieprnform := TfiePrnForm3.Create(self);
try
fieprnform.mio := self;
if fPreviewFontEnabled then
fieprnform.Font.Assign(fPreviewFont)
else
fieprnform.Font.Assign(IEGetDefaultDialogFont);
fieprnform.fTaskName := TaskName;
fieprnform.fDialogsMeasureUnit := fDialogsMeasureUnit;
fieprnform.fPrintPreviewParams := fPrintPreviewParams;
if ThumbnailPrinting then
fieprnform.fPrintPreviewParams.PrintThumbnails := true;
fieprnform.PrintAnnotations := PrintAnnotations;
if Caption <> '' then
fieprnform.DialogCaption := Caption
else
fieprnform.DialogCaption := iemsg(IEMSG_PRINT);
fieprnform.UpdateLanguage();
result := fieprnform.ShowModal = mrOk;
finally
fieprnform.Release;
end;
end;
{$ENDIF}
{!!
<FS>TImageEnMIO.LoadFromFileICO
<FM>Declaration<FC>
function LoadFromFileICO(const FileName: string): Boolean;
<FM>Description<FN>
Load all images contained in a multi-image ICO file into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
Result will be false if the file is not ICO format (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromFileICO(const FileName: string): Boolean;
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fLoadingFileName := FileName;
Result := LoadFromStreamICO(fs);
finally
fLoadingFileName := '';
fLastFilename := Filename;
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromStreamICO
<FM>Declaration<FC>
function LoadFromStreamICO(Stream: TStream): Boolean;
<FM>Description<FN>
Load all images contained in a multi-image ICO stream into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
The result will be false if an error is encountered, e.g. the file in the stream is not ICO format (<A TImageEnMIO.Aborting> will be true).
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromStreamICO(Stream: TStream): Boolean;
var
p1: int64;
bmp: TIEBitmap;
numi, idx: integer;
Progress, Progress2: TProgressRec;
Param: TIOParams;
im: integer;
tempAlphaChannel: TIEMask;
begin
Result := False;
fAborting := False;
if not IsAttached() then
exit;
try
fImageEnMView_LockPaint();
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress2 := NullProgressRec( fAborting );
p1 := Stream.Position;
idx := NextInsertionIndex;
im := 0;
numi := _EnumICOImStream(Stream);
repeat
Attached_InsertImage( idx );
bmp := TIEBitmap.Create;
try
Param := fParamsList.Params[idx];
Stream.position := p1;
Param.ICO_ImageIndex := im;
Param.IsNativePixelFormat := fNativePixelFormat;
tempAlphaChannel := nil;
ICOReadStream(Stream, bmp, Param, false, Progress2, tempAlphaChannel, false);
if assigned(tempAlphaChannel) then
begin
bmp.AlphaChannel.CopyFromTIEMask(tempAlphaChannel);
FreeAndNil(tempAlphaChannel);
end;
Param.ImageIndex := idx;
Param.FileType := ioICO;
Param.FileName := WideString(fLoadingFileName);
if fAborting then
begin
Attached_DeleteImage( idx );
break;
end;
if numi = 0 then
Attached_DeleteImage( idx )
else
begin
Progress.per1 := 100 / numi;
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageDelayTime[idx] := 100;
end;
finally
FreeAndNil(bmp);
end;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting then
break;
inc(idx);
inc(im);
until im >= numi;
Update;
GetIEMBitmap.Modified := False;
finally
fImageEnMView_UnlockPaint();
DoFinishWork;
end;
Result := Not fAborting;
end;
procedure TImageEnMIO.CheckDPI(p: TIOParams);
begin
if p.DpiX < 2 then
p.DpiX := IEGlobalSettings().DefaultDPIX;
if p.DpiY < 2 then
p.DpiY := IEGlobalSettings().DefaultDPIY;
end;
{!!
<FS>TImageEnMIO.LoadFromFileCUR
<FM>Declaration<FC>
function LoadFromFileCUR(const FileName: string): Boolean;
<FM>Description<FN>
Loads all images contained in an a cursor resource file into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
Result will be false if the file is not CUR format (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromFileCUR(const FileName: string): Boolean;
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fLoadingFileName := FileName;
Result := LoadFromStreamCUR(fs);
finally
fLoadingFileName := '';
fLastFilename := Filename;
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromStreamCUR
<FM>Declaration<FC>
function LoadFromStreamCUR(Stream: TStream): Boolean;
<FM>Description<FN>
Loads all images contained in a multi-image CUR stream into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
The result will be false if an error is encountered, e.g. the file in the stream is not CUR format (<A TImageEnMIO.Aborting> will be true).
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromStreamCUR(Stream: TStream): Boolean;
var
p1: int64;
xbmp, bmp: TIEBitmap;
numi, idx: integer;
Progress, Progress2: TProgressRec;
Param: TIOParams;
im: integer;
tempAlphaChannel: TIEMask;
begin
Result := False;
fAborting := False;
if not IsAttached() then
exit;
try
fImageEnMView_LockPaint();
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress2 := NullProgressRec( fAborting );
p1 := Stream.Position;
idx := NextInsertionIndex;
numi := 1;
im := 0;
While im < numi do
begin
Attached_InsertImage( idx );
bmp := TIEBitmap.Create;
Param := fParamsList.Params[idx];
Stream.position := p1;
Param.CUR_ImageIndex := im;
Param.IsNativePixelFormat := fNativePixelFormat;
tempAlphaChannel := nil;
CURReadStream(Stream, bmp, Param, false, Progress2, tempAlphaChannel, false);
if im = 0 then
numi := Param.ImageCount;
CheckDPI(Param);
if assigned(tempAlphaChannel) then
begin
bmp.AlphaChannel.CopyFromTIEMask(tempAlphaChannel);
FreeAndNil(tempAlphaChannel);
end;
if fAutoAdjustDPI then
xbmp := IEAdjustDPI(bmp, Param, fFilteredAdjustDPI)
else
xbmp := bmp;
if bmp <> xbmp then
FreeAndNil(bmp);
bmp := xbmp;
Param.ImageIndex := idx;
Param.FileType := ioCUR;
Param.FileName := WideString(fLoadingFileName);
if fAborting then
begin
Attached_DeleteImage( idx );
FreeAndNil(bmp);
break;
end;
Progress.per1 := 100 / numi;
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageDelayTime[idx] := 100;
//if xbmp=bmp then xbmp := nil;
FreeAndNil(bmp);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting then
break;
inc(idx);
inc( im );
end;
Update;
GetIEMBitmap.Modified := False;
finally
fImageEnMView_UnlockPaint();
DoFinishWork;
end;
Result := Not fAborting;
end;
{!!
<FS>TImageEnMIO.LoadFromFileDCX
<FM>Declaration<FC>
function LoadFromFileDCX(const FileName: string): Boolean;
<FM>Description<FN>
Loads all images contained in a multi-image DCX file into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
Result will be false if the file is not DCX format (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromFileDCX(const FileName: string): Boolean;
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fLoadingFileName := FileName;
Result := LoadFromStreamDCX(fs);
finally
fLoadingFileName := '';
fLastFilename := Filename;
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromStreamDCX
<FM>Declaration<FC>
function LoadFromStreamDCX(Stream: TStream): Boolean;
<FM>Description<FN>
Loads all images contained in a multi-image DCX stream into the attached <A TImageEnMView> or <A TIEMultiBitmap>.
The result will be false if an error is encountered, e.g. the file in the stream is not DCX format (<A TImageEnMIO.Aborting> will be true).
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromStreamDCX(Stream: TStream): Boolean;
var
p1: int64;
xbmp, bmp: TIEBitmap;
numi, idx: integer;
Progress, Progress2: TProgressRec;
Param: TIOParams;
im: integer;
begin
Result := False;
fAborting := False;
if not IsAttached() then
exit;
try
fImageEnMView_LockPaint();
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress2 := NullProgressRec( fAborting );
p1 := Stream.Position;
idx := NextInsertionIndex;
numi := IEDCXCountStream(Stream);
for im := 0 to numi-1 do
begin
Attached_InsertImage( idx );
bmp := TIEBitmap.Create;
Param := fParamsList.Params[idx];
Stream.position := p1;
Param.DCX_ImageIndex := im;
Param.IsNativePixelFormat := fNativePixelFormat;
IEDCXReadStream(Stream, bmp, Param, Progress2, false);
CheckDPI(Param);
if fAutoAdjustDPI then
xbmp := IEAdjustDPI(bmp, Param, fFilteredAdjustDPI)
else
xbmp := bmp;
if bmp <> xbmp then
FreeAndNil(bmp);
bmp := xbmp;
Param.ImageIndex := idx;
Param.FileType := ioDCX;
Param.FileName := WideString(fLoadingFileName);
if fAborting then
begin
Attached_DeleteImage( idx );
FreeAndNil(bmp);
break;
end;
Progress.per1 := 100 / numi;
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageDelayTime[idx] := 100;
//if xbmp=bmp then xbmp := nil;
FreeAndNil(bmp);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting then
break;
inc(idx);
end;
Update;
GetIEMBitmap.Modified := False;
finally
fImageEnMView_UnlockPaint();
DoFinishWork;
end;
Result := Not fAborting;
end;
{!!
<FS>TImageEnMIO.SaveToFileDCX
<FM>Declaration<FC>
procedure SaveToFileDCX(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> as a DCX file.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToFileDCX(const FileName: string; SelectedOnly: Boolean = False);
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmCreate);
try
SaveToStreamDCX(fs, SelectedOnly);
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.SaveToStreamDCX
<FM>Declaration<FC>
procedure SaveToStreamDCX(Stream: TStream; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a stream in DCX format.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToStreamDCX(Stream: TStream; SelectedOnly: Boolean = False);
var
p1: int64;
Param: TIOParams;
Progress: TProgressRec;
bmp: TIEBitmap;
NullProgress: TProgressRec;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
Param := fParamsList.Params[ImgIdx];
Param.DCX_ImageIndex := FileIdx;
Stream.position := p1;
Attached_CopyToIEBitmap( ImgIdx, bmp );
bmp.DefaultDitherMethod := fDefaultDitherMethod;
IEDCXInsertStream(Stream, bmp, Param, NullProgress);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i, imgCount: Integer;
begin
try
fAborting := False;
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
NullProgress := NullProgressRec( Progress.Aborting );
p1 := Stream.Position;
Progress.per1 := 100 / imgCount;
bmp := TIEBitmap.Create;
i := 0;
while not fAborting and (i < imgCount) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
FreeAndNil(bmp);
finally
DoFinishWork;
end;
end;
{$ifdef IEINCLUDEDICOM}
{!!
<FS>TImageEnMIO.LoadFromFileDICOM
<FM>Declaration<FC>
function LoadFromFileDICOM(const FileName: string): Boolean;
<FM>Description<FN>
Loads a DICOM image or a multipage DICOM into the attached <A TImageEnMView> or <A TIEMultiBitmap>. This method is necessary when the DICOM file hasn't extension and hasn't a valid DICOM header, but you are sure that is a DICOM file.
Result will be false if the file is not DICOM format (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Notes:
- DICOM parameters are stored in <A TIOParams.DICOM_Tags>
- Existing content is <FB>not<FN> cleared
<FM>Example<FC>
ImageEnMView1.MIO.LoadFromFileDICOM('heart-sequence');
!!}
function TImageEnMIO.LoadFromFileDICOM(const FileName: string): Boolean;
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fLoadingFileName := FileName;
Result := LoadFromStreamDICOM(fs);
finally
fLoadingFileName := '';
fLastFilename := Filename;
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromStreamDICOM
<FM>Declaration<FC>
function TImageEnMIO.LoadFromStreamDICOM(Stream: TStream): Boolean;
<FM>Description<FN>
Loads a DICOM image or sequence of images from stream into the attached <A TImageEnMView> or <A TIEMultiBitmap>. The result will be false if an error is encountered, e.g. the file in the stream is not DICOM format (<A TImageEnMIO.Aborting> will be true).
Notes:
- DICOM parameters are stored in <A TIOParams.DICOM_Tags>
- Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromStreamDICOM(Stream: TStream): Boolean;
var
p1: int64;
xbmp, bmp: TIEBitmap;
numi, idx: integer;
Progress, Progress2: TProgressRec;
Param: TIOParams;
im: integer;
readContext: TDICOMReadContext;
begin
Result := False;
fAborting := False;
if not IsAttached() then
exit;
readContext := nil;
try
fImageEnMView_LockPaint();
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress2 := NullProgressRec( fAborting );
p1 := Stream.Position;
idx := NextInsertionIndex;
numi := IEDicomImageCount(Stream);
for im := 0 to numi - 1 do
begin
Attached_InsertImage( idx );
Param := fParamsList.Params[idx];
Stream.position := p1;
Param.ImageIndex := im;
Param.IsNativePixelFormat := fNativePixelFormat;
bmp := TIEBitmap.Create();
try
if im = 0 then
begin
readContext := TDICOMReadContext.Create(Stream, Progress2);
readContext.ReadHeader();
readContext.ReadTags(Param);
end;
readContext.GetImage(bmp, Param, false);
except
bmp.Free();
end;
CheckDPI(Param);
if fAutoAdjustDPI then
xbmp := IEAdjustDPI(bmp, Param, fFilteredAdjustDPI)
else
xbmp := bmp;
if bmp <> xbmp then
FreeAndNil(bmp);
bmp := xbmp;
Param.ImageIndex := idx;
Param.FileType := ioDICOM;
Param.FileName := WideString(fLoadingFileName);
if fAborting then
begin
Attached_DeleteImage( idx );
FreeAndNil(bmp);
break;
end;
Progress.per1 := 100 / numi;
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageDelayTime[idx] := 100;
FreeAndNil(bmp);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting then
break;
inc(idx);
end;
Update;
GetIEMBitmap.Modified := False;
finally
readContext.Free();
fImageEnMView_UnlockPaint();
DoFinishWork();
end;
Result := Not fAborting;
end;
{!!
<FS>TImageEnMIO.SaveToFileDICOM
<FM>Declaration<FC>
procedure SaveToFileDICOM(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> as a DICOM file.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToFileDICOM(const FileName: string; SelectedOnly: Boolean = False);
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmCreate);
try
SaveToStreamDICOM(fs, SelectedOnly);
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.SaveToStreamDICOM
<FM>Declaration<FC>
procedure SaveToStreamDICOM(Stream: TStream; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a stream in DICOM format.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToStreamDICOM(Stream: TStream; SelectedOnly: Boolean = False);
var
Param: TIOParams;
Progress: TProgressRec;
bmp: TIEBitmap;
NullProgress: TProgressRec;
ParamBitsPerSample, ParamSamplesPerPixel, ParamWidth, ParamHeight: integer;
context: pointer;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
Param := fParamsList.Params[ImgIdx];
Param.ImageIndex := FileIdx;
Attached_CopyToIEBitmap( ImgIdx, bmp );
bmp.DefaultDitherMethod := fDefaultDitherMethod;
if not ( bmp.PixelFormat in [ ie1g, ie8g, ie16g, ie24RGB ]) then
raise EIEException.Create('DICOM saving: unsupported pixel format');
IEPixelFormatToBPSAndSPP( bmp.PixelFormat, ParamBitsPerSample, ParamSamplesPerPixel );
ParamWidth := bmp.Width;
ParamHeight := bmp.Height;
if FileIdx = 0 then
begin
Param.BitsPerSample := ParamBitsPerSample;
Param.SamplesPerPixel := ParamSamplesPerPixel;
Param.Width := ParamWidth;
Param.Height := ParamHeight;
context := IEDicomWrite_init(Stream, Param, GetIEMBitmap.Count, Progress);
end
else
if (Param.BitsPerSample <> ParamBitsPerSample) or (Param.SamplesPerPixel <> ParamSamplesPerPixel) or (Param.Width <> ParamWidth) or (Param.Height <> ParamHeight) then
raise EIEException.Create('DICOM saving: different images');
IEDicomWrite_addImage(context, bmp);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i, imgCount: Integer;
begin
ParamBitsPerSample := 0;
ParamSamplesPerPixel := 0;
context := nil;
bmp := nil;
try
fAborting := False;
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
NullProgress := NullProgressRec( Progress.Aborting );
Progress.per1 := 100 / imgCount;
bmp := TIEBitmap.Create;
i := 0;
while not fAborting and (i < imgCount) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
finally
IEDicomWrite_finalize(context);
FreeAndNil(bmp);
DoFinishWork;
end;
end;
{$endif}
{$IFDEF IEINCLUDEMISCPLUGINS}
{!!
<FS>TImageEnMIO.LoadFromFilePDF
<FM>Declaration<FC>
function LoadFromFilePDF(const FileName: string): Boolean;
<FM>Description<FN>
Loads a PDF image or a multipage PDF into the attached <A TImageEnMView> or <A TIEMultiBitmap> using either the <A TIEMiscPluginsImageMagick> plug-in or the <L http://www.imageen.com/WPPDF/>WPPDF commercial plug-in</L>.
This method is necessary when the PDF file hasn't extension and hasn't a valid PDF header, but you are sure that is a PDF file.
Result will be false if the file is not PDF format or no PDF plug-ins are available (<A TImageEnMIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: Existing content is <FB>not<FN> cleared
<FM>Example<FC>
ImageEnMView1.Clear;
ImageEnMView1.MIO.LoadFromFilePDF('c:\test.pdf');
!!}
function TImageEnMIO.LoadFromFilePDF(const FileName: string): Boolean;
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fLoadingFileName := FileName;
Result := LoadFromStreamPDF(fs);
finally
fLoadingFileName := '';
fLastFilename := Filename;
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromStreamPDF
<FM>Declaration<FC>
function TImageEnMIO.LoadFromStreamPDF(Stream: TStream): Boolean;
<FM>Description<FN>
Loads a PDF from a stream into the attached <A TImageEnMView> or <A TIEMultiBitmap> using either the <A TIEMiscPluginsImageMagick> plug-in or the <L http://www.imageen.com/WPViewPDF/>WPViewPDF commercial plug-in</L>.
The result will be false if an error is encountered, e.g. the file in the stream is not PDF format or a PDF plug-in is not found(<A TImageEnMIO.Aborting> will be true).
Note: Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromStreamPDF(Stream: TStream): Boolean;
var
p1: int64;
xbmp, bmp: TIEBitmap;
numi, idx: integer;
Progress, Progress2: TProgressRec;
Param: TIOParams;
im: integer;
fpi: TIEFileFormatInfo;
begin
Result := False;
fAborting := False;
if not IsAttached() then
exit;
if ( IEFileFormatGetInfo( iomscPDF ) = nil ) and
( IEFileFormatGetInfo( iomscWPPDF ) = nil ) then
begin
fAborting := True;
exit;
end;
fpi := IEFileFormatGetInfo( iomscWPPDF );
if fpi = nil then
fpi := IEFileFormatGetInfo( iomscPDF );
if fpi = nil then
begin
fAborting := True;
exit;
end;
try
fImageEnMView_LockPaint();
Progress := ProgressRec( Self, fOnProgress, fAborting );
Progress2 := NullProgressRec( fAborting );
p1 := Stream.Position;
idx := NextInsertionIndex;
numi := IEPDFFrameCount( Stream );
for im := 0 to numi - 1 do
begin
Attached_InsertImage( idx );
Param := fParamsList.Params[idx];
Stream.position := p1;
Param.ImageIndex := im;
Param.IsNativePixelFormat := fNativePixelFormat;
bmp := TIEBitmap.Create();
try
fpi.ReadFunction(Stream, bmp, Param, Progress2, False);
except
bmp.Free();
end;
CheckDPI(Param);
if fAutoAdjustDPI then
xbmp := IEAdjustDPI(bmp, Param, fFilteredAdjustDPI)
else
xbmp := bmp;
if bmp <> xbmp then
FreeAndNil(bmp);
bmp := xbmp;
Param.ImageIndex := idx;
Param.FileType := fpi.FileType;
Param.FileName := WideString(fLoadingFileName);
if fAborting then
begin
Attached_DeleteImage( idx );
FreeAndNil(bmp);
break;
end;
Progress.per1 := 100 / numi;
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageDelayTime[idx] := 100;
FreeAndNil(bmp);
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting then
break;
inc(idx);
end;
Update;
GetIEMBitmap.Modified := False;
finally
fImageEnMView_UnlockPaint();
DoFinishWork();
end;
Result := Not fAborting;
end;
{$endif}
{$ifdef IEINCLUDEDIRECTSHOW}
{!!
<FS>TImageEnMIO.LoadFromMediaFile
<FM>Declaration<FC>
procedure LoadFromMediaFile(const FileName: string); dynamic;
<FM>Description<FN>
Load a video using DirectShow. It allows loading of video formats that ImageEn does not natively support such as WMV and MPEG. It is also useful with AVI files when <A TImageEnMIO.LoadFromFileAVI> fails.
!!}
function TImageEnMIO.LoadFromMediaFile(const FileName: string) : Boolean;
var
dshow: TIEDirectShow;
idx, i, l: integer;
Progress: TProgressRec;
Param: TIOParams;
bmp: TIEBitmap;
rate: double;
avgtime, ltime: int64;
mul: integer;
begin
Result := False;
if not IsAttached() then
exit;
fAborting := False;
Progress := ProgressRec( Self, fOnProgress, fAborting );
bmp := TIEBitmap.Create;
dshow := TIEDirectShow.Create;
try
fImageEnMView_LockPaint();
dshow.FileInput := AnsiString(FileName);
dshow.EnableSampleGrabber := true;
dshow.Connect;
dshow.Pause;
dshow.TimeFormat := tfTime;
ltime := dshow.Duration;
if (ltime=0) then
begin
fAborting := true;
exit;
end;
dshow.TimeFormat := tfFrame;
l := dshow.Duration;
avgtime := dshow.GetAverageTimePerFrame;
idx := NextInsertionIndex;
if l=ltime then
begin
l := l div avgtime;
mul := avgtime;
end
else
mul := 1;
rate := (ltime/10000000)/l*100;
Progress.per1 := 100 / l;
for i := 0 to l-1 do
begin
Attached_InsertImage( idx );
Param := fParamsList.Params[idx];
Param.ImageIndex := idx;
Param.FileType := ioUnknown;
Param.FileName := WideString(FileName);
Param.IsNativePixelFormat := fNativePixelFormat;
dshow.position := int64(i) * int64(mul);
dshow.GetSample( bmp );
Attached_SetIEBitmap( idx, bmp );
GetIEMBitmap.ImageDelayTime[idx] := trunc(rate);
if i = 0 then
begin
if assigned( fImageEnMView ) and (( fImageEnMView as TImageEnMView ).StoreType <> ietNormal ) then
// Thumbnails
GetIEMBitmap.PrepareSpaceFor(( fImageEnMView as TImageEnMView ).ThumbWidth,
( fImageEnMView as TImageEnMView ).ThumbHeight,
bmp.BitCount, l - 1)
else
// Full size
GetIEMBitmap.PrepareSpaceFor(bmp.Width, bmp.Height, bmp.BitCount, l - 1);
end;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * i));
if fAborting then
break;
inc(idx);
end;
dshow.Disconnect;
Update;
GetIEMBitmap.Modified := False;
finally
fLastFilename := Filename;
FreeAndNil(dshow);
FreeAndNil(bmp);
fImageEnMView_UnlockPaint();
DoFinishWork;
end;
Result := Not fAborting;
end;
{$endif}
{!!
<FS>TImageEnMIO.Params
<FM>Declaration<FC>
property Params[idx: integer]: <A TIOParams>;
<FM>Description<FN>
Provides access to the <A TIOParams> object for the image <FC>idx<FN> to modify image parameters (e.g. bits per sample, compression, etc).
The parameters are updated when you load from files or streams. You can modify these parameters before saving images.
Note: If this TImageEnMIO is connected to a TImageEnMView which is being filled "on demand", then <fc>Params<FN> will not be valid until the image is loaded. Either use the <A TImageEnMView.OnImageLoaded> to delay until the image/params are ready, or force loading by using <A TImageEnMView.EnsureImageLoaded>
<FM>Example<FC>
// Change the compression type of a TIFF and save it
for I := 0 to ImageEnMIO1.ParamsCount - 1 do
ImageEnMIO1.Params[ I ].TIFF_Compression := ioTIFF_G4FAX;
ImageEnMIO1.SaveToFileTIFF( ... );
!!}
function TImageEnMIO.GetParams(idx: integer): TIOParams;
begin
if ( GetIEMBitmap <> nil ) and GetIEMBitmap.ParamsEnabled then
Result := GetIEMBitmap.Params[ idx ]
else
result := fParamsList.Params[ idx ];
end;
function TImageEnMIO.IsAttached: Boolean;
begin
Result := Assigned( fImageEnMView ) or Assigned( fIEMBitmap );
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// load from url
{!!
<FS>TImageEnMIO.LoadFromURL
<FM>Declaration<FC>
procedure LoadFromURL(URL: string);
<FM>Description<FN>
Load a multi-page file from the network using the HTTP or FTP protocol. URL must have the syntax:
'http://domain[:port]/resource'
'https://domain[:port]/resource'
'ftp://user:password@domain[:port]/resource'
It is possible to set proxy parameters using <A TIEImageEnGlobalSettings.ProxyAddress>, <A TIEImageEnGlobalSettings.ProxyUser> and <A TIEImageEnGlobalSettings.ProxyPassword> properties.
Note: This function doesn't support password authentication for HTTP, while it is necessary for FTP (also connecting to anonymous server).
<FM>Example<FC>
// load from standard port 80
ImageEnMView.MIO.LoadFromURL('http://www.imageen.com/image.gif');
// load from port 8080
ImageEnMView.MIO.LoadFromURL('http://www.imageen.com:8080/image.gif');
// load from FTP
ImageEnMView.MIO.LoadFromURL('ftp://space:shuttle@ftp.imageen.com/Pictures/test.jpg')
!!}
function TImageEnMIO.LoadFromURL(URL: string): Boolean;
var
ms: TMemoryStream;
ft: TIOFileType;
tempf: string;
fileext: string;
begin
Result := False;
fAborting := false;
ms := TMemoryStream.Create();
try
if not IEGetFromURL(URL, ms, IEGlobalSettings().ProxyAddress, IEGlobalSettings().ProxyUser, IEGlobalSettings().ProxyPassword, fOnProgress, self, @fAborting, FileExt) then
begin
fAborting := true;
DoFinishWork();
end
else
begin
fLoadingFileName := URL;
ms.Position := 0;
fAborting := False;
ft := FindStreamFormat(ms);
if ft = ioUnknown then
ft := IEFilenameToFileFormat( URL );
case ft of
ioGIF : Result := LoadFromStreamGIF(ms);
ioTIFF : Result := LoadFromStreamTIFF(ms);
ioICO : Result := LoadFromStreamICO(ms);
ioCUR : Result := LoadFromStreamCUR(ms);
ioDCX : Result := LoadFromStreamDCX(ms);
{$ifdef IEINCLUDEDICOM}
ioDICOM : Result := LoadFromStreamDICOM(ms);
{$endif}
else
begin
// format not loadable from stream, need to save in a temporary file
tempf := string(IEGetTempFileName2) + '.' + fileExt;
ms.SaveToFile(tempf);
FreeAndNil(ms);
Result := LoadFromFile(tempf);
DeleteFile(tempf);
end;
end;
end;
finally
fLoadingFileName := '';
if assigned(ms) then
FreeAndNil(ms);
end;
end;
// load from url
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnMIO.LoadFromBuffer
<FM>Declaration<FC>
procedure LoadFromBuffer(Buffer: pointer; BufferSize: integer; Format: <A TIOFileType> = ioUnknown);
<FM>Description<FN>
Load an image or a multi-page image from the specified buffer.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>Buffer<FN></C> <C>The buffer pointer.</C> </R>
<R> <C><FC>BufferSize<FN></C> <C>The buffer length in bytes.</C> </R>
<R> <C><FC>Format<FN></C> <C>Specifies the expected file format. If Format is ioUnknown, then try to find the format automatically.</C> </R>
</TABLE>
<FM>Example<FC>
ImageEnMView1.MIO.LoadFromBuffer(mybuffer, mybufferlength, ioJPEG);
!!}
procedure TImageEnMIO.LoadFromBuffer(Buffer: pointer; BufferSize: integer; Format: TIOFileType);
var
stream: TIEMemStream;
begin
stream := TIEMemStream.Create(Buffer, BufferSize);
try
LoadFromStream(stream, Format);
finally
FreeAndNil(stream);
end;
end;
{!!
<FS>TImageEnMIO.LoadFromStream
<FM>Declaration<FC>
function LoadFromStream(Stream: TStream; FileFormat: <A TIOFileType> = ioUnknown): Boolean;
<FM>Description<FN>
Load an image (or multiple image) from the specified stream into the attached <A TImageEnMView> (at <A TImageEnMView.SelectedImage>) or <A TIEMultiBitmap>.
If <FC>FileFormat<FN> is <FC>ioUnknown<FN> the file format is detected by reading the image header (using <A FindStreamFormat>).
The result will be false if an error is encountered, e.g. the file in the stream is not a recognized format (<A TImageEnMIO.Aborting> will be true).
Notes:
- AVI is <FB>not<FN> supported
- Existing content is <FB>not<FN> cleared
!!}
function TImageEnMIO.LoadFromStream(Stream: TStream; FileFormat: TIOFileType = ioUnknown): Boolean;
var
idx: integer;
lp: int64;
begin
Result := False;
if FileFormat = ioUnknown then
begin
lp := Stream.Position;
FileFormat := FindStreamFormat(Stream);
Stream.Position := lp;
end;
case FileFormat of
ioGIF : Result := LoadFromStreamGIF(Stream);
ioTIFF : Result := LoadFromStreamTIFF(Stream);
//ioAVI : Result := LoadFromStreamAVI(Stream); // not supported
ioICO : Result := LoadFromStreamICO(Stream);
ioCUR : Result := LoadFromStreamCUR(Stream);
ioDCX : Result := LoadFromStreamDCX(Stream);
{$ifdef IEINCLUDEDICOM}
ioDICOM : Result := LoadFromStreamDICOM(Stream);
{$endif}
{$IFDEF IEINCLUDEMISCPLUGINS}
iomscWPPDF,
iomscPDF: Result := LoadFromStreamPDF(Stream);
{$endif}
else
begin
if FileFormat <> ioUnknown then
begin
// try single image
idx := NextInsertionIndex;
Attached_InsertImage( idx );
if assigned(fImageEnMView) then
(fImageEnMView as TImageEnMView).SetImageFromStream(idx, Stream)
else
GetIEMBitmap.SetImage(idx, Stream);
Result := Not fAborting;
end
end;
end;
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function TImageEnMIO.LoadFromStreamFormat(Stream: TStream; FileFormat: TIOFileType): Boolean;
begin
Result := LoadFromStream( Stream, FileFormat );
end;
{$endif}
{!!
<FS>TImageEnMIO.LoadFromFiles
<FM>Declaration<FC>
procedure LoadFromFiles(const FileName: string; AutoDetect: boolean=false; LoadWhenViewed: boolean=false);
<FM>Description<FN>
Loads multiple files separated by '|' character.
If AutoDetect is true then ImageEn tries to detect file type from header, otherwise it looks only the file extension.
If LoadWhenViewed is true each file is actually loaded only when it needs to be displayed.
Note: Existing content is <FB>not<FN> cleared
<FM>Examples<FC>
// Load three files
ImageEnMView1.MIO.LoadFromFiles('one.jpg|two.jpg|three.jpg');
// Execute the open dialog and load the returned list of selected files
filenames := ImageEnMView1.MIO.ExecuteOpenDialog('', '', true, 1, '', true);
ImageEnMView1.MIO.LoadFromFiles(filenames);
!!}
procedure TImageEnMIO.LoadFromFiles(const FileName: string; AutoDetect: boolean; LoadWhenViewed: boolean);
var
sl: TStringList;
p1, p2, idx: integer;
begin
sl := TStringList.Create;
fImageEnMView_LockPaint();
try
p1 := 1;
p2 := 1;
while p2<=length(FileName) do
begin
if (FileName[p2]='|') then
begin
sl.Add( Trim(Copy(string(FileName), p1, p2-p1)) );
p1 := p2+1;
end;
inc(p2);
end;
if (p1<>p2) then
sl.Add( Trim(Copy(string(FileName), p1, p2-p1+1)) );
for p1 := 0 to sl.Count-1 do
begin
idx := NextInsertionIndex;
if AutoDetect then
LoadFromFileAuto( sl[p1] )
else
if LoadWhenViewed and assigned( fImageEnMView ) then
begin
// note 1: if the file contains multiple pages only the first one is loaded
// note 2: the image is added at the end of the image list
idx := GetIEMBitmap.count;
Attached_InsertImage( idx ); // Append to end
( fImageEnMView as TImageEnMView ).ImageFileName[idx] := sl[p1]+'::0';
end
else
LoadFromFile( sl[p1] );
if assigned( fImageEnMView ) then
( fImageEnMView as TImageEnMView ).ImageBottomText[idx] := ExtractFilename(sl[p1]);
if assigned(fOnProgress) then
fOnProgress(self, trunc(p1 / sl.Count * 100));
end;
finally
fImageEnMView_UnlockPaint();
sl.free;
end;
end;
{!!
<FS>TImageEnMIO.PrintImagePos
<FM>Declaration<FC>
procedure PrintImagePos(ImageIndex: integer; PrtCanvas: TCanvas; x, y: double; Width, Height: double; GammaCorrection: double = 1.0; PrintAnnotations: boolean = False);
<FM>Description<FN>
Print the specified image at an absolute position and size.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>ImageIndex<FN></C> <C>Index of the page/image to print (0 = first image). <FC>IEM_SELECTED_IMAGES<FN> can be specified for <FC>ImageIndex<FN> to print all images that the user has selected in the TImageEnMView or <FC>IEM_ALL_IMAGES<FN> to print all images in the TImageEnMView</C> </R>
<R> <C><FC>PrtCanvas<FN></C> <C>The printing canvas. Specify nil to use the Printer.Canvas</C> </R>
<R> <C><FC>x<FN></C> <C>Left position to print image (in inches)</C> </R>
<R> <C><FC>y<FN></C> <C>Top position to print image (in inches)</C> </R>
<R> <C><FC>Width<FN></C> <C>Width to print image (in inches)</C> </R>
<R> <C><FC>Height<FN></C> <C>Height to print image (in inches)</C> </R>
<R> <C><FC>GammaCorrection<FN></C> <C> Level of gamma correction, use 1 to disable gamma correction</C> </R>
<R> <C>FC>PrintAnnotations<FN></C> <C> If true and the image contains <L TIOParams.ImagingAnnot>imaging</L> or <L TIOParams.ImageEnAnnot>ImageEn</L> annotations they will be printed </C> </R>
</TABLE>
<FM>Example<FC>
// print the image first page at the position 2, 2 and height 10 and width 10 (stretch the image)
Printer.BeginDoc;
ImageEnMView1.MIO.PrintImagePos(0, Printer.Canvas, 2, 2, 10, 10, 1);
Printer.EndDoc;
!!}
procedure TImageEnMIO.PrintImagePos(ImageIndex: integer; PrtCanvas: TCanvas; x, y: double; Width, Height: double; GammaCorrection: double = 1.0; PrintAnnotations: boolean = False);
var
bmp: TIEBitmap;
io: TImageEnIO;
begin
bmp := Attached_GetTIEBitmap( ImageIndex );
io := TImageEnIO.CreateFromBitmap(bmp);
if PrintAnnotations then
io.Params.Assign( GetParams( ImageIndex ));
io.Params.DpiX := Params[ImageIndex].DpiX;
io.Params.DpiY := Params[ImageIndex].DpiY;
try
io.PrintImagePos(PrtCanvas, x, y, Width, Height, GammaCorrection, PrintAnnotations);
finally
Attached_ReleaseBitmap( ImageIndex, false );
io.free;
end;
end;
{!!
<FS>TImageEnMIO.PrintImage
<FM>Declaration<FC>
procedure PrintImage(ImageIndex : integer; PrtCanvas : TCanvas = nil; MarginLeft : double = 1; MarginTop : double = 1; MarginRight : double = 1; MarginBottom : double = 1; VerticalPos : TIEVerticalPos = ievpCenter; HorizontalPos : TIEHorizontalPos = iehpCenter; Size : TIESize = iesFitToPage; SpecWidth : double = 0; SpecHeight : double = 0; GammaCorrection : double = 1; PrintAnnotations: boolean = False);
<FM>Description<FN>
Print the specified image by specifying margins, vertical position, horizonal position and size.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>ImageIndex<FN></C> <C>Index of the page/image to print (0 = first image). <FC>IEM_SELECTED_IMAGES<FN> can be specified for <FC>ImageIndex<FN> to print all images that the user has selected in the TImageEnMView or <FC>IEM_ALL_IMAGES<FN> to print all images in the TImageEnMView</C> </R>
<R> <C><FC>PrtCanvas<FN></C> <C>The printing canvas. Specify nil to use the Printer.Canvas</C> </R>
<R> <C><FC>MarginLeft<FN></C> <C>Left page margin in inches (Specify zero for no margin)</C> </R>
<R> <C><FC>MarginTop<FN></C> <C>Top page margin in inches (Specify zero for no margin)</C> </R>
<R> <C><FC>MarginRight<FN></C> <C>Right page margin in inches (Specify zero for no margin)</C> </R>
<R> <C><FC>MarginBottom<FN></C> <C>Bottom page margin in inches (Specify zero for no margin)</C> </R>
<R> <C><FC>VerticalPos<FN></C> <C>Vertical alignment of the image on the page, e.g. ievpCenter to center</C> </R>
<R> <C><FC>HorizontalPos<FN></C> <C>Horizontal alignment of the image on the page, e.g. iehpCenter to center</C> </R>
<R> <C><FC>Size<FN></C> <C>How the image should be sized for printing</C> </R>
<R> <C><FC>SpecWidth<FN></C> <C>The absolute width of the image in inches if Size = iesSpecifiedSize. The number of pages wide if Size = iesMultiplePages</C> </R>
<R> <C><FC>SpecHeight<FN></C> <C>The absolute height of the image in inches if Size = iesSpecifiedSize. The number of pages high if Size = iesMultiplePages</C> </R>
<R> <C><FC>GammaCorrection<FN></C> <C> Level of gamma correction, use 1 to disable gamma correction</C> </R>
<R> <C>FC>PrintAnnotations<FN></C> <C> If true and the image contains <L TIOParams.ImagingAnnot>imaging</L> or <L TIOParams.ImageEnAnnot>ImageEn</L> annotations they will be printed </C> </R>
</TABLE>
<FM>Example<FC>
// Print the first image in center of the page with original sizes
Printer.BeginDoc;
ImageEnMView1.MIO.PrintImage(0, Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesNormal, 0, 0, 1);
Printer.EndDoc;
// Print the selected image(s) stretched to the page center (respecting the proportions)
Printer.BeginDoc;
ImageEnMView1.MIO.PrintImage(IEM_SELECTED_IMAGES, Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesFitToPage, 0, 0, 1);
Printer.EndDoc;
// Print the first image as a poster, four pages wide and six pages high
Printer.BeginDoc;
ImageEnMView1.MIO.PrintImage(0, Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesMultiplePages, 4, 6, 1);
Printer.EndDoc;
!!}
procedure TImageEnMIO.PrintImage(ImageIndex: integer; PrtCanvas: TCanvas; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; VerticalPos: TIEVerticalPos; HorizontalPos: TIEHorizontalPos; Size: TIESize ; SpecWidth: double; SpecHeight: double; GammaCorrection: double; PrintAnnotations: boolean);
var
bPrintedPage: Boolean;
I: Integer;
procedure _PrintImage(idx : Integer);
var
bmp: TIEBitmap;
io: TImageEnIO;
begin
if bPrintedPage then
Printer.NewPage;
bmp := Attached_GetTIEBitmap( idx );
io := TImageEnIO.CreateFromBitmap(bmp);
if PrintAnnotations then
io.Params.Assign( GetParams( idx ));
io.Params.DpiX := Params[idx].DpiX;
io.Params.DpiY := Params[idx].DpiY;
try
io.PrintImage(PrtCanvas, MarginLeft, MarginTop, MarginRight, MarginBottom, VerticalPos, HorizontalPos, Size, SpecWidth, SpecHeight, GammaCorrection, PrintAnnotations);
finally
Attached_ReleaseBitmap( idx, false );
io.free;
end;
bPrintedPage := True;
end;
begin
bPrintedPage := False;
// Selection: Showing only a single frame
if (ImageIndex = IEM_SELECTED_IMAGES) and assigned( fImageEnMView ) and
((fImageEnMView as TImageEnMView).DisplayMode = mdSingle) then
_PrintImage(( fImageEnMView as TImageEnMView ).VisibleFrame )
else
// Selection, but no TImageEnMView
if (ImageIndex = IEM_SELECTED_IMAGES) and ( assigned( fImageEnMView ) = False ) then
_PrintImage( 0 )
else
// Selection
if ImageIndex = IEM_SELECTED_IMAGES then
begin
for I := 0 to GetIEMBitmap.Count - 1 do
if (fImageEnMView as TImageEnMView).IsSelected(I) then
_PrintImage(I);
end
else
// Print all
if ImageIndex = IEM_ALL_IMAGES then
begin
for I := 0 to GetIEMBitmap.Count - 1 do
_PrintImage(I);
end
else
// Print single of index
begin
_PrintImage(ImageIndex);
end;
end;
procedure TImageEnMIO.PrintImagesEx(PrtCanvas: TCanvas; dpix, dpiy: integer; pagewidth, pageheight: double; bPreview: Boolean; Columns: integer; Rows: integer; HorizSpace: double; VertSpace: double; PrintSelected: boolean; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; DrawBox: boolean; DrawText: boolean; DrawShadow: boolean; BoxColor: TColor = clBlack; iPageNo : Integer = 0);
var
bmp, tbmp, xbmp: TIEBitmap;
io: TImageEnIO;
proc: TImageEnProc;
i: integer;
row, col: integer;
ww, hh, t1: double;
bx, by: double;
bw, bh: double;
z: double;
h1, h2, h3: double;
remaining: integer;
iThumbCount: integer;
iStartIndex: Integer;
procedure PrtImg(index: integer);
const
SoftShadow_Radius = 3;
SoftShadow_Offset = 3;
SoftShadow_Intensity = 100;
var
sText : WideString;
begin
bmp := Attached_GetTIEBitmap( index );
try
if DrawShadow then
begin
tbmp.Assign( bmp );
tbmp.PixelFormat := ie24RGB;
if assigned( fImageEnMView ) then
with ( fImageEnMView as TImageEnMView ) do
proc.AddSoftShadow( SoftShadow.Radius, SoftShadow.OffsetX, SoftShadow.OffsetY, true, 0, SoftShadow.Intensity )
else
proc.AddSoftShadow( SoftShadow_Radius, SoftShadow_Offset, SoftShadow_Offset, true, 0, SoftShadow_Intensity );
tbmp.RemoveAlphaChannel(true, clWhite);
xbmp := tbmp;
end
else
xbmp := bmp;
io.AttachedIEBitmap := xbmp;
bx := MarginLeft + col * (ww + HorizSpace);
by := MarginTop + row * (hh + VertSpace);
h1 := 0;
h2 := 0;
h3 := 0;
if DrawText then
begin
sText := GetIEMBitmap.GetImageInfo( index ).TopText;
if sText <> '' then
begin
if assigned( fImageEnMView ) then
PrtCanvas.Font.Assign(( fImageEnMView as TImageEnMView ).TopTextFont);
t1 := PrtCanvas.TextWidth ( sText);
h1 := PrtCanvas.TextHeight( sText );
PrtCanvas.TextOut(trunc((bx+(ww-t1/dpix)/2)*dpix), trunc(by*dpiy), sText );
end;
sText := GetIEMBitmap.GetImageInfo( index ).InfoText;
if sText <> '' then
begin
if assigned( fImageEnMView ) then
PrtCanvas.Font.Assign(( fImageEnMView as TImageEnMView ).InfoTextFont);
t1 := PrtCanvas.TextWidth ( sText);
h1 := PrtCanvas.TextHeight( sText );
PrtCanvas.TextOut(trunc((bx+(ww-t1/dpix)/2)*dpix), trunc((by+hh-h2*2/dpiy)*dpiy), sText );
end;
sText := GetIEMBitmap.GetImageInfo( index ).BottomText;
if sText <> '' then
begin
if assigned( fImageEnMView ) then
PrtCanvas.Font.Assign(( fImageEnMView as TImageEnMView ).BottomTextFont);
t1 := PrtCanvas.TextWidth ( sText);
h1 := PrtCanvas.TextHeight( sText );
PrtCanvas.TextOut(trunc((bx+(ww-t1/dpix)/2)*dpix), trunc((by+hh-h3/dpiy)*dpiy), sText );
end;
end;
h1 := h1 / dpiy;
h2 := h2 / dpiy;
h3 := h3 / dpiy;
z := dmin( ww/(xbmp.Width/dpix), (hh-h1-h2-h3)/(xbmp.Height/dpiy));
bw := xbmp.Width/dpix*z;
bh := xbmp.Height/dpiy*z;
io.PrintImagePosEx(io.AttachedIEBitmap, PrtCanvas, dpix, dpiy, bx+(ww-bw)/2, by+(hh-bh-h1-h2-h3)/2+h1, bw, bh, 1);
if DrawBox then
begin
PrtCanvas.Pen.Color := BoxColor;
PrtCanvas.Pen.Style := psSolid;
PrtCanvas.Brush.Style := bsClear;
PrtCanvas.Rectangle(trunc(bx*dpix), trunc(by*dpiy), trunc((bx+ww)*dpix), trunc((by+hh)*dpiy));
end;
dec(remaining);
inc(col);
if col = Columns then
begin
col := 0;
inc(row);
if row = Rows then
begin
row := 0;
if (bPreview = False) and (remaining > 0) then
Printer.NewPage;
end;
end;
finally
Attached_ReleaseBitmap( index, false );
io.AttachedIEBitmap := nil;
end;
end;
begin
fAborting := false;
try
io := TImageEnIO.Create(nil);
tbmp := TIEBitmap.Create;
proc := TImageEnProc.CreateFromBitmap( tbmp );
row := 0;
col := 0;
ww := (pagewidth-(MarginLeft+MarginRight+HorizSpace*(Columns-1))) / Columns;
hh := (pageheight-(MarginTop+MarginBottom+VertSpace*(Rows-1))) / Rows;
iStartIndex := 0;
if iPageNo > 0 then
iStartIndex := iPageNo * Columns * Rows;
if PrintSelected and assigned( fImageEnMView ) then
begin
// print only selected images
iThumbCount := ( fImageEnMView as TImageEnMView ).MultiSelectedImagesCount - iStartIndex;
if bPreview and (iThumbCount > Columns * Rows) then
iThumbCount := Columns * Rows;
remaining := iThumbCount;
for i := iStartIndex to iStartIndex + iThumbCount - 1 do
begin
PrtImg( ( fImageEnMView as TImageEnMView ).MultiSelectedImages[i] );
if assigned(fOnProgress) then
fOnProgress(self, trunc(i / iThumbCount * 100));
if fAborting then
break;
end
end
else
begin
// print all images
iThumbCount := GetIEMBitmap.Count - iStartIndex;
if bPreview and (iThumbCount > Columns * Rows) then
iThumbCount := Columns * Rows;
remaining := iThumbCount;
for i := iStartIndex to iStartIndex + iThumbCount - 1 do
begin
PrtImg(i);
if assigned(fOnProgress) then
fOnProgress(self, trunc(i / iThumbCount * 100));
if fAborting then
break;
end
end;
finally
tbmp.Free;
proc.Free;
io.Free;
DoFinishWork;
end;
end;
{!!
<FS>TImageEnMIO.PrintImages
<FM>Declaration<FC>
procedure PrintImages(Columns: integer; Rows: integer; HorizSpace: double; VertSpace: double; PrintSelected: boolean; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; DrawBox: boolean; DrawText: boolean; DrawShadow: boolean; BoxColor: TColor = clBlack; PrintAnnotations: boolean = False);
<FM>Description<FN>
Print multiple images (all or just selected) in the attached <A TImageEnMView> or <A TIEMultiBitmap> as rows and columns of thumbnails.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>Columns<FN></C> <C>Specifies how arrange images, specifying the number of columns.</C> </R>
<R> <C><FC>Rows<FN></C> <C>Specifies how arrange images, specifying the number of rows.</C> </R>
<R> <C><FC>HorizSpace<FN></C> <C>The horizontal space in inches between images.</C> </R>
<R> <C><FC>VertSpace<FN></C> <C>The vertical space in inches between images.</C> </R>
<R> <C><FC>PrintSelected<FN></C> <C>Set to true to print only selected images.</C> </R>
<R> <C><FC>MarginLeft<FN></C> <C>Page left margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>MarginTop<FN></C> <C>Page top margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>MarginRight<FN></C> <C>Page right margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>MarginBottom<FN></C> <C>Page bottom margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>DrawBox<FN></C> <C>Set to true to draw a box around the images (image space). The image is always stretched to maintain aspect ratio.</C> </R>
<R> <C><FC>DrawText<FN></C> <C>Set to true to draw text associated with every image.</C> </R>
<R> <C><FC>DrawShadow<FN></C> <C>Set to true to draw a shadow around the image.</C> </R>
<R> <C><FC>BoxColor<FN></C> <C>Specifies the color of the box around the image if DrawBox is True.</C> </R>
</TABLE>
Note: If the component is attached only to a <A TIEMultiBitmap> then you should specify the font of Printer.Canvas before printing
<FM>Example<FC>
// Printing from a TImageEnMView
Printer.BeginDoc;
ImageEnMView1.MIO.PrintImages(6, 4);
Printer.EndDoc;
// Printing images in a TIEMBitmap
MIO := TImageEnIO.Create;
MIO.AttachedIEMBitmap := mbmp;
Printer.BeginDoc;
Printer.Canvas.Font.Name := 'Tahoma';
Printer.Canvas.Font.Size := 14;
MIO.PrintImages(6, 4);
Printer.EndDoc;
MIO.Free;
!!}
procedure TImageEnMIO.PrintImages(Columns: integer; Rows: integer; HorizSpace: double; VertSpace: double; PrintSelected: boolean; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; DrawBox: boolean; DrawText: boolean; DrawShadow: boolean; BoxColor: TColor);
var
pagewidth, pageheight: double;
dpix, dpiy: integer;
PrtCanvas: TCanvas;
begin
PrtCanvas := Printer.Canvas;
dpix := GetDeviceCaps(PrtCanvas.Handle, LOGPIXELSX);
dpiy := GetDeviceCaps(PrtCanvas.Handle, LOGPIXELSY);
pagewidth := GetDeviceCaps(PrtCanvas.Handle, HORZRES) / dpix;
pageheight := GetDeviceCaps(PrtCanvas.Handle, VERTRES) / dpiy;
PrintImagesEx( PrtCanvas, dpix, dpiy, pagewidth, pageheight, False, Columns, Rows, HorizSpace, VertSpace, PrintSelected, MarginLeft, MarginTop, MarginRight, MarginBottom, DrawBox, DrawText, DrawShadow, BoxColor, 0 );
end;
{!!
<FS>TImageEnMIO.PreviewPrintImages
<FM>Declaration<FC>
procedure PreviewPrintImages(DestBitmap: TBitmap; MaxBitmapWidth, MaxBitmapHeight: integer; PrinterObj: TPrinter; Columns: integer; Rows: integer; HorizSpace: double; VertSpace: double; PrintSelected: boolean; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; DrawBox: boolean; DrawText: boolean; DrawShadow: boolean; BoxColor: TColor = clBlack; iPageNo : Integer = 0);
<FM>Description<FN>
Display a preview of printing of images (all or just selected) in the attached <A TImageEnMView> or <A TIEMultiBitmap> as rows and columns of thumbnails.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>DestBitmap<FN></C> <C>Destination bitmap where to paint the preview. Resizes DestBitmap as needed.</C> </R>
<R> <C><FC>MaxBitmapWidth<FN></C> <C>Maximum destination bitmap width. Preview will be stretched to match this size.</C> </R>
<R> <C><FC>MaxBitmapHeight<FN></C> <C>Maximum destination bitmap height. Preview will be stretched to match this size.</C> </R>
<R> <C><FC>Printer<FN></C> <C>This is the Printer object. PreviewPrintImage need it to know printer settings as orientation or page sizes.</C> </R>
<R> <C><FC>Columns<FN></C> <C>Specifies how arrange images, specifying the number of columns.</C> </R>
<R> <C><FC>Rows<FN></C> <C>Specifies how arrange images, specifying the number of rows.</C> </R>
<R> <C><FC>HorizSpace<FN></C> <C>The horizontal space in inches between images.</C> </R>
<R> <C><FC>VertSpace<FN></C> <C>The vertical space in inches between images.</C> </R>
<R> <C><FC>PrintSelected<FN></C> <C>Set to true to print only selected images.</C> </R>
<R> <C><FC>MarginLeft<FN></C> <C>Page left margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>MarginTop<FN></C> <C>Page top margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>MarginRight<FN></C> <C>Page right margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>MarginBottom<FN></C> <C>Page bottom margin in inches. By specifying all zero values, no margins are used.</C> </R>
<R> <C><FC>DrawBox<FN></C> <C>Set to true to draw a box around the images (image space). Image is always stretched to maintain aspect ratio.</C> </R>
<R> <C><FC>DrawText<FN></C> <C>Set to true to draw text associated with every image.</C> </R>
<R> <C><FC>DrawShadow<FN></C> <C>Set to true to draw a shadow around the image.</C> </R>
<R> <C><FC>BoxColor<FN></C> <C>Specifies the color of the box around the image if DrawBox is True.</C> </R>
<R> <C><FC>iPageNo<FN></C> <C>The page of thumbnails to preview. 0 shows the first page, 1 the second, etc.</C> </R>
</TABLE>
<FM>Example<FC>
// Paint and display the preview of thumbnails of the ImageEnMView using a TImageEnView component
ImageEnMView1.MIO.PreviewPrintImages(ImageEnView2.Bitmap, ImageEnView2.Width, ImageEnView2.Height, Printer, 6, 4, ...);
!!}
procedure TImageEnMIO.PreviewPrintImages(DestBitmap: TBitmap; MaxBitmapWidth, MaxBitmapHeight: integer; PrinterObj: TPrinter; Columns: integer; Rows: integer; HorizSpace: double; VertSpace: double; PrintSelected: boolean; MarginLeft: double; MarginTop: double; MarginRight: double; MarginBottom: double; DrawBox: boolean; DrawText: boolean; DrawShadow: boolean; BoxColor: TColor = clBlack; iPageNo : Integer = 0);
const
Can_Draw_Text_In_Preview = False; // todo... Support preview of text
var
Zoom, z1, z: double;
x1, y1, x2, y2: integer;
dpix, dpiy: integer;
PageWidth, PageHeight: integer;
begin
if PrinterObj = nil then
PrinterObj := Printer;
Zoom := (MaxBitmapWidth - 5) / (PrinterObj.PageWidth / 100);
z1 := (MaxBitmapHeight - 5) / (PrinterObj.PageHeight / 100);
if z1 < Zoom then
Zoom := z1;
z := Zoom / 100;
PageWidth := trunc(PrinterObj.PageWidth * z);
PageHeight := trunc(PrinterObj.PageHeight * z);
dpix := trunc(GetDeviceCaps(PrinterObj.Handle, LOGPIXELSX) * z);
dpiy := trunc(GetDeviceCaps(PrinterObj.Handle, LOGPIXELSY) * z);
DestBitmap.Width := 1;
DestBitmap.Height := 1;
DestBitmap.PixelFormat := pf24bit;
DestBitmap.Width := PageWidth;
DestBitmap.Height := PageHeight;
with DestBitmap.Canvas do
begin
Brush.Color := clWhite;
Brush.Style := bsSolid;
fillrect(rect(0, 0, destbitmap.width, destbitmap.height));
end;
if Can_Draw_Text_In_Preview = False then
DrawText := False;
PrintImagesEx(DestBitmap.Canvas, dpix, dpiy, PageWidth / dpix, PageHeight / dpiy, True, Columns, Rows, HorizSpace {* dpix}, VertSpace {* dpiy}, PrintSelected, MarginLeft {* dpix}, MarginTop {* dpiy}, MarginRight {* dpix}, MarginBottom {* dpiy}, DrawBox, DrawText, DrawShadow, BoxColor, iPageNo);
with DestBitmap.Canvas do
begin
Brush.Style := bsClear;
Pen.Color := IEPrint_Preview_Margin_Color;
Pen.Style := psDot;
Pen.Width := 1;
x1 := trunc(MarginLeft * dpix);
y1 := trunc(MarginTop * dpiy);
x2 := trunc(PageWidth - MarginRight * dpix);
y2 := trunc(PageHeight - MarginBOttom * dpiy);
Rectangle(x1, y1, x2, y2);
end;
end;
{!!
<FS>TImageEnMIO.PrintImagesToFile
<FM>Declaration<FC>
procedure PrintImagesToFile(const sFilename : string; iJpegQuality : Integer; iImageWidth, iImageHeight: integer; iColumns : integer; iRows : integer; iHorzSpace : Integer = 6; iVertSpace : Integer = 6; bPrintSelectedOnly: Boolean = False; iHorzMargin : Integer = 12; iVertMargin : Integer = 12; bDrawBox : Boolean = False; bDrawText : Boolean = True; bDrawShadow : Boolean = True; BackgroundColor : TColor = clWhite; BoxColor: TColor = clBlack; iPageNo : Integer = -1);
<FM>Description<FN>
Outputs multiple images (all or just selected) in the attached <A TImageEnMView> or <A TIEMultiBitmap> as rows and columns of thumbnails to a file.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>sFilename<FN></C> <C>The destination filename for these thumbnails. If all pages are being printed (see iPageNo) then this filename will be automatically adjusted in the format image.jpg, image_2.jpg, image_3.jpg, etc.</C> </R>
<R> <C><FC>iJpegQuality<FN></C> <C>If sFilename is a JPEG file then specify the output quality (e.g. 80)</C> </R>
<R> <C><FC>iImageWidth<FN></C> <C>The output width for the image</C> </R>
<R> <C><FC>iImageHeight<FN></C> <C>The output height for the image</C> </R>
<R> <C><FC>iColumns<FN></C> <C>Specifies how many thumbnails span across the page</C> </R>
<R> <C><FC>iRows<FN></C> <C>Specifies how many thumbnails span down the page</C> </R>
<R> <C><FC>iHorzSpace<FN></C> <C>The horizontal space in pixels between thumbnails</C> </R>
<R> <C><FC>iVertSpace<FN></C> <C>The vertical space in pixels between thumbnails</C> </R>
<R> <C><FC>bPrintSelectedOnly<FN></C> <C>Set to true to print only selected images. False to print all image in the TImageEnMView</C> </R>
<R> <C><FC>iHorzMargin<FN></C> <C>Page margin on left and right of the image (in pixels)</C> </R>
<R> <C><FC>iVertMargin<FN></C> <C>Page margin on top and bottom of the image (in pixels)</C> </R>
<R> <C><FC>bDrawBox<FN></C> <C>Set to true to draw a box around the images (image space). Image is always stretched to maintain aspect ratio.</C> </R>
<R> <C><FC>bDrawText<FN></C> <C>Set to true to draw text associated with every image.</C> </R>
<R> <C><FC>bDrawShadow<FN></C> <C>Set to true to draw a shadow around the image.</C> </R>
<R> <C><FC>BackgroundColor<FN></C> <C>Specifies the fill color of the image.</C> </R>
<R> <C><FC>BoxColor<FN></C> <C>Specifies the color of the box around the image if DrawBox is True.</C> </R>
<R> <C><FC>iPageNo<FN></C> <C>The page of thumbnails to output. If this is -1 (default) then all pages are output and the filename is automatically incremented</C> </R>
</TABLE>
<FM>Example<FC>
// Save image of thumbnails
ImageEnMView1.MIO.PrintImagesToFile('C:\SomeImage.jpg', Screen.Width, Screen.Height, 6, 4, ...);
!!}
procedure TImageEnMIO.PrintImagesToFile(const sFilename : string; iJpegQuality : Integer; iImageWidth, iImageHeight: integer; iColumns : integer; iRows : integer; iHorzSpace : Integer = 6; iVertSpace : Integer = 6; bPrintSelectedOnly: Boolean = False; iHorzMargin : Integer = 12; iVertMargin : Integer = 12; bDrawBox : Boolean = False; bDrawText : Boolean = True; bDrawShadow : Boolean = True; BackgroundColor : TColor = clWhite; BoxColor: TColor = clBlack; iPageNo : Integer = -1);
// NPC: 27/2/13
procedure _PrintImagesToFile(sCurrFilename : string; iCurrPageNo : Integer);
var
bmp : TBitmap;
io: TImageEnIO;
begin
bmp := TBitmap.create;
bmp.Width := iImageWidth;
bmp.Height := iImageHeight;
bmp.PixelFormat := pf24bit;
bmp.Canvas.Brush.Color := BackgroundColor;
bmp.Canvas.FillRect(Rect(0, 0, iImageWidth, iImageHeight));
io := TImageEnIO.CreateFromBitmap(bmp);
try
PrintImagesEx(bmp.Canvas, 1, 1, iImageWidth, iImageHeight, True { as we are not printing },
iColumns, iRows, iHorzSpace, iVertSpace, bPrintSelectedOnly,
iHorzMargin, iVertMargin, iHorzMargin, iVertMargin,
bDrawBox, bDrawText, bDrawShadow, BoxColor, iCurrPageNo);
io.Params.JPEG_Quality := iJpegQuality;
io.SaveToFile(sCurrFilename);
if io.Aborting then
raise EIEException.create(format('Unable to save to %s', [sCurrFilename]));
finally
io.Free;
bmp.free;
end;
end;
var
iImageCount: Integer;
iThumbsPerPage: integer;
iPageCount: Integer;
I: Integer;
sCurrentFilename: string;
begin
if bPrintSelectedOnly and assigned( fImageEnMView ) then
iImageCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
iImageCount := GetIEMBitmap.Count;
iThumbsPerPage := iColumns * iRows;
iPageCount := iImageCount div iThumbsPerPage;
if iImageCount mod iThumbsPerPage <> 0 then
inc(iPageCount);
if iPageNo > -1 then
_PrintImagesToFile(sFilename, iPageNo)
else
for I := 0 to iPageCount - 1 do
begin
if I = 0 then
sCurrentFilename := sFilename
else
sCurrentFilename := ChangeFileExt(sFilename, format('_%d%s', [I + 1, ExtractFileExt(sFilename)]));
_PrintImagesToFile(sCurrentFilename, I);
if assigned(fOnProgress) then
fOnProgress(self, trunc(I / iPageCount * 100));
if fAborting then
break
end;
DoFinishWork();
end;
{!!
<FS>TImageEnMIO.SaveToFileICO
<FM>Declaration<FC>
procedure SaveToFileICO(const FileName: string; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> as a GIF file.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToFileICO(const FileName: string; SelectedOnly: Boolean = False);
var
fs: TFileStream;
begin
fAborting := False;
fs := TFileStream.Create(FileName, fmCreate);
try
SaveToStreamICO(fs, SelectedOnly);
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnMIO.SaveToStreamICO
<FM>Declaration<FC>
procedure SaveToStreamICO(Stream: TStream; SelectedOnly: Boolean = False);
<FM>Description<FN>
Save all images in the attached <A TImageEnMView> or <A TIEMultiBitmap> to a stream in ICO format.
If <FC>SelectedOnly<FN> = True and the component is attached to a <A TImageEnMView> then only the selected images are output.
Note: If an internal save error is encountered <A TImageEnMIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnMIO.SaveToStreamICO(Stream: TStream; SelectedOnly: Boolean = False);
var
Progress: TProgressRec;
NullProgress: TProgressRec;
ielist: array of TObject;
ie: TImageEnView;
procedure _SaveImg(ImgIdx, FileIdx: integer);
begin
ie := TImageEnView.Create(nil);
ie.LegacyBitmap := false;
ielist[FileIdx] := ie;
Attached_CopyToIEBitmap( ImgIdx, ie.IEBitmap );
ie.IO.Params.Assign( Params[ImgIdx] );
ie.IO.Params.ICO_Sizes[FileIdx].cx := ie.IEBitmap.Width;
ie.IO.Params.ICO_Sizes[FileIdx].cy := ie.IEBitmap.Height;
ie.IO.Params.ICO_ImageIndex := FileIdx;
ie.IO.Params.ICO_Background := Params[ImgIdx].ICO_Background;
ie.Update;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * FileIdx));
end;
var
i, imgCount: Integer;
begin
try
fAborting := False;
if not IsAttached() then
exit;
if SelectedOnly and assigned( fImageEnMView ) then
imgCount := (fImageEnMView as TImageEnMView).MultiSelectedImagesCount
else
imgCount := GetIEMBitmap.Count;
if imgCount = 0 then
exit;
Progress := ProgressRec( Self, fOnProgress, fAborting );
NullProgress := NullProgressRec( Progress.Aborting );
Progress.per1 := 100 / imgCount;
SetLength(ielist, imgCount);
i := 0;
while not fAborting and (i < length(ielist)) do
begin
if SelectedOnly and assigned( fImageEnMView ) then
_SaveImg((fImageEnMView as TImageEnMView).MultiSelectedImages[i], i)
else
_SaveImg(i, i);
inc(i);
end;
ICOWriteStream2(Stream, ielist, Progress);
finally
for i := 0 to length(ielist) - 1 do
TImageEnView(ielist[i]).Free;
DoFinishWork;
end;
end;
procedure TImageEnMIO.SetAborting(Value: Boolean);
begin
fAborting := Value;
{$IFDEF IEINCLUDEIEXACQUIRE}
fAcquireParams.Aborting := Value;
{$ENDIF}
{$IFDEF IEINCLUDEWPD}
fDCIMParams.Aborting := Value;
{$ENDIF}
end;
function TImageEnMIO.GetParamsList: TIOMultiParams;
begin
if ( GetIEMBitmap <> nil ) and GetIEMBitmap.ParamsEnabled then
Result := GetIEMBitmap.ParamsList
else
Result := fParamsList;
end;
function TImageEnMIO.ParamsFromFileOrStream(const FileName: WideString; Stream: TStream; Format: TIOFileType): Boolean;
var
io: TImageEnIO;
idx: Integer;
iImageCount: Integer;
begin
fAborting := False;
Result := True;
io := TImageEnIO.Create( NIL );
try
idx := 0;
iImageCount := 1;
while idx < iImageCount do
begin
io.Params.ImageIndex := idx;
if Stream = nil then
Result := io.ParamsFromFile( FileName, Format )
else
begin
Stream.Position := 0;
Result := io.ParamsFromStream( Stream, Format );
end;
if result = False then
exit;
if idx = 0 then
begin
iImageCount := io.Params.ImageCount;
fParamsList.Allocate( iImageCount );
end;
fParamsList.Params[ idx ].Assign( io.Params );
inc( idx );
end;
finally
FreeAndNil( io );
fAborting := not Result;
end;
DoFinishWork;
end;
{!!
<FS>TImageEnMIO.ParamsFromFile
<FM>Declaration<FC>
function ParamsFromFile(const FileName: WideString; Format: <A TIOFileType> = ioUnknown): Boolean; overload;
function ParamsFromFile(const FileName: WideString; bUseExtension: Boolean): Boolean; overload;
<FM>Description<FN>
Reads the <L TImageEnMIO.Params>image properties</L> without loading the image (and without changing the current image). Result is false if a loading error is encountered due to a corrupt or unknown image format.
<FC>FileName<FN> is the file name with full path.
<FC>Format<FN> is the file format that the stream or file contains. If <FC>ioUnknown<FN> is specified then the file content is analyzed to determine the format.
<FC>bUseExtension<FN> determines that the file format is based on the extension of the file, e.g. image.jpeg will be processed as ioJPEG format.
<FM>Examples<FC>
// Load the parameters of an image (which may be a TIFF file, but we will examine the content to be sure)
ImageEnView1.IO.ParamsFromFile( 'C:\alfa.tiff' );
Label1.Caption := 'alfa.tiff contains ' + inttostr(ImageEnView1.IO.Params[0].ImageCount) + ' images';
// Load the parameters of a TIFF
ImageEnView1.IO.ParamsFromFile( 'C:\alfa.tiff', ioTIFF );
Label1.Caption := 'alfa.tiff contains ' + inttostr(ImageEnView1.IO.Params[0].ImageCount) + ' images';
// Load the parameters of a file. It will be assumed to a TIFF because of the file extension
ImageEnView1.IO.ParamsFromFile( 'C:\alfa.tiff', True );
Label1.Caption := 'alfa.tiff contains ' + inttostr(ImageEnView1.IO.Params[0].ImageCount) + ' images';
!!}
function TImageEnMIO.ParamsFromFile(const FileName: WideString; Format: TIOFileType = ioUnknown): Boolean;
begin
Result := ParamsFromFileOrStream( FileName, nil, Format );
end;
function TImageEnMIO.ParamsFromFile(const FileName: WideString; bUseExtension: Boolean): Boolean;
var
Format: TIOFileType;
begin
Format := ioUnknown;
if bUseExtension then
Format := IEFilenameToInternalFileType( FileName, True );
Result := ParamsFromFileOrStream( FileName, nil, Format );
end;
{!!
<FS>TImageEnMIO.ParamsFromStream
<FM>Declaration<FC>
function ParamsFromStream(Stream: TStream; Format: <A TIOFileType> = ioUnknown): Boolean;
<FM>Description<FN>
Reads the <L TImageEnMIO.Params>image properties</L> without loading the image (and without changing the current image). Result is false if a loading error is encountered due to a corrupt or unknown image format.
<FC>Stream<FN> is a TStream that contains the image.
<FC>Format<FN> is the file format that the stream or file contains. If <FC>ioUnknown<FN> is specified then the file content is analyzed to determine the format.
!!}
// Fills Params reading Stream, but doesn't load the image
// format specifies the file format
// The Stream position changes
function TImageEnMIO.ParamsFromStream(Stream: TStream; Format: TIOFileType = ioUnknown): Boolean;
begin
Result := ParamsFromFileOrStream( '', Stream, Format );
end;
{!!
<FS>TImageEnMIO.ParamsFromBuffer
<FM>Declaration<FC>
function ParamsFromBuffer(Buffer: Pointer; BufferSize: Integer; Format: <A TIOFileType> = ioUnknown): Boolean;
<FM>Description<FN>
Loads image parameters (but not the actual image) from the specified buffer. Result is false if a loading error is encountered due to a corrupt or non-standard image format.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>Buffer<FN></C> <C>The buffer pointer</C> </R>
<R> <C><FC>BufferSize<FN></C> <C>The buffer length in bytes.</C> </R>
<R> <C><FC>Format<FN></C> <C>Specifies the expected file format. If Format is ioUnknown, then try to find the format automatically</C> </R>
</TABLE>
See also: <A TImageEnMIO.LoadFromBuffer>
<FM>Example<FC>
ImageEnView1.IO.ParamsFromBuffer(mybuffer, mybufferlength, ioJPEG);
!!}
function TImageEnMIO.ParamsFromBuffer(Buffer: Pointer; BufferSize: Integer; Format: TIOFileType): Boolean;
var
Stream: TIEMemStream;
begin
Result := False;
if ( Buffer = nil ) or ( BufferSize = 0 ) then
begin
fAborting := true;
exit;
end;
Stream := TIEMemStream.Create( Buffer, BufferSize );
try
Result := ParamsFromStream( Stream, Format );
finally
FreeAndNil( Stream );
end;
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-08)
function TImageEnMIO.GetProxyAddress: WideString;
begin
Result := IEGlobalSettings().ProxyAddress;
end;
function TImageEnMIO.GetProxyUser: WideString;
begin
Result := IEGlobalSettings().ProxyUser;
end;
function TImageEnMIO.GetProxyPassword: WideString;
begin
Result := IEGlobalSettings().ProxyPassword;
end;
procedure TImageEnMIO.SetProxyAddress(Value: WideString);
begin
IEGlobalSettings().ProxyAddress := Value;
end;
procedure TImageEnMIO.SetProxyUser(Value: WideString);
begin
IEGlobalSettings().ProxyUser := Value;
end;
procedure TImageEnMIO.SetProxyPassword(Value: WideString);
begin
IEGlobalSettings().ProxyPassword := Value;
end;
{$ENDIF}
{$ELSE} // {$ifdef IEINCLUDEMULTIVIEW}
interface
implementation
{$ENDIF}
end.