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

13832 lines
423 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 1070
Doc revision 1004
*)
unit imageenio;
{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF}
{$R-}
{$Q-}
{$I ie.inc}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, SyncObjs, ieview,
ImageEnProc, ExtCtrls, hyiedefs, iexBitmaps, Dialogs, hyieutils, iegdiplus,
{$ifdef IEHASTYPES} Types, {$endif}
{$ifdef IEHASUITYPES} System.UITypes, {$endif}
{$IFDEF IEINCLUDEIEXACQUIRE}
iexAcquire, ietwain, iexDCIM, iewia,
{$ENDIF}
{$IFDEF IEINCLUDEDIRECTSHOW}
ieds,
{$ENDIF}
{$IFDEF IEINCLUDEMEDIAFOUNDATION}
iemmf,
{$ENDIF}
{$ifdef FPC}
lmetafile,
{$endif}
printers;
const
// Standard Twain sizes
IETW_NONE = 0;
IETW_A4LETTER = 1;
IETW_B5LETTER = 2;
IETW_USLETTER = 3;
IETW_USLEGAL = 4;
IETW_A5 = 5;
IETW_B4 = 6;
IETW_B6 = 7;
IETW_USLEDGER = 9;
IETW_USEXECUTIVE = 10;
IETW_A3 = 11;
IETW_B3 = 12;
IETW_A6 = 13;
IETW_C4 = 14;
IETW_C5 = 15;
IETW_C6 = 16;
IETW_4A0 = 17;
IETW_2A0 = 18;
IETW_A0 = 19;
IETW_A1 = 20;
IETW_A2 = 21;
IETW_A4 = IETW_A4LETTER;
IETW_A7 = 22;
IETW_A8 = 23;
IETW_A9 = 24;
IETW_A10 = 25;
IETW_ISOB0 = 26;
IETW_ISOB1 = 27;
IETW_ISOB2 = 28;
IETW_ISOB3 = IETW_B3;
IETW_ISOB4 = IETW_B4;
IETW_ISOB5 = 29;
IETW_ISOB6 = IETW_B6;
IETW_ISOB7 = 30;
IETW_ISOB8 = 31;
IETW_ISOB9 = 32;
IETW_ISOB10 = 33;
IETW_JISB0 = 34;
IETW_JISB1 = 35;
IETW_JISB2 = 36;
IETW_JISB3 = 37;
IETW_JISB4 = 38;
IETW_JISB5 = IETW_B5LETTER;
IETW_JISB6 = 39;
IETW_JISB7 = 40;
IETW_JISB8 = 41;
IETW_JISB9 = 42;
IETW_JISB10 = 43;
IETW_C0 = 44;
IETW_C1 = 45;
IETW_C2 = 46;
IETW_C3 = 47;
IETW_C7 = 48;
IETW_C8 = 49;
IETW_C9 = 50;
IETW_C10 = 51;
IETW_USSTATEMENT = 52;
IETW_BUSINESSCARD = 53;
type
{!!
<FS>TIETextFormat
<FM>Declaration<FC>
TIETextFormat = (ietfPascal, ietfHex, ietfBase64, ietfASCIIArt);
<FM>Description<FN>
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C><FC>ietfPascal<FN></C> <C>
In this case the format is as follows:<FC>
const
'FileName_Extension_Size' = nnnn;
'FileName_Extension' : array [0 .. 'FileName_Extension_Size' - 1] of byte = ( $xx,$xx );<FN>
This is useful when you want to embed the image inside a .pas file. You can load back the image by writing:<FC>
ImageEnView1.IO.LoadFromBuffer(FileName_Extension, FileName_Extension_Size, fileformat);<FN>
</C> </R>
<R> <C><FC>ietfHex<FN></C> <C>
Save the image as a sequence of hex values. Example:<FC>
0xaa, 0xbb, etc...<FN>
</C> </R>
<R> <C><FC>ietfBase64<FN></C> <C>
Save the image encoded with base 64 (the base of Mime64). Example:<FC>
/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYF...<FN>
</C> </R>
<R> <C><FC>ietfASCIIArt<FN></C> <C>
Save the image as an Ascii art. We suggest you sub-sample the image before save as Ascii art. The <FC>ImageFormat<FN> field of <A TImageEnIO.SaveToText> must be <FC>ioUnknown<FN>.</C> </R>
</TABLE>
!!}
TIETextFormat = (ietfPascal, ietfHex, ietfBase64, ietfASCIIArt);
{!!
<FS>TIEAcquireBitmapEvent
<FM>Declaration<FC>
TIEAcquireBitmapEvent = procedure(Sender: TObject; ABitmap: <A TIEBitmap>; DpiX, DpiY: Integer; var Handled: boolean) of object;
<FM>Description<FN>
Occurs whenever an image is acquired from a scanner.
<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.
!!}
TIEAcquireBitmapEvent = procedure(Sender: TObject; ABitmap: TIEBitmap; DpiX, DpiY: Integer; var Handled: boolean) of object;
{!!
<FS>TIEAfterAcquireBitmapEvent
<FM>Declaration<FC>
TIEAfterAcquireBitmapEvent = procedure(Sender: TObject; index: integer) of object;
<FM>Description<FN>
This event fired after an image has been acquired and added to the image list.
<FC>index<FN> specifies the index of the new image in the attached <A TImageEnMView>.
!!}
TIEAfterAcquireBitmapEvent = procedure(Sender: TObject; index: Integer) of object;
// Header used to save a jpeg inside a Stream
TStreamJpegHeader = record
ID: array[0..4] of AnsiChar; // ="JFIF\0"
dim: integer; // length of jpeg box
end;
// Header used to save a PCX inside a Stream
PCXSHead = record
ID: array[0..4] of AnsiChar; // 'PCX2\0'
dim: integer;
end;
// Header used to save a TIFF inside a Stream
TIFFSHead = record
ID: array[0..4] of AnsiChar; // 'TIFF\0'
dim: integer;
end;
// printing properties
{!!
<FS>TIEVerticalPos
<FM>Declaration<FC>
TIEVerticalPos = (ievpTop, ievpCenter, ievpBottom);
<FM>Description<FN>
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>ievpTop</C> <C>Image is aligned to the top</C> </R>
<R> <C>ievpCenter</C> <C>Image is vertically centered</C> </R>
<R> <C>ievpBottom</C> <C>Image is aligned to the bottom</C> </R>
</TABLE>
!!}
TIEVerticalPos = (ievpTop, ievpCenter, ievpBottom);
{!!
<FS>TIEHorizontalPos
<FM>Declaration<FC>
TIEHorizontalPos = (iehpLeft, iehpCenter, iehpRight);
<FM>Description<FN>
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>iehpLeft</C> <C>Image is aligned to the left-hand side</C> </R>
<R> <C>iehpCenter</C> <C>Image is horizontally centered</C> </R>
<R> <C>iehpRight</C> <C>Image is aligned to the right-hand side</C> </R>
</TABLE>
!!}
TIEHorizontalPos = (iehpLeft, iehpCenter, iehpRight);
{!!
<FS>TIESize
<FM>Declaration<FC>
TIESize = (iesNormal, iesFitToPage, iesFitToPageStretch, iesFillPage, iesSpecifiedSize, iesMultiplePages);
<FM>Description<FN>
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>iesNormal</C> <C>Determine print size by the original image DPI (i.e. to create a true size copy)</C> </R>
<R> <C>iesFitToPage</C> <C>Stretch the image to fit the page, while respecting its proportions</C> </R>
<R> <C>iesFitToPageStretch</C> <C>Stretch the image to fit the page, ignoring the proportions</C> </R>
<R> <C>iesFillPage</C> <C>Stretch the image to fill the entire page (respecting its proportions), cropping any edge of it so that it aligns with the orientation of the page (i.e. portions of the image may not be printed)</C> </R>
<R> <C>iesSpecifiedSize</C> <C>Print at an absolute size specified by the SpecWidth and SpecHeight parameters</C> </R>
<R> <C>iesMultiplePages</C> <C>Print the image over multiple pages with count specified by the SpecWidth and SpecHeight parameters</C> </R>
</TABLE>
!!}
TIESize = (iesNormal, iesFitToPage, iesFitToPageStretch, iesFillPage, iesSpecifiedSize, iesMultiplePages);
{!!
<FS>TIECreateAVIFileResult
<FM>Declaration<FC>
TIECreateAVIFileResult = (ieaviOK, ieaviNOCOMPRESSOR, ieaviMEMORY, ieaviUNSUPPORTED);
<FM>Description<FN>
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>ieaviOK</C> <C>No error</C> </R>
<R> <C>ieaviNOCOMPRESSOR</C> <C>A suitable compressor cannot be found</C> </R>
<R> <C>ieaviMEMORY</C> <C>There is not enough memory to complete the operation</C> </R>
<R> <C>ieaviUNSUPPORTED</C> <C>Compression is not supported for this type of data</C> </R>
</TABLE>
!!}
TIECreateAVIFileResult = (ieaviOK, ieaviNOCOMPRESSOR, ieaviMEMORY, ieaviUNSUPPORTED);
// occurs after preview
{!!
<FS>TIEIOPreviewEvent
<FM>Declaration<FC>
}
TIEIOPreviewEvent = procedure(Sender: TObject; PreviewForm: TForm) of object;
{!!}
{!!
<FS>TIEDoPreviewsEvent
<FM>Declaration<FC>
}
TIEDoPreviewsEvent = procedure(Sender: TObject; var Handled: boolean) of object;
{!!}
{!!
<FS>TIECSSource
<FM>Declaration<FC>
TIECSSource = (iecsScreen, iecsPrimary, iecsForegroundWindow, iecsForegroundWindowClient);
<FM>Description<FN>
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>iecsScreen</C> <C>Captures the entire screen (all screens on a multiple monitor system)</C> </R>
<R> <C>iecsPrimary</C> <C>Captures the screen of the primary monitor on a multiple monitor system (or the whole screen if there is only one monitor)</C> </R>
<R> <C>iecsForegroundWindow</C> <C>Captures the active window</C> </R>
<R> <C>iecsForegroundWindowClient</C> <C>Captures the client area of the active window</C> </R>
</TABLE>
!!}
TIECSSource = (iecsScreen, iecsPrimary, iecsForegroundWindow, iecsForegroundWindowClient);
{!!
<FS>TIEDialogType
<FM>Declaration<FC>
TIEDialogType = (iedtDialog, iedtMaxi);
<FM>Description<FN>
iedtDialog : Show a dialog window.
iedtMaxi : Show a maximized window.
!!}
TIEDialogType = (iedtDialog, iedtMaxi);
{!!
<FS>TIEDialogsMeasureUnit
<FM>Declaration<FC>
TIEDialogsMeasureUnit = (ieduInches, ieduCm, ieduSelectableDefInches, ieduSelectableDefCm);
<FM>Description<FN>
<TABLE>
<R> <H>Value</H> <H>Description</H> </R>
<R> <C>ieduInches</C> <C>Use inches (default)</C> </R>
<R> <C>ieduCm</C> <C>Use centimeters (Cm)</C> </R>
<R> <C>ieduSelectableDefInches</C> <C>Use inches but allow the user to change it</C> </R>
<R> <C>ieduSelectableDefCm</C> <C>Use centimeters but allow the user to change it</C> </R>
</TABLE>
!!}
TIEDialogsMeasureUnit = (ieduInches, ieduCm, ieduSelectableDefInches, ieduSelectableDefCm);
// C++Builder doesn't work if we import IEVFW in interface uses
TAviStreamInfoA_Ex = record
fccType: DWORD;
fccHandler: DWORD;
dwFlags: DWORD; // Contains AVITF_* flags
dwCaps: DWORD;
wPriority: WORD;
wLanguage: WORD;
dwScale: DWORD;
dwRate: DWORD; // dwRate / dwScale == samples/second
dwStart: DWORD;
dwLength: DWORD; // In units above...
dwInitialFrames: DWORD;
dwSuggestedBufferSize: DWORD;
dwQuality: DWORD;
dwSampleSize: DWORD;
rcFrame: TRECT;
dwEditCount: DWORD;
dwFormatChangeCount: DWORD;
szName: array[0..63] of AnsiChar;
end;
TAviStreamInfoW_Ex = record
fccType: DWORD;
fccHandler: DWORD;
dwFlags: DWORD; // Contains AVITF_* flags
dwCaps: DWORD;
wPriority: WORD;
wLanguage: WORD;
dwScale: DWORD;
dwRate: DWORD; // dwRate / dwScale == samples/second
dwStart: DWORD;
dwLength: DWORD; // In units above...
dwInitialFrames: DWORD;
dwSuggestedBufferSize: DWORD;
dwQuality: DWORD;
dwSampleSize: DWORD;
rcFrame: TRECT;
dwEditCount: DWORD;
dwFormatChangeCount: DWORD;
szName: array[0..63] of WideChar;
end;
TAviStreamInfo_Ex = {$IFDEF UNICODE}TAviStreamInfoW_Ex{$ELSE}TAviStreamInfoA_Ex{$ENDIF};
{!!
<FS>TIOPrintPreviewPosition
<FM>Declaration<FC>
}
TIOPrintPreviewPosition = (ppTopLeft, ppTop, ppTopRight, ppLeft, ppCenter, ppRight, ppBottomLeft, ppBottom, ppBottomRight);
{!!}
{!!
<FS>TIOPrintPreviewSize
<FM>Declaration<FC>
TIOPrintPreviewSize = (psNormal, psFitToPage, psStretchToPage, psFillPage, psSpecifiedSize, psMultiplePages);
<FM>Description<FN>
Aligns with <A TIESize>
!!}
TIOPrintPreviewSize = (psNormal, psFitToPage, psStretchToPage, psFillPage, psSpecifiedSize, psMultiplePages);
{!!
<FS>TIOPrintPreviewThumbnailStyle
<FM>Declaration<FC>
}
TIOPrintPreviewThumbnailStyle = (ptFlat, ptSoftShadow, ptBorder);
{!!}
{$IFDEF IEINCLUDEPRINTDIALOGS}
{!!
<FS>TIOPrintPreviewParams
<FM>Description<FN>
This class provides access to the properties of the Print Preview dialog.
<FM>Methods and Properties<FN>
<FI>Storage Handling<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TIOPrintPreviewParams.GetProperty></C> </R>
<R> <C_IMG_METHOD> <C><A TIOPrintPreviewParams.LoadFromFile></C> </R>
<R> <C_IMG_METHOD> <C><A TIOPrintPreviewParams.LoadFromStream></C> </R>
<R> <C_IMG_METHOD> <C><A TIOPrintPreviewParams.SaveToFile></C> </R>
<R> <C_IMG_METHOD> <C><A TIOPrintPreviewParams.SaveToStream></C> </R>
<R> <C_IMG_METHOD> <C><A TIOPrintPreviewParams.SetProperty></C> </R>
</TABLE>
<FI>Settings<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.Gamma></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.Height></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.MarginBottom></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.MarginLeft></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.MarginRight></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.MarginTop></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.Position></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.Size></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.Width></C> </R>
</TABLE>
<FI>TImageEnMIO.DoPrintPreviewDialog Only<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.DlgWidth></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.DlgHeight></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.PrintSelected></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.PrintThumbnails></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.ThumbnailColumns></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.ThumbnailRows></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.ThumbnailSpacing></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.ThumbnailStyle></C> </R>
<R> <C_IMG_PROPERTY> <C><A TIOPrintPreviewParams.ThumbnailShowText></C> </R>
</TABLE>
!!}
TIOPrintPreviewParams = class
private
fMarginTop: Double;
fMarginLeft: Double;
fMarginRight: Double;
fMarginBottom: Double;
fPosition: TIOPrintPreviewPosition;
fSize: TIOPrintPreviewSize;
fWidth: Double; // <=0: autocalculated
fHeight: Double; // <=0: autocalculated
fGamma: Double;
fPrintSelected : Boolean;
fPrintThumbnails : Boolean;
fThumbnailColumns : Integer;
fThumbnailRows : Integer;
fThumbnailSpacing : Double;
fThumbnailStyle : TIOPrintPreviewThumbnailStyle;
fThumbnailShowText : Boolean;
fDlgWidth : Integer;
fDlgHeight : Integer;
public
constructor Create;
{!!
<FS>TIOPrintPreviewParams.MarginTop
<FM>Declaration<FC>
property MarginTop: Double;
<FM>Description<FN>
The top margin (unprintable area) of the printed page.
!!}
property MarginTop: Double read fMarginTop write fMarginTop;
{!!
<FS>TIOPrintPreviewParams.MarginLeft
<FM>Declaration<FC>
property MarginLeft: Double;
<FM>Description<FN>
The left margin (unprintable area) of the printed page.
!!}
property MarginLeft: Double read fMarginLeft write fMarginLeft;
{!!
<FS>TIOPrintPreviewParams.MarginRight
<FM>Declaration<FC>
property MarginRight: Double;
<FM>Description<FN>
The right margin (unprintable area) of the printed page.
!!}
property MarginRight: Double read fMarginRight write fMarginRight;
{!!
<FS>TIOPrintPreviewParams.MarginBottom
<FM>Declaration<FC>
property MarginBottom: Double;
<FM>Description<FN>
The bottom margin (unprintable area) of the printed page.
!!}
property MarginBottom: Double read fMarginBottom write fMarginBottom;
{!!
<FS>TIOPrintPreviewParams.Position
<FM>Declaration<FC>
property Position: <A TIOPrintPreviewPosition>;
<FM>Description<FN>
The alignment of the image on the printed page.
!!}
property Position: TIOPrintPreviewPosition read fPosition write fPosition;
{!!
<FS>TIOPrintPreviewParams.Size
<FM>Declaration<FC>
property Size: <A TIOPrintPreviewSize>;
<FM>Description<FN>
The size of the image on the printed page.
!!}
property Size: TIOPrintPreviewSize read fSize write fSize;
{!!
<FS>TIOPrintPreviewParams.Width
<FM>Declaration<FC>
property Width: Double;
<FM>Description<FN>
Width of the printed image when <A TIOPrintPreviewParams.Size> = psSpecifiedSize (in inches or CM depending on <A TImageEnIO.DialogsMeasureUnit>). Number of pages across when <A TIOPrintPreviewParams.Size> = psMultiplePages.
!!}
property Width: Double read fWidth write fWidth;
{!!
<FS>TIOPrintPreviewParams.Height
<FM>Declaration<FC>
property Height: Double;
<FM>Description<FN>
Height of the printed image when <A TIOPrintPreviewParams.Size> = psSpecifiedSize (in inches or CM depending on <A TImageEnIO.DialogsMeasureUnit>). Number of pages down when <A TIOPrintPreviewParams.Size> = psMultiplePages.
!!}
property Height: Double read fHeight write fHeight;
{!!
<FS>TIOPrintPreviewParams.Gamma
<FM>Declaration<FC>
property Gamma: Double;
<FM>Description<FN>
Gamma value.
!!}
property Gamma: Double read fGamma write fGamma;
{!!
<FS>TIOPrintPreviewParams.PrintSelected
<FM>Declaration<FC>
property PrintSelected: Boolean;
<FM>Description<FN>
Default to printing the images selected in the associated <A TImageEnMView> instead of printing all images (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only).
Default: False
!!}
property PrintSelected: Boolean read fPrintSelected write fPrintSelected;
{!!
<FS>TIOPrintPreviewParams.PrintThumbnails
<FM>Declaration<FC>
property PrintThumbnails: Boolean;
<FM>Description<FN>
Default to printing of thumbnails (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only).
Default: False
!!}
property PrintThumbnails: Boolean read fPrintThumbnails write fPrintThumbnails;
{!!
<FS>TIOPrintPreviewParams.ThumbnailColumns
<FM>Declaration<FC>
property ThumbnailColumns: Integer;
<FM>Description<FN>
Number of thumbnail columns per page (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only)
!!}
property ThumbnailColumns: Integer read fThumbnailColumns write fThumbnailColumns;
{!!
<FS>TIOPrintPreviewParams.ThumbnailRows
<FM>Declaration<FC>
property ThumbnailRows: Integer;
<FM>Description<FN>
Number of thumbnail rows per page (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only)
!!}
property ThumbnailRows: Integer read fThumbnailRows write fThumbnailRows;
{!!
<FS>TIOPrintPreviewParams.ThumbnailSpacing
<FM>Declaration<FC>
property ThumbnailSpacing : Double;
<FM>Description<FN>
Spacing between each thumbnail in inches or CM depending on <A TImageEnIO.DialogsMeasureUnit> (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only)
!!}
property ThumbnailSpacing : Double read fThumbnailSpacing write fThumbnailSpacing;
{!!
<FS>TIOPrintPreviewParams.ThumbnailStyle
<FM>Declaration<FC>
property ThumbnailStyle: <A TIOPrintPreviewThumbnailStyle>;
<FM>Description<FN>
Style of printed thumbnails (TImageEnMIO.DoPrintPreviewDialog only)
!!}
property ThumbnailStyle: TIOPrintPreviewThumbnailStyle read fThumbnailStyle write fThumbnailStyle;
{!!
<FS>TIOPrintPreviewParams.ThumbnailShowText
<FM>Declaration<FC>
property ThumbnailShowText: Boolean;
<FM>Description<FN>
Whether the caption from items in a TImageEnMView is included when printing thumbnails (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only)
!!}
property ThumbnailShowText: Boolean read fThumbnailShowText write fThumbnailShowText;
{!!
<FS>TIOPrintPreviewParams.DlgWidth
<FM>Declaration<FC>
property DlgWidth : Integer;
<FM>Description<FN>
The width of the Preview dialog in pixels or zero for the default size (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only)
!!}
property DlgWidth : Integer read fDlgWidth write fDlgWidth;
{!!
<FS>TIOPrintPreviewParams.DlgHeight
<FM>Declaration<FC>
property DlgHeight : Integer;
<FM>Description<FN>
The Height of the Preview dialog in pixels or zero for the default size (TImageEnMIO.<A TImageEnMIO.DoPrintPreviewDialog> only)
!!}
property DlgHeight : Integer read fDlgHeight write fDlgHeight;
procedure SaveToFile(const FileName: WideString);
procedure LoadFromFile(const FileName: WideString);
procedure SaveToStream(Stream: TStream);
procedure LoadFromStream(Stream: TStream);
procedure SetProperty(Prop, Value: WideString);
function GetProperty(const Prop: WideString): WideString;
end;
{$ENDIF}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// TImageEnIO
{!!
<FS>TImageEnIO.TIEIOSeekDestination
<FM>Declaration<FC>
TIEIOSeekDestination = (ieioSeekFirst, ieioSeekPrior, ieioSeekNext, ieioSeekLast);
<FM>Description<FN>
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>ieioSeekFirst<FN></C> <C>Go to first page</C> </R>
<R> <C><FC>ieioSeekPrior<FN></C> <C>Go to previous page (or first page)</C> </R>
<R> <C><FC>ieioSeekNext<FN></C> <C>Go to next page (or last page)</C> </R>
<R> <C><FC>ieioSeekLast<FN></C> <C>Go to last page</C> </R>
</TABLE>
!!}
TIEIOSeekDestination = (ieioSeekFirst, ieioSeekPrior, ieioSeekNext, ieioSeekLast);
{!!
<FS>TImageEnIO
<FM>Description<FN>
TImageEnIO provides input/output support to ImageEn:
- <L TImageEnIO.LoadFromFile>Loading</L> and <L TImageEnIO.SaveToFile>saving</L> images
- Access to <L TImageEnIO.Params>image properties and meta-data</L>
- <L TImageEnIO.Acquire>Acquisition</L> of images from cameras and scanners
- <L TImageEnIO.DoPrintPreviewDialog>Printing</L>
- <L TImageEnIO.DShowParams>DirectShow</L> functions for multimedia support
See also: <A TImageEnMIO>, which is made to work with images containing multiple frames (e.g. animated GIFs)
Generally you will not add a TImageEnIO component directly to your project. It is accessed via the following methods:
<FM>1. Using the <A TImageEnView.IO> property of a <A TImageEnView> or <A TImageEnVect><FN>
ImageEnView1.IO.LoadFromFile('C:\MyImage.jpeg');
ImageEnView1.IO.DoPrintPreviewDialog;
<FM>2. Attached to a TBitmap or <A TIEBitmap> in code<FN>
MyBitmap := TBitmap.create;
AnImageEnIO := TImageEnIO.CreateFromBitmap(MyBitmap);
AnImageEnIO.LoadFromFile('C:\input.jpg');
...
AnImageEnIO.Free;
MyBitmap.Free;
<FM>3. Attached to a TImage<FN>
Note: In this case a TImageEnIO would be added to the form and the <A TImageEnIO.AttachedTImage> set appropriately.
<FM>Notes<FN>
- Ensure you do not call any TImageEnIO methods before it is actually attached to an image container (<A TImageEnView>, <A TIEBitmap>, etc)
- Do not attach TImageEnIO to a <A TImageEnMView> component. Only a <A TImageEnMIO> can be attached to a <A TImageEnMView> component.
<FN>
<FM>Methods and Properties<FN>
<FI>Connected Component<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.AttachedBitmap></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.AttachedIEBitmap></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.AttachedImageEn></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.AttachedTImage></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.Update></C> </R></C> </R>
</TABLE>
<FI>Generic Input/Output<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.Aborting></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.AssignParams></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.AutoAdjustDPI></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.Background></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.Bitmap></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.CaptureFromScreen></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.ChangeBackground></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.Create></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.CreateFromBitmap></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.DefaultDitherMethod></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.FilteredAdjustDPI></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.IEBitmap></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromBuffer></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileAuto></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromResource></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStream></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromText></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromURL></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.NativePixelFormat></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.Params></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 TImageEnIO.SaveToFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStream></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToText></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.Seek></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.StreamHeaders></C> </R>
</TABLE>
<FI>Image Acquisition (Twain/WIA)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.Acquire></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SelectAcquireSource></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.SelectedAcquireSource></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SetAcquireSource></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.AcquireParams></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.DCIMParams></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.TwainParams></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.TwainAcquireOpen></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.TwainAcquireClose></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.WIAParams></C> </R>
</TABLE>
<FI>Aynchronous input/output<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.AsyncMode></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.AsyncRunning></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.ThreadsCount></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.WaitThreads></C> </R>
</TABLE>
<FI>DirectShow capture<FN>
<TABLE2>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.DShowParams></C> </R>
</TABLE>
<FI>Dialogs<FN>
<TABLE2>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.DialogsMeasureUnit></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.DoPreviews></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ExecuteOpenDialog></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ExecuteSaveDialog></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.PreviewFont></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.PreviewFontEnabled></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.PreviewsParams></C> </R>
<R> <C_IMG_PUBLISHED> <C><A TImageEnIO.SimplifiedParamsDialogs></C> </R>
</TABLE>
<FI>Printing<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.DoPrintPreviewDialog></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.PreviewPrintImage></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.PrintImagePos></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.PrintImage></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.PrintingFilterOnSubsampling></C> </R>
<R> <C_IMG_PROPERTY> <C><A TImageEnIO.PrintPreviewParams></C> </R>
</TABLE>
<FI>IEN (ImageEn native image format with layers)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileIEN></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamIEN></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileIEN></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamIEN></C> </R>
</TABLE>
<FI>JPEG<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InjectJpegEXIFStream></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InjectJpegEXIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InjectJpegIPTCStream></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InjectJpegIPTC></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileJpeg></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamJpeg></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileJpeg></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamJpeg></C> </R>
</TABLE>
<FI>JPEG 2000<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileJ2K></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileJP2></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamJ2K></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamJP2></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileJ2K></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileJP2></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamJ2K></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamJP2></C> </R>
</TABLE>
<FI>GIF<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InsertToFileGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamGIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ReplaceFileGIF></C> </R>
</TABLE>
<FI>Adobe PSD<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFilePSD></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamPSD></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFilePSD></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamPSD></C> </R>
</TABLE>
<FI>Microsoft HD Photos (HDP)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileHDP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamHDP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileHDP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamHDP></C> </R>
</TABLE>
<FI>TIFF<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InjectTIFFEXIF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InsertToFileTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InsertToStreamTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ReplaceFileTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ReplaceStreamTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileTIFF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamTIFF></C> </R>
</TABLE>
<FI>BMP<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileBMP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamBMP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileBMP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamBMP></C> </R>
</TABLE>
<FI>PNG<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFilePNG></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamPNG></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFilePNG></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamPNG></C> </R>
</TABLE>
<FI>Cursors (CUR)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileCUR></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamCUR></C> </R>
</TABLE>
<FI>ICO<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileICO></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamICO></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileICO></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamICO></C> </R>
</TABLE>
<FI>PCX<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFilePCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamPCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFilePCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamPCX></C> </R>
</TABLE>
<FI>DCX (Multipage PCX)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileDCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamDCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamDCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileDCX></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.InsertToFileDCX></C> </R>
</TABLE>
<FI>Meta Files (WMF, EMF)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ImportMetafile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.MergeMetaFile></C> </R>
</TABLE>
<FI>SVG (Scalable Vector Graphics)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileSVG></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamSVG></C> </R>
</TABLE>
<FI>Targa (TGA)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileTGA></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamTGA></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileTGA></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamTGA></C> </R>
</TABLE>
<FI>PXM (PPM, PBM, PGM)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFilePXM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamPXM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFilePXM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamPXM></C> </R>
</TABLE>
<FI>AVI Videos<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.CloseAVIFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.CreateAVIFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.IsOpenAVI></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromAVI></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.OpenAVIFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToAVI></C> </R>
</TABLE>
<FI>WBMP<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileWBMP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamWBMP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileWBMP></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamWBMP></C> </R>
</TABLE>
<FI>PostScript (PS)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ClosePSFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.CreatePSFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFilePS></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToPS></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamPS></C> </R>
</TABLE>
<FI>Adobe PDF<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.ClosePDFFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.CreatePDFFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFilePDF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToPDF></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamPDF></C> </R>
</TABLE>
<FI>Raw Camera Files<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileRAW></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamRAW></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadJpegFromFileCRW></C> </R>
</TABLE>
<FI>Media Files (AVI, MPEG, WMV..)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.CloseMediaFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.IsOpenMediaFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromMediaFile></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.OpenMediaFile></C> </R>
</TABLE>
<FI>BmpRaw (a true "raw" format, not the same as a digital camera Raw file)<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileBMPRAW></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamBMPRAW></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileBMPRAW></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamBMPRAW></C> </R>
</TABLE>
<FI>DICOM Medical Imaging Format<FN>
<TABLE2>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileDICOM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamDICOM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileDICOM></C> </R>
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamDICOM></C> </R>
</TABLE>
<FM>Events<FN>
<TABLE2>
<R> <C_IMG_EVENT> <C><A TImageEnIO.OnAcquireBitmap></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnIO.OnAcquireClose></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnIO.OnDoPreviews></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnIO.OnFinishWork></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnIO.OnIOPreview></C> </R>
<R> <C_IMG_EVENT> <C><A TImageEnIO.OnProgress></C> </R>
</TABLE>
!!}
{$ifdef IEHASPLATFORMATTRIBUTE}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$endif}
TImageEnIO = class(TComponent)
private
fBitmap: TBitmap; // refers to the bitmap (if fImageEnView is valid then it is FImageEnView.bitmap)
fIEBitmap: TIEBitmap; // encapsulates fBitmap if SetBitmap, SetAttachedBitmap, SetAttachedImageEn, SetTImage are called
fIEBitmapCreated: boolean; // true is fIEBitmap is created by TImageEnIO
fImageEnView: TIEView; // refers to TIEView (fbitmap=fimageenview.bitmap)
fImageEnViewBitmapChangeHandle: Pointer; // bitmap change handle (nil=none)
fTImage: TImage; // refers to TImage
fBackground: TColor; // valid only if fImageEnview = nil
fPreviewsParams: TIOPreviewsParams;
fSimplifiedParamsDialogs: boolean;
fOnDoPreviews: TIEDoPreviewsEvent;
fChangeBackground: boolean; // if true change the Background property using the loaded image background
{$ifdef IEINCLUDEIEXACQUIRE}
fAcquireParams : TIEAcquireParams;
fTwainParams: TIETwainParams;
{$endif}
{$IFDEF IEINCLUDEWPD}
fDCIMParams : TIEDcimAcquire;
{$endif}
fStreamHeaders: boolean; // enable/disable load/save stream headers
fPreviewFont: TFont;
fPreviewFontEnabled: Boolean;
fOnIOPreview: TIEIOPreviewEvent;
fDialogsMeasureUnit: TIEDialogsMeasureUnit;
fAutoAdjustDPI: boolean;
fFilteredAdjustDPI: boolean;
fAVI_avf: pointer; // PAVIFILE
fAVI_avs: pointer; // PAVISTREAM
fAVI_avs1: pointer; // PAVISTREAM
fAVI_gf: pointer; // PGETFRAME
fAVI_psi: TAviStreamInfoW_Ex;
fAVI_popts: pointer; // PAVICOMPRESSOPTIONS
fAVI_idx: integer;
{$ifdef IEINCLUDEDIRECTSHOW}
fOpenMediaFile: TIEDirectShow; // open media file
fOpenMediaFileRate: Double;
fOpenMediaFileMul: Integer;
{$endif}
fPS_handle: pointer;
fPS_stream: TIEWideFileStream;
fPDF_handle: pointer;
fPDF_stream: TIEWideFileStream;
fAsyncThreads: TList; // Count > 0 is one or more threads are running
fAsyncThreadsFinishEvent: THandle;
fAsyncThreadsCS: TCriticalSection; // protect fAsyncThreads access
fAsyncMode: boolean; // true if we need async mode
fPrintingFilterOnSubsampling: TResampleFilter;
// Twain modeless
fgrec: pointer;
// WIA
{$IFDEF IEINCLUDEIEXACQUIRE}
fWIA: TIEWia;
{$ENDIF}
// DirectShow
{$IFDEF IEINCLUDEDIRECTSHOW}
fDShow: TIEDirectShow;
{$ENDIF}
// Media Foundation Grabber
{$IFDEF IEINCLUDEMEDIAFOUNDATION}
fMediaFoundationSourceReader: TIEMediaFoundationSourceReader;
{$ENDIF}
//
fDefaultDitherMethod: TIEDitherMethod;
fResetPrinter: boolean;
{$IFDEF IEINCLUDEPRINTDIALOGS}
fPrintPreviewParams: TIOPrintPreviewParams;
{$ENDIF}
//
function IsInsideAsyncThreads: Boolean;
procedure SetAttachedBitmap(atBitmap: TBitmap);
procedure SetAttachedImageEn(atImageEn: TIEView);
function GetReBackground: TColor;
procedure SetReBackground(v: TColor);
procedure SetPreviewFont(f: TFont);
procedure SetPreviewFontEnabled(Value: Boolean);
procedure SetTImage(v: TImage);
procedure SetIOPreviewParams(v: TIOPreviewsParams);
function GetIOPreviewParams: TIOPreviewsParams;
procedure AdjustDPI;
function GetAsyncRunning: integer;
function GetThreadsCount: integer;
procedure SetDefaultDitherMethod(Value: TIEDitherMethod);
{$IFDEF IEINCLUDEIEXACQUIRE}
function WiaOnProgress(Percentage: integer): boolean;
{$ENDIF}
procedure SetPrintLogFile(v: String);
function GetPrintLogFile: String;
procedure UpdateAPP138BimResolution;
procedure ParamsFromMetaFile(stream: TStream);
function GetImageEnVersion: String;
procedure SetImageEnVersion(Value: String);
procedure SetAborting(Value: Boolean);
function GetParams: TIOParams;
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}
procedure CheckHaveValidBitmap();
procedure ParamsFromStreamIEN(Stream: TStream; LoadThumbnail: Boolean = False);
procedure GeneratePrintBitmap(PrintAnnotations, PrintLayers: Boolean);
procedure ResetModified(AllLayers: Boolean = False);
protected
fAborting: boolean;
fOnIntProgress: TIEProgressEvent; // internal progress event, always assigned to DoIntProgress
fOnProgress: TIEProgressEvent;
fOnFinishWork: TNotifyEvent;
fOnAcquireBitmap: TIEAcquireBitmapEvent;
fOnAcquireClose: TNotifyEvent;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure OnBitmapChange(Sender: TObject; destroying: boolean);
{$IFDEF IEINCLUDEJPEG2000}
function LoadFromStreamJ2000(Stream: TStream): Boolean;
procedure SaveToStreamJ2000(Stream: TStream; format: integer);
{$ENDIF} // IEINCLUDEJPEG2000
procedure SetBitmap(bmp: TBitmap);
procedure SetIEBitmap(bmp: TIEBitmap);
procedure SetAttachedIEBitmap(bmp: TIEBitmap);
procedure TWMultiCallBack(Bitmap: TIEBitmap; var IOParams: TObject; ImDpiX, ImDpiY: integer); virtual;
procedure TWCloseCallBack; virtual;
procedure DoAcquireBitmap(ABitmap: TIEBitmap; ImDpiX, ImDpiY: integer; var Handled: boolean); dynamic;
procedure DoFinishWork; virtual;
function GetBitmap: TBitmap; virtual;
function MakeConsistentBitmap(allowedFormats: TIEPixelFormatSet): boolean;
{$IFDEF IEINCLUDEIEXACQUIRE}
function GetWIAParams: TIEWia; virtual;
{$ENDIF}
{$IFDEF IEINCLUDEDIRECTSHOW}
function GetDShowParams: TIEDirectShow; virtual;
{$ENDIF}
{$IFDEF IEINCLUDEMEDIAFOUNDATION}
function GetMediaFoundationSourceReader(): TIEMediaFoundationSourceReader;
{$ENDIF}
function SyncLoadFromStreamGIF(Stream: TStream): integer;
function SyncLoadFromStreamPCX(Stream: TStream; streamhead: boolean) : Boolean;
function SyncLoadFromStreamDCX(Stream: TStream) : Boolean;
function SyncLoadFromStreamTIFF(Stream: TStream; streamhead: boolean): integer;
function SyncLoadFromStreamBMP(Stream: TStream) : Boolean;
procedure SyncSaveToStreamJpeg(Stream: TStream; streamhead: boolean);
procedure SyncSaveToStreamPS(Stream: TStream);
{$ifdef IEINCLUDEPDFWRITING}
procedure SyncSaveToStreamPDF(Stream: TStream);
{$endif}
{$ifdef IEINCLUDEDICOM}
procedure SyncSaveToStreamDICOM(Stream: TStream);
{$endif}
procedure SyncSaveToStreamBMP(Stream: TStream);
procedure SyncSaveToStreamDCX(Stream: TStream);
{$ifdef IEINCLUDEPSD}
function SyncLoadFromStreamPSD(Stream: TStream) : Boolean;
{$endif}
function SyncLoadFromStreamCUR(Stream: TStream) : Boolean;
function SyncLoadFromStreamICO(Stream: TStream) : Boolean;
{$ifdef IEINCLUDEWIC}
function SyncLoadFromStreamHDP(Stream: TStream) : Boolean;
{$endif}
{$ifdef IEINCLUDERAWFORMATS}
function SyncLoadFromStreamRAW(Stream: TStream) : Boolean;
{$endif}
function SyncLoadFromStreamBMPRAW(Stream: TStream) : Boolean;
procedure SyncSaveToStreamBMPRAW(Stream: TStream);
function SyncLoadFromStreamTGA(Stream: TStream) : Boolean;
function SyncLoadFromStreamPNG(Stream: TStream) : Boolean;
function SyncLoadFromStreamPXM(Stream: TStream) : Boolean;
function SyncLoadFromStreamWBMP(Stream: TStream) : Boolean;
function SyncLoadFromStreamJPEG(Stream: TStream; bCheckHeader: Boolean) : Boolean;
{$ifdef IEINCLUDEDICOM}
function SyncLoadFromStreamDICOM(Stream: TStream) : Boolean;
{$endif}
procedure CheckDPI;
procedure SetNativePixelFormat(value: Boolean);
function GetNativePixelFormat: Boolean;
procedure DoIntProgress(Sender: TObject; per: integer); virtual;
{$ifdef IEINCLUDEPSD}
procedure SyncSaveToStreamPSD(Stream: TStream);
{$endif}
{$ifdef IEINCLUDEWIC}
procedure SyncSaveToStreamHDP(Stream: TStream);
{$endif}
function LoadVectFile(const fileName: WideString; ft: TIOFileType): Boolean;
function LoadVectStream(Stream: TStream; ft: TIOFileType): Boolean;
{$ifdef IEINCLUDEIEXACQUIRE}
function GetSelectedAcquireSource : TIEAcquireSource;
{$endif}
public
fParams: TIOParams;
fPrintBitmap: TIEBitmap; // When using Print preview this is the actual image to print
constructor Create(Owner: TComponent); override;
constructor CreateFromBitmap(Bitmap: TIEBitmap); overload;
constructor CreateFromBitmap(Bitmap: TBitmap); overload;
destructor Destroy; override;
property AttachedBitmap: TBitmap read fBitmap write SetAttachedBitmap;
property AttachedIEBitmap: TIEBitmap read fIEBitmap write SetAttachedIEBitmap;
procedure Update();
procedure SyncGetHandle;
{!!
<FS>TImageEnIO.ChangeBackground
<FM>Declaration<FC>
property ChangeBackground: Boolean;
<FM>Description<FN>
When set to True, the background color of the attached <A TImageEnView> will automatically be set to to the image background color.
Default: False
Note: Not all file formats contains background color information.
!!}
property ChangeBackground: boolean read fChangeBackground write fChangeBackground;
property ThreadsCount: integer read GetThreadsCount;
property DefaultDitherMethod: TIEDitherMethod read fDefaultDitherMethod write SetDefaultDitherMethod;
{$IFDEF IEINCLUDEDIALOGIO}
function DoPreviews(pp: TPreviewParams = [ppAll]): boolean; virtual;
{$ENDIF} // IEINCLUDEDIALOGIO
property Bitmap: TBitmap read GetBitmap write SetBitmap;
property IEBitmap: TIEBitmap read fIEBitmap write SetIEBitmap;
{!!
<FS>TImageEnIO.Params
<FM>Declaration<FC>
property Params: <A TIOParams>;
<FM>Description<FN>
Provides access to the parameters and meta-data of the current image as a <A TIOParams> object. This object contains many format specific properties, such as bits per sample, type of compression, embedded text data, etc. It is filled automatically when loading images or manually using <A TImageEnIO.ParamsFromFile>. The properties can also be set or modified when saving files.
<FM>Example<FC>
// Sets color-mapped 256 colors
ImageEnView1.IO.Params.BitsPerSample := 8;
ImageEnView1.IO.Params.SamplesPerPixel := 1;
// Sets JPEG quality of 90%
ImageEnView1.IO.Params.JPEG_Quality := 90;
ImageEnView1.IO.SaveToFile('D:\output.jpg');
!!}
property Params: TIOParams read GetParams;
procedure AssignParams(Source: TObject);
procedure RecreatedTImageEnViewHandle;
{$ifdef IEINCLUDERESOURCEEXTRACTOR}
procedure LoadFromResource(const ModulePath: WideString; const ResourceType: String; const ResourceName: String; Format: TIOFileType);
{$endif}
// IEN
function LoadFromFileIEN(const FileName: WideString; Append: Boolean = False): Boolean;
function LoadFromStreamIEN(Stream: TStream; Append: Boolean = False): Boolean;
procedure SaveToStreamIEN(Stream: TStream);
procedure SaveToFileIEN(const FileName: WideString);
// SVG
procedure SaveToStreamSVG(Stream: TStream);
procedure SaveToFileSVG(const FileName: WideString);
// JPEG
procedure SaveToFileJpeg(const FileName: WideString);
function LoadFromFileJpeg(const FileName: WideString): Boolean;
procedure SaveToStreamJpeg(Stream: TStream);
function LoadFromStreamJpeg(Stream: TStream): Boolean;
function InjectJpegIPTC(const FileName: WideString): boolean;
function InjectJpegIPTCStream(InputStream, OutputStream: TStream): boolean;
function InjectJpegEXIF(const FileName: WideString): boolean;
function InjectJpegEXIFStream(InputStream, OutputStream: TStream): boolean;
// DCX
function LoadFromFileDCX(const FileName: WideString): Boolean;
function LoadFromStreamDCX(Stream: TStream): Boolean;
procedure SaveToStreamDCX(Stream: TStream);
procedure SaveToFileDCX(const FileName: WideString);
procedure InsertToFileDCX(const FileName: WideString);
// JPEG2000
{$IFDEF IEINCLUDEJPEG2000}
function LoadFromFileJP2(const FileName: WideString): Boolean;
function LoadFromFileJ2K(const FileName: WideString): Boolean;
function LoadFromStreamJP2(Stream: TStream): Boolean;
function LoadFromStreamJ2K(Stream: TStream): Boolean;
procedure SaveToStreamJP2(Stream: TStream);
procedure SaveToStreamJ2K(stream: TStream);
procedure SaveToFileJP2(const FileName: WideString);
procedure SaveToFileJ2K(const FileName: WideString);
{$ENDIF} // IEINCLUDEJPEG2000
// GIF
function LoadFromFileGIF(const FileName: WideString): integer;
procedure SaveToFileGIF(const FileName: WideString);
function InsertToFileGIF(const FileName: WideString): integer;
function LoadFromStreamGIF(Stream: TStream): integer;
procedure SaveToStreamGIF(Stream: TStream);
function ReplaceFileGIF(const FileName: WideString): integer;
// PCX
procedure SaveToStreamPCX(Stream: TStream);
function LoadFromStreamPCX(Stream: TStream): Boolean;
procedure SaveToFilePCX(const FileName: WideString);
function LoadFromFilePCX(const FileName: WideString): Boolean;
// TIFF
function LoadFromStreamTIFF(Stream: TStream): integer;
procedure SaveToStreamTIFF(Stream: TStream);
function LoadFromFileTIFF(const FileName: WideString): integer;
procedure SaveToFileTIFF(const FileName: WideString);
function InsertToFileTIFF(const FileName: WideString): integer;
function InsertToStreamTIFF(Stream: TStream): integer;
function ReplaceFileTIFF(const FileName: WideString): integer;
function ReplaceStreamTIFF(Stream: TStream): integer;
{$ifdef IEINCLUDETIFFHANDLER}
function InjectTIFFEXIF(const FileName: WideString; pageIndex: Integer = 0): boolean; overload;
function InjectTIFFEXIF(const InputFileName, OutputFileName: WideString; pageIndex: Integer = 0): boolean; overload;
function InjectTIFFEXIF(InputStream, OutputStream: TStream; pageIndex: Integer = 0): boolean; overload;
{$endif}
// BMP
procedure SaveToStreamBMP(Stream: TStream);
function LoadFromStreamBMP(Stream: TStream): Boolean;
procedure SaveToFileBMP(const FileName: WideString);
function LoadFromFileBMP(const FileName: WideString): Boolean;
// ICO
function LoadFromFileICO(const FileName: WideString): Boolean;
function LoadFromStreamICO(Stream: TStream): Boolean;
procedure SaveToStreamICO(Stream: TStream);
procedure SaveToFileICO(const FileName: WideString);
// CUR
function LoadFromFileCUR(const FileName: WideString): Boolean;
function LoadFromStreamCUR(Stream: TStream): Boolean;
// PNG
{$IFDEF IEINCLUDEPNG}
function LoadFromFilePNG(const FileName: WideString): Boolean;
function LoadFromStreamPNG(Stream: TStream): Boolean;
procedure SaveToFilePNG(const FileName: WideString);
procedure SaveToStreamPNG(Stream: TStream);
{$ENDIF}
{$ifdef IEINCLUDEDICOM}
// DICOM
function LoadFromFileDICOM(const FileName: WideString): Boolean;
function LoadFromStreamDICOM(Stream: TStream): Boolean;
procedure SaveToStreamDICOM(Stream: TStream);
procedure SaveToFileDICOM(const FileName: WideString);
{$endif}
// TGA
function LoadFromFileTGA(const FileName: WideString): Boolean;
function LoadFromStreamTGA(Stream: TStream): Boolean;
procedure SaveToFileTGA(const FileName: WideString);
procedure SaveToStreamTGA(Stream: TStream);
// METAFILE (WMF, EMF)
function ImportMetafile(const FileName: WideString; Width: Integer = -1; Height: Integer = -1; WithAlpha: boolean = True): Boolean; overload;
function ImportMetafile(Stream: TStream; Width: Integer = -1; Height: Integer = -1; WithAlpha: boolean = True): Boolean; overload;
function ImportMetafile(meta: TMetafile; Width: Integer = -1; Height: Integer = -1; WithAlpha: boolean = True): Boolean; overload;
function ImportMetafile(meta: TIEMetafile; Width: Integer = -1; Height: Integer = -1; WithAlpha: boolean = True): Boolean; overload;
procedure MergeMetafile(const FileName: WideString; x, y: Integer; Width: Integer = -1; Height: Integer = -1);
// PXM, PBM, PGM, PPM
function LoadFromFilePXM(const FileName: WideString): Boolean;
function LoadFromStreamPXM(Stream: TStream): Boolean;
procedure SaveToFilePXM(const FileName: WideString);
procedure SaveToStreamPXM(Stream: TStream);
// AVI
function OpenAVIFile(const FileName: WideString): integer;
procedure CloseAVIFile;
function LoadFromAVI(FrameIndex: integer): Boolean;
function CreateAVIFile(const FileName: WideString; rate: Double = 15.0; const codec: AnsiString='DIB '): TIECreateAVIFileResult;
procedure SaveToAVI;
function IsOpenAVI: Boolean;
// Media File
{$ifdef IEINCLUDEDIRECTSHOW}
function OpenMediaFile(const FileName: WideString): Integer;
procedure CloseMediaFile;
procedure LoadFromMediaFile(FrameIndex: Integer);
function IsOpenMediaFile: Boolean;
{$endif}
// WBMP
function LoadFromFileWBMP(const FileName: WideString): Boolean;
function LoadFromStreamWBMP(Stream: TStream): Boolean;
procedure SaveToFileWBMP(const FileName: WideString);
procedure SaveToStreamWBMP(Stream: TStream);
// PostScript (PS)
procedure CreatePSFile(const FileName: WideString);
procedure SaveToPS;
procedure ClosePSFile;
procedure SaveToStreamPS(Stream: TStream);
procedure SaveToFilePS(const FileName: WideString);
// PDF
{$ifdef IEINCLUDEPDFWRITING}
procedure CreatePDFFile(const FileName: WideString);
procedure SaveToPDF;
procedure ClosePDFFile;
procedure SaveToStreamPDF(Stream: TStream);
procedure SaveToFilePDF(const FileName: WideString);
{$endif}
// RAW
{$ifdef IEINCLUDERAWFORMATS}
function LoadFromStreamRAW(Stream: TStream): Boolean;
function LoadFromFileRAW(const FileName: WideString): Boolean;
function LoadJpegFromFileCRW(const FileName: WideString): Boolean;
{$endif}
// Real RAW
function LoadFromStreamBMPRAW(Stream: TStream): Boolean;
function LoadFromFileBMPRAW(const FileName: WideString): Boolean;
procedure SaveToStreamBMPRAW(Stream: TStream);
procedure SaveToFileBMPRAW(const FileName: WideString);
// PSD
{$ifdef IEINCLUDEPSD}
function LoadFromStreamPSD(Stream: TStream): Boolean;
function LoadFromFilePSD(const FileName: WideString): Boolean;
procedure SaveToStreamPSD(Stream: TStream);
procedure SaveToFilePSD(const FileName: WideString);
{$endif}
// HDP
{$ifdef IEINCLUDEWIC}
function LoadFromStreamHDP(Stream: TStream): Boolean;
function LoadFromFileHDP(const FileName: WideString): Boolean;
procedure SaveToStreamHDP(Stream: TStream);
procedure SaveToFileHDP(const FileName: WideString);
{$endif}
// GENERAL
function LoadFromFile(const FileName: WideString; FileFormat: TIOFileType): Boolean; overload; dynamic;
function LoadFromFile(const FileName: WideString; bCheckUnknown: Boolean = True): Boolean; overload; dynamic;
function LoadFromFileAuto(const FileName: WideString): Boolean; dynamic;
procedure SaveToFile(const FileName: WideString; ImageFormat: TIOFileType = -1); dynamic;
procedure SaveToText(const FileName: WideString; ImageFormat: TIOFileType = -1; TextFormat: TIETextFormat = ietfASCIIArt); overload; dynamic;
procedure SaveToText(Stream: TStream; ImageFormat: TIOFileType = -1; TextFormat: TIETextFormat = ietfASCIIArt); overload; dynamic;
procedure LoadFromText(const FileName: WideString; TextFormat: TIETextFormat = ietfBase64); overload;
procedure LoadFromText(Stream: TStream; TextFormat: TIETextFormat = ietfBase64); overload;
procedure LoadFromBuffer(Buffer: Pointer; BufferSize: Integer; Format: TIOFileType = ioUnknown); dynamic;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function LoadFromFileFormat(const FileName: WideString; FileFormat: TIOFileType): Boolean; dynamic; {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use LoadFromFile instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
function LoadFromStreamFormat(Stream: TStream; FileFormat: TIOFileType): Boolean; dynamic; {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use LoadFromStream instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
{$endif}
{!!
<FS>TImageEnIO.Aborting
<FM>Declaration<FC>
property Aborting: Boolean;
<FM>Description<FN>
During an operation such as loading or saving, setting Aborting to true will halt the current process.
If set to True while loading, the loaded image will be truncated (i.e. only a portion of the image is loaded).
If set to True while saving, the file will be closed and truncated (i.e. it will be unreadable and should be deleted).
<FC>Aborting<FN> can also be read after loading or saving to determine if an abort has occured.
<FM>Load Error Example<FC>
MyImageEnMView.LoadFromFileGIF('C:\MyGif.gif');
if MyImageEnMView.Aborting then
ShowMessage('GIF Load Error!');
Which is the same as:
if MyImageEnMView.LoadFromFileGIF('C:\MyGif.gif') = False then
ShowMessage('GIF Load Error!');
<FM>Abort Loading Example<FC>
// Begin to load image
procedure TForm1.btnLoadClick(Sender: TObject);
begin
ImageEnView1.IO.LoadFromFile('C:\xyx.bmp');
end;
// Progress of load
procedure TForm1.ImageEnIO1Progress(Sender: TObject; per: Integer);
begin
ProgressBar1.Position := per;
Application.ProcessMessages; // <- important!
end;
// STOP! button
procedure TForm1.btnStopClick(Sender: TObject);
begin
// Cancel loading
ImageEnView1.IO.Aborting := True;
end;
!!}
property Aborting: boolean read fAborting write SetAborting;
function ParamsFromFile(const FileName: WideString; Format: TIOFileType): Boolean; overload; dynamic;
function ParamsFromFile(const FileName: WideString; bUseExtension: Boolean = False): Boolean; overload; dynamic;
function ParamsFromStream(Stream: TStream; Format: TIOFileType = ioUnknown): Boolean; dynamic;
function ParamsFromBuffer(Buffer: Pointer; BufferSize: Integer; Format: TIOFileType = ioUnknown): Boolean; dynamic;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function ParamsFromFileFormat(const FileName: WideString; Format: TIOFileType): Boolean; dynamic; {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use ParamsFromFile instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
function ParamsFromStreamFormat(Stream: TStream; Format: TIOFileType): Boolean; dynamic; {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use ParamsFromStream instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
{$ENDIF}
function LoadFromStream(Stream: TStream; FileFormat: TIOFileType = ioUnknown): Boolean; dynamic;
{$IFDEF VIDEO_THUMBNAILS}
function LoadThumbnailFromExplorer(const FileName : WideString; iDesiredWidth : Integer = 120; iDesiredHeight : Integer = 120) : Boolean;
{$ENDIF}
procedure SaveToStream(Stream: TStream; FileType: TIOFileType); dynamic;
function Seek(Destination: TIEIOSeekDestination; FileName: WideString = ''): Integer;
{$IFDEF IEINCLUDEOPENSAVEDIALOGS}
function ExecuteOpenDialog(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) : WideString; overload;
function ExecuteOpenDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False) : WideString; 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) : WideString; overload;
function ExecuteSaveDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False) : WideString; overload;
{$ENDIF} // IEINCLUDEOPENSAVEDIALOGS
procedure CaptureFromScreen(Source: TIECSSource = iecsScreen; MouseCursor: TCursor = -1);
function LoadFromURL(const URL: WideString): Boolean;
// TWAIN SCANNERS
{$IFDEF IEINCLUDEIEXACQUIRE}
function Acquire(bResetParams : Boolean = False) : boolean;
function SelectAcquireSource(Apis : TIEAcquireApis = [ieaTwain, ieaWIA]): 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} // IEINCLUDEIEXACQUIRE
// ASYNC WORKS
property AsyncRunning: integer read GetAsyncRunning;
{!!
<FS>TImageEnIO.AsyncMode
<FM>Declaration<FC>
property AsyncMode: Boolean;
<FM>Description<FN>
Set to True to enable asynchronous input/output operations.
When asynchronous mode is enabled, each input/output method creates a new thread to executes the task then returns without waiting for the task to complete.
Note: Applicable only when TImageEnIO is attached to a <A TIEBitmap> object.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\Preload\Preload.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// multithread saving
Var
Bmp: TIEBitmap;
Io: TImageEnIO;
Begin
Bmp:= TIEBitmap.Create;
Io := TImageEnIO.CreateFromBitmap(bmp);
Io.LoadFromFile('C:\input.bmp');
Io.AsyncMode := True; // So it will create a thread for each input/output task
Io.SaveToFile('D:\i1.jpg'); // thread 1
Io.SaveToFile('D:\i2.jpg'); // thread 2
Io.SaveToFile('D:\i3.jpg'); // thread 3
Io.Free; // Free method will wait for all tasks to end!
Bmp.Free;
End;
!!}
property AsyncMode: boolean read fAsyncMode write fAsyncMode;
procedure WaitThreads(Aborts: Boolean = false);
procedure SuspendThreads; {$ifdef IEHASTTHREADSTART} deprecated; {$endif}
procedure ResumeThreads; {$ifdef IEHASTTHREADSTART} deprecated; {$endif}
{!!
<FS>TImageEnIO.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 DCIM Retrieval. AcquireParams accesses <A TImageEnIO.TwainParams>, <A TImageEnIO.WIAParams> and <A TImageEnIO.DCIMParams>.
If you have called <A TImageEnIO.SelectAcquireSource> or <A TImageEnIO.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>TImageEnIO.TwainParams
<FM>Declaration<FC>
property TwainParams: <A TIETwainParams>;
<FM>Description<FN>
Use the TwainParams property to control acquisition from Twain scanners and cameras. You can enable/disable the standard user interface, set pixel type (Grayscale, RGB...), DPI, etc.
Note: Use TwainParams only when you need access to Twain specific parameters and functionality (when <A TImageEnIO.SelectedAcquireSource>.Api is ieaTwain). For generic access to all image acquisitions sources (Twain, WIA, etc.) use <A TImageEnIO.AcquireParams> instead.
<FM>Example<FC>
// Acquire a black/white (1bit) image from the default Twain device
ImageEnView1.IO.TwainParams.PixelType.CurrentValue := 0;
if ImageEnView1.IO.SetSource(ieaTwain, Default_Device) then
ImageEnView1.IO.Acquire;
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\Twain\TwainDemo.dpr </C> </R>
</TABLE>
<FM>See Also<FN>
- <A TIETwainParams>
- <A TImageEnIO.AcquireParams>
- <A TImageEnIO.SelectedAcquireSource>
!!}
{$IFDEF IEINCLUDEIEXACQUIRE}
property TwainParams: TIETwainParams read fTwainParams;
{$ENDIF}
{!!
<FS>TImageEnIO.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 camera devices (which appear as USB drives).
Notes:
- Use DCIMParams only when you need access to DCIM specific functionality (when <A TImageEnIO.SelectedAcquireSource>.Api is ieaDCIM). For generic access to all image acquisitions sources (Twain, WIA, etc.) use <A TImageEnIO.AcquireParams> instead
- Not available in Delphi/C++ Builder 5
!!}
{$IFDEF IEINCLUDEWPD}
property DCIMParams: TIEDcimAcquire read fDCIMParams;
{$ENDIF}
{$IFDEF IEINCLUDEIEXACQUIRE}
property WIAParams: TIEWia read GetWIAParams;
{$ENDIF}
// Video capture
{$IFDEF IEINCLUDEDIRECTSHOW}
property DShowParams: TIEDirectShow read GetDShowParams;
{$ENDIF}
{$IFDEF IEINCLUDEMEDIAFOUNDATION}
property MediaFoundationSourceReader: TIEMediaFoundationSourceReader read GetMediaFoundationSourceReader;
{$ENDIF}
// PRINTING
procedure PrintImageEx(PrintBMP: TIEBitmap; PrtCanvas: TCanvas; dpix, dpiy: integer; pagewidth, pageheight: double; MarginLeft, MarginTop, MarginRight, MarginBottom: double; VerticalPos: TIEVerticalPos; HorizontalPos: TIEHorizontalPos; Size: TIESize; SpecWidth, SpecHeight: double; GammaCorrection: double; bPrinting: Boolean = True);
procedure PrintImagePos(PrtCanvas: TCanvas; x, y: double; Width, Height: double; GammaCorrection: double = 1; PrintAnnotations: Boolean = False; PrintLayers: Boolean = False);
procedure PrintImagePosEx(PrintBMP: TIEBitmap; PrtCanvas: TCanvas; dpix, dpiy: integer; x, y: double; Width, Height: double; GammaCorrection: double);
procedure PrintImage(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; PrintLayers: Boolean = False);
procedure PreviewPrintImage(DestBitmap: TBitmap; MaxBitmapWidth: integer; MaxBitmapHeight: integer; PrinterObj: TPrinter = 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);
procedure PreviewPrintImageEx(PrintBMP: TIEBitmap; DestBitmap: TBitmap; MaxBitmapWidth, MaxBitmapHeight: integer; PrinterObj: TPrinter;
MarginLeft, MarginTop, MarginRight, MarginBottom: double;
VerticalPos: TIEVerticalPos; HorizontalPos: TIEHorizontalPos; Size: TIESize;
SpecWidth, SpecHeight: double; GammaCorrection: double);
{$IFDEF IEINCLUDEPRINTDIALOGS}
function DoPrintPreviewDialog(DialogType: TIEDialogType = iedtDialog; const TaskName: WideString = ''; PrintAnnotations: Boolean = False; const Caption: WideString=''; PrintLayers: Boolean = False): boolean;
{!!
<FS>TImageEnIO.PrintPreviewParams
<FM>Declaration<FC>
property PrintPreviewParams: <A TIOPrintPreviewParams>;
<FM>Description<FN>
This property provides access to the parameters of the Print Preview dialog.
Note: All measure units are specified by <A TImageEnIO.DialogsMeasureUnit> property.
!!}
property PrintPreviewParams: TIOPrintPreviewParams read fPrintPreviewParams;
{$ENDIF}
{!!
<FS>TImageEnIO.PrintingFilterOnSubsampling
<FM>Declaration<FC>
property PrintingFilterOnSubsampling: <A TResampleFilter>;
<FM>Description<FN>
Specifies a filter when an image needs to be resampled for printing.
Filtering enhances the image quality, but slows down 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}
//
property ResetPrinter: boolean read fResetPrinter write fResetPrinter;
property PrintLogFile: String read GetPrintLogFile write SetPrintLogFile;
published
property AttachedImageEn: TIEView read fImageEnView write SetAttachedImageEn;
property Background: TColor read GetReBackground write SetReBackground default clBlack;
{!!
<FS>TImageEnIO.OnProgress
<FM>Declaration<FC>
property OnProgress: <A TIEProgressEvent>;
<FM>Description<FN>
Occurs during input/output operations. It is commonly used to show task progress.
Notes:
- If you are using it to update a progress bar then you can reset it in the <A TImageEnIO.OnFinishWork> event.
- To access I/O progress for the <A TImageEnView.IO> class of a TImageEnView, use the <A TImageEnView.OnProgress> event.
<FM>Example<FC>
procedure TForm1.ImageEnIO1Progress(Sender: TObject; per: Integer);
begin
// Show load/save progress
ProgressBar1.Visible := True;
ProgressBar1.Position := per;
Application.ProcessMessages; // <- important!
end;
procedure TForm1.ImageEnIO1FinishWork(Sender: TObject);
begin
// Hide the progress bar
ProgressBar1.Visible := False;
end;
!!}
property OnProgress: TIEProgressEvent read fOnProgress write fOnProgress;
property PreviewsParams: TIOPreviewsParams read GetIOPreviewParams write SetIOPreviewParams default [];
{!!
<FS>TImageEnIO.StreamHeaders
<FM>Declaration<FC>
property StreamHeaders: boolean;
<FM>Description<FN>
If True, each SaveToStreamXXX method adds an additional special header as needed for multi-image streams.
When a special header is added, the images saved with SaveToStream*** aren't compatible with LoadFromFile*** methods.
<FM>Example<FC>
// Save ImageEnView1 and ImageEnView2 images in the file, images.dat
// Note: images.dat won't be loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('bmpimages.dat', fmCreate);
ImageEnView1.IO.StreamHeaders := True;
ImageEnView1.IO.SaveToStreamJPEG(fs);
ImageEnView2.IO.StreamHeaders := True;
ImageEnView2.IO.SaveToStreamJPEG(fs);
fs.free;
End;
// Save a single image in image.jpg
// image.jpg is loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('image.jpg');
ImageEnView1.IO.StreamHeaders := False;
ImageEnView1.IO.SaveToFileJPEG(fs);
End;
!!}
property StreamHeaders: boolean read fStreamHeaders write fStreamHeaders default false;
property PreviewFont: TFont read fPreviewFont write SetPreviewFont;
property PreviewFontEnabled: Boolean read fPreviewFontEnabled write SetPreviewFontEnabled default false;
property AttachedTImage: TImage read fTImage write SetTImage;
{!!
<FS>TImageEnIO.OnIOPreview
<FM>Declaration<FC>
property OnIOPreview: <A TIEIOPreviewEvent>;
<FM>Description<FN>
OnIOPreview is called before the preview form is displayed (i.e. when calling the <A TImageEnIO.DoPreviews> method).
<FM>Example<FC>
procedure TForm1.ImageEnIO1IOPreview(Sender: TObject; PreviewForm: TForm);
begin
with (PreviewForm as TfIOPreviews) do
ProgressBar1.Visible := False;
end;
!!}
property OnIOPreview: TIEIOPreviewEvent read fOnIOPreview write fOnIOPreview;
{!!
<FS>TImageEnIO.DialogsMeasureUnit
<FM>Declaration<FC>
property DialogsMeasureUnit: <A TIEDialogsMeasureUnit>
<FM>Description<FN>
Specifies the measurement unit used in the <L TImageEnIO.DoPrintPreviewDialog>Print Preview dialog</L>
<FM>Example<FC>
ImageEnView1.IO.DialogsMeasureUnit := ieduCm;
ImageEnView1.IO.DoPrintPreviewDialog(iedtDialog);
!!}
property DialogsMeasureUnit: TIEDialogsMeasureUnit read fDialogsMeasureUnit write fDialogsMeasureUnit default ieduInches;
{!!
<FS>TImageEnIO.AutoAdjustDPI
<FM>Declaration<FC>
property AutoAdjustDPI: Boolean;
<FM>Description<FN>
When set to True and the current (loaded or scanned) image has a horizontal DPI that does not not equal its vertical DPI, ImageEn will resize the image to make them equal.
Default: False
!!}
property AutoAdjustDPI: boolean read fAutoAdjustDPI write fAutoAdjustDPI default False;
{!!
<FS>TImageEnIO.FilteredAdjustDPI
<FM>Declaration<FC>
property FilteredAdjustDPI: Boolean;
<FM>Description<FN>
If set to True, ImageEn applies a resampling filter to enhance quality when adjusting an image's DPI.
Note: Only valid when <A TImageEnIO.AutoAdjustDPI> is True. It can slow down the loading process.
!!}
property FilteredAdjustDPI: boolean read fFilteredAdjustDPI write fFilteredAdjustDPI default false;
{!!
<FS>TImageEnIO.OnFinishWork
TImageEnMView component
<FM>Declaration<FC>
property OnFinishWork: TNotifyEvent;
<FM>Description<FN>
OnFinishWork occurs when an input/output task ends. It is useful for resetting a progress bar or to know when a thread ends in a asynchronous mode.
<FM>Example<FC>
procedure TForm1.ImageEnIO1Progress(Sender: TObject; per: Integer);
begin
// Show load/save progress
ProgressBar1.Visible := True;
ProgressBar1.Position := per;
Application.ProcessMessages; // <- important!
end;
procedure TForm1.ImageEnIO1FinishWork(Sender: TObject);
begin
// Hide the progress bar
ProgressBar1.Visible := False;
end;
<FM>See Also<FN>
- <L TImageEnIO.OnProgress>TImageEnIO.OnProgress</L>
- <L TImageEnView.OnFinishWork>TImageEnView.OnFinishWork</L>
!!}
property OnFinishWork: TNotifyEvent read fOnFinishWork write fOnFinishWork;
{!!
<FS>TImageEnIO.OnAcquireBitmap
<FM>Declaration<FC>
property OnAcquireBitmap: <A TIEAcquireBitmapEvent>;
<FM>Description<FN>
Occurs whenever a new bitmap is acquired during a multi-page acquisition.
<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>Has no effect when acquiring via a TImageEnView/TImageEnIO</C> </R>
</TABLE>
!!}
property OnAcquireBitmap: TIEAcquireBitmapEvent read fOnAcquireBitmap write fOnAcquireBitmap;
{!!
<FS>TImageEnIO.OnAcquireClose
<FM>Declaration<FC>
property OnAcquireClose: TNotifyEvent;
<FM>Description<FN>
Occurs when the user closes the acquire dialog, which was opened using <A TImageEnIO.TwainAcquireOpen>.
!!}
property OnAcquireClose: TNotifyEvent read fOnAcquireClose write fOnAcquireClose;
{!!
<FS>TImageEnIO.SimplifiedParamsDialogs
<FM>Declaration<FC>
property SimplifiedParamsDialogs: Boolean;
<FM>Description<FN>
When set to true (the default), the File Format Parameters dialog (shown when clicking the "Advanced" button in ImageEn's Save dialog or using <A TImageEnIO.DoPreviews>) will show a simplified set of parameters. Set to false to display a fuller set of parameters.
<FM>Example<FC>
The Parameters dialog for TIFF, using SimplifiedParamsDialogs = True:
<IMG help_images\68.jpg>
The Parameters dialog for TIFF, using SimplifiedParamsDialogs = False:
<IMG help_images\69.jpg>
!!}
property SimplifiedParamsDialogs: boolean read fSimplifiedParamsDialogs write fSimplifiedParamsDialogs default true;
{!!
<FS>TImageEnIO.OnDoPreviews
<FM>Declaration<FC>
property OnDoPreviews: <A TIEDoPreviewsEvent>;
<FM>Description<FN>
OnDoPreviews occurs just before the Format Parameters dialog (shown when clicking the "Advanced" button in ImageEn's Save dialog) shows.
You can disable the dialog box by setting Handled to true.
!!}
property OnDoPreviews: TIEDoPreviewsEvent read fOnDoPreviews write fOnDoPreviews;
property NativePixelFormat: boolean read GetNativePixelFormat write SetNativePixelFormat default false;
property ImageEnVersion: String read GetImageEnVersion write SetImageEnVersion stored false;
end;
// TImageEnIO
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure IEInitialize_imageenio;
procedure IEFinalize_imageenio;
var
iegPrintLogFileName: String;
iegPrintLogFile: textfile;
function IEFilenameToInternalFileType(const FileName: String; IncludeMultiOnly: Boolean = false): TIOFileType;
const
// Property strings for TIOPrintPreviewParams.GetProperty/SetProperty
PPP_MARGINTOP = 'MARGINTOP';
PPP_MARGINLEFT = 'MARGINLEFT';
PPP_MARGINRIGHT = 'MARGINRIGHT';
PPP_MARGINBOTTOM = 'MARGINBOTTOM';
PPP_POSITION = 'POSITION';
PPP_SIZE = 'SIZE';
PPP_WIDTH = 'WIDTH';
PPP_HEIGHT = 'HEIGHT';
PPP_GAMMA = 'GAMMA';
PPP_PRINTSELECTED = 'PRINTSELECTED';
PPP_PRINTTHUMBNAILS = 'PRINTTHUMBNAILS';
PPP_THUMBNAILCOLUMNS = 'THUMBNAILCOLUMNS';
PPP_THUMBNAILROWS = 'THUMBNAILROWS';
PPP_THUMBNAILSPACING = 'THUMBNAILSPACING';
PPP_THUMBNAILSTYLE = 'THUMBNAILSTYLE';
PPP_THUMBNAILSHOWTEXT = 'THUMBNAILSHOWTEXT';
PPP_DLGWIDTH = 'DLGWIDTH';
PPP_DLGHEIGHT = 'DLGHEIGHT';
PPP_Property_Count = 18;
PPP_Property_List : array[0 .. PPP_Property_Count - 1] of string =
( PPP_MARGINTOP ,
PPP_MARGINLEFT ,
PPP_MARGINRIGHT ,
PPP_MARGINBOTTOM ,
PPP_POSITION ,
PPP_SIZE ,
PPP_WIDTH ,
PPP_HEIGHT ,
PPP_GAMMA ,
PPP_PRINTTHUMBNAILS ,
PPP_THUMBNAILCOLUMNS ,
PPP_THUMBNAILROWS ,
PPP_THUMBNAILSPACING ,
PPP_THUMBNAILSTYLE ,
PPP_THUMBNAILSHOWTEXT ,
PPP_DLGWIDTH ,
PPP_DLGHEIGHT ,
PPP_PRINTSELECTED);
implementation
uses
{$ifdef IEUSEVCLZLIB}zlib, {$else}iezlib, {$endif}
{$IFDEF VIDEO_THUMBNAILS}
iexShellThumbnails,
{$ENDIF}
giffilter, PCXFilter, imscan, tiffilt, jpegfilt, BMPFilt, IOPreviews, pngfilt, pngfiltw, neurquant, ietgafil,
IEMIO, IEMView, IEOpenSaveDlg, ieprnform1, ieprnform2, ievect, imageenview, iesettings, iedicom, iej2000,
iepsd, iewic, giflzw, tiflzw, ielcms, ieraw, iemiscplugins, ievfw, iexLayers, iexSVG;
{$R-}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type
TIEIOMethodTypes = (ieLoadSaveFile, ieLoadSaveFileIF, ieLoadSaveStream, ieLoadSaveFileRetInt, ieLoadSaveFileRetBool, ieLoadSaveFileIFRetBool,
ieLoadSaveStreamRetInt, ieLoadSaveStreamRetBool, ieLoadSaveFileFFRetBool, ieLoadSaveStreamFF,
ieLoadSaveStreamFTRetBool, ieCaptureFromScreen, ieLoadSaveIndexRetBool, ieImportMetaFileRetBool, ieLoadFromURLRetBool,
ieAcquire);
TIEIOMethodType_LoadSaveFile = procedure(const FileName: WideString) of object;
TIEIOMethodType_LoadSaveFileIF = procedure(const FileName: WideString; FileType: TIOFileType) of object;
TIEIOMethodType_LoadSaveStream = procedure(Stream: TStream) of object;
TIEIOMethodType_LoadSaveFileRetInt = function(const FileName: WideString): integer of object;
TIEIOMethodType_LoadSaveFileRetBool = function(const FileName: WideString): Boolean of object;
TIEIOMethodType_LoadSaveFileIFRetBool = function(const FileName: WideString; FileType: TIOFileType): Boolean of object;
TIEIOMethodType_LoadSaveStreamRetInt = function(Stream: TStream): integer of object;
TIEIOMethodType_LoadSaveStreamRetBool = function(Stream: TStream): Boolean of object;
TIEIOMethodType_LoadSaveFileFFRetBool = function(const FileName: WideString; FileFormat: TIOFileType) : Boolean of object;
TIEIOMethodType_LoadSaveStreamFF = procedure(Stream: TStream; FileFormat: TIOFileType) of object;
TIEIOMethodType_LoadSaveStreamFTRetBool = function(Stream: TStream; FileFormat: TIOFileType) : Boolean of object;
TIEIOMethodType_CaptureFromScreen = procedure(Source: TIECSSource; MouseCursor: TCursor) of object;
TIEIOMethodType_LoadSaveIndexRetBool = function(Index: integer): Boolean of object;
TIEIOMethodType_ImportMetaFileRetBool = function(const FileName: WideString; Width, Height: integer; WithAlpha: boolean): Boolean of object;
TIEIOMethodType_LoadFromURLRetBool = function(const URL: WideString) : Boolean of object;
TIEIOMethodType_Acquire = function(bResetParams : Boolean = False) : boolean of object;
TIEIOThread = class(TThread)
private
fThreadList: TList;
fMethodType: TIEIOMethodTypes;
fMethod_LoadSaveFile: TIEIOMethodType_LoadSaveFile;
fMethod_LoadSaveFileIF: TIEIOMethodType_LoadSaveFileIF;
fMethod_LoadSaveStream: TIEIOMethodType_LoadSaveStream;
fMethod_LoadSaveFileRetInt: TIEIOMethodType_LoadSaveFileRetInt;
fMethod_LoadSaveFileRetBool : TIEIOMethodType_LoadSaveFileRetBool;
fMethod_LoadSaveFileIFRetBool : TIEIOMethodType_LoadSaveFileIFRetBool;
fMethod_LoadSaveStreamRetInt: TIEIOMethodType_LoadSaveStreamRetInt;
fMethod_LoadSaveStreamRetBool: TIEIOMethodType_LoadSaveStreamRetBool;
fMethod_LoadSaveFileFFRetBool: TIEIOMethodType_LoadSaveFileFFRetBool;
fMethod_LoadSaveStreamFF: TIEIOMethodType_LoadSaveStreamFF;
fMethod_LoadSaveStreamFTRetBool: TIEIOMethodType_LoadSaveStreamFTRetBool;
fMethod_CaptureFromScreen: TIEIOMethodType_CaptureFromScreen;
fMethod_LoadSaveIndexRetBool: TIEIOMethodType_LoadSaveIndexRetBool;
fMethod_ImportMetaFileRetBool: TIEIOMethodType_ImportMetaFileRetBool;
fMethod_LoadFromURLRetBool: TIEIOMethodType_LoadFromURLRetBool;
fMethod_Acquire: TIEIOMethodType_Acquire;
p_nf: WideString;
p_ImageFormat: TIOFileType;
p_stream: TStream;
p_fileformat: TIOFileType;
p_source: TIECSSource;
p_index: integer;
p_width, p_height: integer;
p_withalpha: boolean;
p_mouseCursor: TCursor;
p_URL: WideString;
p_ResetParams: Boolean;
fThreadID: dword;
fOwner: TImageEnIO;
procedure Init;
public
procedure Execute; override;
constructor CreateLoadSaveFile(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFile; const in_nf: WideString);
constructor CreateLoadSaveFileIF(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileIF; const in_nf: WideString; ImageFormat: TIOFileType);
constructor CreateLoadSaveStream(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStream; in_Stream: TStream);
constructor CreateLoadSaveFileRetInt(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileRetInt; const in_nf: WideString);
constructor CreateLoadSaveFileRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileRetBool; const in_nf: WideString);
constructor CreateLoadSaveFileIFRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileIFRetBool; const in_nf: WideString; ImageFormat: TIOFileType);
constructor CreateLoadSaveStreamRetInt(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamRetInt; in_Stream: TStream);
constructor CreateLoadSaveStreamRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamRetBool; in_Stream: TStream);
constructor CreateLoadSaveFileFFRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileFFRetBool; const in_nf: WideString; in_fileformat: TIOFileType);
constructor CreateLoadSaveStreamFF(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamFF; in_Stream: TStream; in_fileformat: TIOFileType);
constructor CreateLoadSaveStreamFTRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamFTRetBool; in_Stream: TStream; in_fileformat: TIOFileType);
constructor CreateCaptureFromScreen(owner: TImageEnIO; InMethod: TIEIOMethodType_CaptureFromScreen; in_source: TIECSSource; in_mouseCursor: TCursor);
constructor CreateLoadSaveIndexRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveIndexRetBool; in_index: integer);
constructor CreateImportMetaFileRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_ImportMetaFileRetBool; const in_nf: WideString; in_width, in_height: integer; in_withalpha: boolean);
constructor CreateAcquire(owner: TImageEnIO; InMethod: TIEIOMethodType_Acquire; bResetParams: Boolean);
// dummy is necessary to C++Builder in order to compile
constructor CreateLoadFromURLRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadFromURLRetBool; const in_URL: WideString; dummy: Double);
property ThreadID: dword read fThreadID;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnIO.Create
<FM>Declaration<FC>
constructor Create(Owner: TComponent);
<FM>Description<FN>
Creates a new instance of TImageEnIO. You can set Owner = nil to create an owner-less component.
!!}
constructor TImageEnIO.Create(Owner: TComponent);
begin
inherited Create(Owner);
IEGDIPLoadLibrary();
fIEBitmap := TIEBitmap.Create;
fIEBitmapCreated := true; // we create fIEBitmap
fAsyncThreadsCS := TCriticalSection.Create();
fImageEnViewBitmapChangeHandle := nil;
fOnIOPreview := nil;
fStreamHeaders := false;
fParams := TIOParams.Create( self );
{$IFDEF IEINCLUDEIEXACQUIRE}
fAcquireParams := TIEAcquireParams.Create(Self);
fTwainParams := TIETwainParams.Create(Self);
{$ENDIF}
{$IFDEF IEINCLUDEWPD}
fDCIMParams := TIEDcimAcquire.Create(Self);
{$ENDIF}
fBitmap := nil;
fImageEnView := nil;
fTImage := nil;
fBackground := clBlack;
fOnIntProgress := DoIntProgress;
fOnProgress := nil;
fOnFinishWork := nil;
fPreviewsParams := [];
fPreviewFont := TFont.Create;
fPreviewFontEnabled := False;
fAborting := false;
fDialogsMeasureUnit := ieduInches;
fAutoAdjustDPI := False;
fFilteredAdjustDPI := false;
fAVI_avf := nil;
fAVI_avs := nil;
fAVI_avs1 := nil;
fAVI_gf := nil;
{$ifdef IEINCLUDEDIRECTSHOW}
fOpenMediaFile := nil;
{$endif}
fAsyncThreads := TList.Create;
fAsyncThreadsFinishEvent := Windows.CreateEvent(nil, false, false, nil);
fAsyncMode := false;
fPrintingFilterOnSubsampling := rfFastLinear;
fgrec := nil;
fOnAcquireBitmap := nil;
fOnAcquireClose := nil;
SimplifiedParamsDialogs := true;
fOnDoPreviews := nil;
fChangeBackground := false;
fDefaultDitherMethod := ieThreshold;
fResetPrinter := true;
fPS_handle := nil;
fPS_stream := nil;
fPDF_handle := nil;
fPDF_stream := nil;
{$IFDEF IEINCLUDEIEXACQUIRE}
fWIA := nil;
{$ENDIF}
{$IFDEF IEINCLUDEDIRECTSHOW}
fDShow := nil;
{$ENDIF}
{$IFDEF IEINCLUDEMEDIAFOUNDATION}
fMediaFoundationSourceReader := nil;
{$ENDIF}
{$IFDEF IEINCLUDEPRINTDIALOGS}
fPrintPreviewParams := TIOPrintPreviewParams.Create;
{$ENDIF}
end;
{!!
<FS>TImageEnIO.CreateFromBitmap
<FM>Declaration<FC>
constructor CreateFromBitmap(Bitmap: <A TIEBitmap>);
constructor CreateFromBitmap(Bitmap: TBitmap);
<FM>Description<FN>
Creates a new instance of TImageEnIO, assigning the property <A TImageEnIO.AttachedIEBitmap> or <A TImageEnIO.AttachedBitmap>.
<FM>Example<FC>
with TImageEnIO.CreateFromBitmap(myBitmap) do
begin
DoPrintPreviewDialog( iedtDialog, '' )
Free;
end;
// If an area of the image is selected, print the selection, otherwise print the whole image
procedure TForm1.PrintImageClick(Sender: TObject);
var
bmp: TIEBitmap;
IO: TImageEnIO;
begin
if ImageEnView1.Selected = False then
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog, '' )
else
begin
bmp := TIEBitmap.Create;
IO := TImageEnIO.CreateFromBitmap( bmp );
try
ImageEnView1.CopySelectionToBitmap( bmp );
IO.DoPrintPreviewDialog( iedtDialog, '' );
finally
IO.Free;
bmp.Free;
end;
end;
end;
!!}
constructor TImageEnIO.CreateFromBitmap(Bitmap: TIEBitmap);
begin
Create(nil);
AttachedIEBitmap := Bitmap;
end;
constructor TImageEnIO.CreateFromBitmap(Bitmap: TBitmap);
begin
Create(nil);
AttachedBitmap := Bitmap;
end;
{!!
<FS>TImageEnIO.ImageEnVersion
<FM>Declaration<FC>
property ImageEnVersion: String;
<FM>Description<FN>
Returns the ImageEn version as a string.
!!}
function TImageEnIO.GetImageEnVersion: String;
begin
result := IEMAINVERSION;
end;
procedure TImageEnIO.SetImageEnVersion(Value: String);
begin
// this is a read-only property, but it must be displayed in object inspector
end;
procedure TImageEnIO.SetNativePixelFormat(value: Boolean);
begin
if GetParams <> nil then
GetParams.IsNativePixelFormat := value;
end;
// Sets modified to false for the attached fIEBitmap and imageenview
procedure TImageEnIO.ResetModified(AllLayers: Boolean = False);
begin
if assigned( fIEBitmap ) then
fIEBitmap.Modified := False;
if assigned( fImageEnView ) and ( fImageEnView is TImageEnView ) then
if AllLayers or ( TImageEnView( fImageEnView ).LayersCount = 1 ) then
TImageEnView( fImageEnView ).Modified := False;
end;
{!!
<FS>TImageEnIO.NativePixelFormat
<FM>Declaration<FC>
property NativePixelFormat: Boolean;
<FM>Description<FN>
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.
Setting NativePixelFormat to True disables the conversion and uses the image's native format.
Note: <A TImageEnView.LegacyBitmap> must be False to enable <FC>NativePixelFormat<FN>. Also, use of <FC>NativePixelFormat<FN> will prevent execution of some image processing operations.
<FM>Example<FC>
If you have a 16 bit gray scale TIFF and you want to work with 16 bit gray scale pixels, you must write this before loading the image:<FC>
ImageEnView1.LegacyBitmap := False; // Do not use Tbitmap
ImageEnView1.IO.NativePixelFormat := True; // Use the original pixel format
<FN>Now you can read the pixels using:<FC>
word = ImageEnView1.IEBitmap.Pixels_ie16g[x,y];
!!}
function TImageEnIO.GetNativePixelFormat: Boolean;
begin
if GetParams <> nil then
result := GetParams.IsNativePixelFormat
else
result := False;
end;
{!!
<FS>TImageEnIO.WaitThreads
<FM>Declaration<FC>
procedure WaitThreads(Aborts: Boolean = false);
<FM>Description<FN>
Call WaitThreads to wait until all threads complete. If <FC>Aborts<FN> is True, then all threads will be aborted.
<FM>Example<FC>
ImageEnIO.LoadFromFile('C:\input.jpg');
ImageEnIO.AsyncMode := True; // Enable multithreading
ImageEnIO.SaveToFile('D:\output1.jpg'); // Save in thread 1
ImageEnIO.SaveToFile('D:\output2.jpg'); // Save in thread 2
ImageEnIO.WaitThreads(false); // Wait until all saving threads terminate
!!}
procedure TImageEnIO.WaitThreads(Aborts: Boolean);
var
i: Integer;
begin
repeat
fAsyncThreadsCS.Enter();
if Aborts then
fAborting := true;
i := fAsyncThreads.Count;
fAsyncThreadsCS.Leave();
if i = 0 then
break;
Windows.WaitForSingleObject(fAsyncThreadsFinishEvent, INFINITE);
until false;
end;
procedure TImageEnIO.SuspendThreads; {$ifdef IEHASTTHREADSTART} deprecated; {$endif}
var
i: integer;
begin
fAsyncThreadsCS.Enter();
try
for i := 0 to fAsyncThreads.Count - 1 do
begin
TThread(fAsyncThreads[i]).Suspend;
while not TThread(fAsyncThreads[i]).Suspended do
sleep(0); // give up the remainder of my current time slice
end;
finally
fAsyncThreadsCS.Leave();
end;
end;
procedure TImageEnIO.SetAborting(Value: Boolean);
begin
fAborting := Value;
{$IFDEF IEINCLUDEIEXACQUIRE}
fAcquireParams.Aborting := Value;
{$ENDIF}
{$IFDEF IEINCLUDEWPD}
fDCIMParams.Aborting := Value;
{$ENDIF}
end;
procedure TImageEnIO.ResumeThreads; {$ifdef IEHASTTHREADSTART} deprecated; {$endif}
var
i: integer;
begin
fAsyncThreadsCS.Enter();
try
for i := 0 to fAsyncThreads.Count - 1 do
if TThread(fAsyncThreads[i]).Suspended then
TThread(fAsyncThreads[i]).Resume;
finally
fAsyncThreadsCS.Leave();
end;
end;
destructor TImageEnIO.Destroy;
begin
// wait threads
WaitThreads(false);
FreeAndNil(fAsyncThreads);
Windows.CloseHandle(fAsyncThreadsFinishEvent);
//
{$ifdef IEINCLUDEDIRECTSHOW}
CloseMediaFile;
{$endif}
CloseAVIFile; // works only if AVI is not closed
ClosePSFile;
{$ifdef IEINCLUDEPDFWRITING}
ClosePDFFile;
{$endif}
if assigned(fImageEnView) then
fImageEnView.RemoveBitmapChangeEvent(fImageEnViewBitmapChangeHandle);
FreeAndNil(fParams);
{$IFDEF IEINCLUDEIEXACQUIRE}
FreeAndNil(fAcquireParams);
FreeAndNil(fTwainParams);
{$ENDIF}
{$IFDEF IEINCLUDEWPD}
FreeAndNil(fDCIMParams);
{$ENDIF}
{$IFDEF IEINCLUDEPRINTDIALOGS}
FreeAndNil(fPrintPreviewParams);
{$ENDIF}
FreeAndNil(fPreviewFont);
if fIEBitmapCreated then
FreeAndNil(fIEBitmap);
{$IFDEF IEINCLUDEIEXACQUIRE}
if assigned(fWia) then
FreeAndNil(fWia);
{$ENDIF}
{$IFDEF IEINCLUDEDIRECTSHOW}
if assigned(fDShow) then
FreeAndNil(fDShow);
{$ENDIF}
{$IFDEF IEINCLUDEMEDIAFOUNDATION}
FreeAndNil(fMediaFoundationSourceReader);
{$ENDIF}
FreeAndNil(fAsyncThreadsCS);
IEGDIPUnLoadLibrary();
inherited;
end;
procedure TImageEnIO.RecreatedTImageEnViewHandle;
begin
{$ifdef IEINCLUDEDIRECTSHOW}
if assigned(fImageEnView) and assigned(fDShow) and (fDShow.NotifyWindow<>fImageEnView.Handle) then
fDShow.SetNotifyWindow(fImageEnView.Handle, IEM_NEWFRAME, IEM_EVENT);
{$endif}
{$ifdef IEINCLUDEMEDIAFOUNDATION}
if assigned(fImageEnView) and assigned(fMediaFoundationSourceReader) then
begin
fMediaFoundationSourceReader.ClearNotifyReceivers();
fMediaFoundationSourceReader.PushNotifyReceiver( TIEMediaFoundationReaderWindowNotifyReceiver.Create(fImageEnView.Handle, IEM_MEDIAFOUNDATION) );
end;
{$endif}
end;
procedure TImageEnIO.SyncGetHandle;
begin
if Assigned(fImageEnView) then
fImageEnView.Handle;
end;
{!!
<FS>TImageEnIO.Update
<FM>Declaration<FC>
procedure Update();
<FM>Description<FN>
If TImageEnIO is attached to a <A TImageEnView> (or inherited) object, Update will call the Update method of the relevant control.
If TImageEnIO is attached to a TBitmap object, Update sets its <FC>Modified<FN> property to True.
!!}
procedure TImageEnIO.Update();
begin
// remove alpha if attached to fBitmap
if assigned(fBitmap) then
fIEBitmap.RemoveAlphaChannel;
if assigned(fImageEnView) then
begin
with fImageEnView do
begin
if IsInsideAsyncThreads then
begin
if Parent <> nil then
begin
{$ifdef IEHASTTHREADSTATICSYNCHRONIZE}
if not HandleAllocated then
TThread.Synchronize(nil, SyncGetHandle);
{$endif}
PostMessage(handle, IEM_UPDATE, 0, 0);
end;
end
else
Update();
ImageChange;
end;
end
else
if assigned(fBitmap) then
fBitmap.modified := true;
end;
// Get actual background color
function TImageEnIO.GetReBackground: TColor;
begin
if assigned(fImageEnView) then
result := fImageEnView.Background
else
result := fBackground;
end;
{!!
<FS>TImageEnIO.Background
<FM>Declaration<FC>
property Background: TColor;
<FM>Description<FN>
The background color of the image (shown in unoccupied areas if the current image is smaller than the control size).
Note: When TImageEnIO is attached to <A TImageEnView>, the TImageEnIO.Background is equal to <A TImageEnView.Background>.
!!}
procedure TImageEnIO.SetReBackground(v: TColor);
begin
if assigned(fImageEnView) then
begin
{$IFDEF IEINCLUDEMULTIVIEW}
if not (fImageEnView is TImageEnMView) then
{$ENDIF}
if fChangeBackground then
fImageEnView.Background := v;
end
else
fBackground := v;
end;
function TImageEnIO.IsInsideAsyncThreads: boolean;
var
i: integer;
ch: THandle;
begin
result := false;
ch := GetCurrentThreadId;
try
fAsyncThreadsCS.Enter();
for i := 0 to fAsyncThreads.Count - 1 do
if TIEIOThread(fAsyncThreads.Items[i]).ThreadId = ch then
begin
result := true;
exit;
end;
finally
fAsyncThreadsCS.Leave();
end;
end;
// Raise exception if there is no bitmap available
procedure TImageEnIO.CheckHaveValidBitmap();
var
bHaveBitmap: Boolean;
begin
bHaveBitmap := assigned(fIEBitmap);
if assigned( fImageEnView ) and ( fImageEnView is TImageEnView ) and ( TImageEnView( fImageEnView ).fIEBitmapValid = False ) then
bHaveBitmap := False;
if bHaveBitmap = False then
raise EIEException.create( 'Active layer does not contain bitmap' );
end;
function TImageEnIO.MakeConsistentBitmap(allowedFormats: TIEPixelFormatSet): boolean;
begin
CheckHaveValidBitmap();
result := false;
if not assigned(fIEBitmap) then
exit;
if assigned(fBitmap) then
fIEBitmap.EncapsulateTBitmap(fBitmap, false); // synchronize fBitmap with fIEBitmap
result := fIEBitmap.CheckFormat(allowedFormats, true);
end;
{!!
<FS>TImageEnIO.SaveToFileGif
<FM>Declaration<FC>
procedure SaveToFileGif(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in GIF format (89a). The GIF will have a single image and it won't be marked as animated.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
// Save an interlaced, 64 color Gif.
ImageEnView1.IO.Params.GIF_Interlaced := True;
ImageEnView1.IO.Params.BitsPerSample := 6;
ImageEnView1.IO.Params.SamplesPerPixel := 1;
ImageEnView1.IO.SaveToFileGif('D:\image.gif');
!!}
procedure TImageEnIO.SaveToFileGIF(const FileName: WideString);
var
Progress: TProgressRec;
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileGIF, FileName);
exit;
end;
try
fAborting := true;
fs := nil;
try
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
WriteGIFStream(fs, fiebitmap, fParams, Progress);
fParams.FileName := FileName;
fParams.FileType := ioGIF;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.InsertToFileGif
<FM>Declaration<FC>
function InsertToFileGif(const FileName: WideString): integer;
<FM>Description<FN>
Inserts a frame into a GIF file at the position specified by <A TIOParams.GIF_ImageIndex> and makes it animated. The file must exist.
<FC>FileName<FN> is the file name including extension.
Returns the number of images inside the specified file.
<FM>Example<FC>
// Create an animated gif with images contained in ImageEn1 and ImageEn2 components:
ImageEnView1.IO.SaveToFileGif('D:\anim.gif');
ImageEnView2.IO.Params.GIF_ImageIndex := 1;
ImageEnView2.IO.InsertToFileGif('D:\anim.gif');
!!}
function TImageEnIO.InsertToFileGIF(const FileName: WideString): integer;
var
Progress: TProgressRec;
begin
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetInt(self, InsertToFileGIF, FileName);
result := -1;
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
result := 0;
if not MakeConsistentBitmap([]) then
exit;
if fParams.GIF_WinWidth < (fiebitmap.width + fParams.GIF_XPos) then
fParams.GIF_WinWidth := fiebitmap.width + fParams.GIF_XPos;
if fParams.GIF_WinHeight < (fiebitmap.height + fParams.GIF_ypos) then
fParams.GIF_WinHeight := fiebitmap.height + fParams.GIF_ypos;
result := _InsertGIFIm(FileName, fIEBitmap, fParams, Progress);
if not fAborting then
_GIFMakeAnimate(string(FileName), 0, fParams.GIF_WinWidth, fParams.GIF_WinHeight); // makes it animated
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.InsertToFileTIFF
<FM>Declaration<FC>
function InsertToFileTIFF(const FileName: WideString): integer;
<FM>Description<FN>
Insert a frame into a TIFF file at the position specified by <A TIOParams.ImageIndex>. The file must exist.
<FC>FileName<FN> is the file name including extension.
Returns the number of images inside the file.
<FM>Example<FC>
// Create a multi-image TIFF from images into two ImageEnViews
ImageEnView1.IO.SaveToFile('D:\multi.tif'); // create with a single image
ImageEnView2.IO.Params.ImageIndex := 1; // prepare to insert as second image
ImageEnView2.IO.InsertToFileTIFF('D:\multi.tif');
!!}
function TImageEnIO.InsertToFileTIFF(const FileName: WideString): integer;
var
Progress: TProgressRec;
fs: TIEWideFileStream;
begin
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetInt(self, InsertToFileTIFF, FileName);
result := -1;
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
result := 0;
if not MakeConsistentBitmap([]) then
exit;
fs := nil;
try
fs := TIEWideFileStream.Create(FileName, fmOpenReadWrite);
fAborting := false;
result := TIFFWriteStream(fs, true, fIEBitmap, fParams, Progress);
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.InsertToStreamTIFF
<FM>Declaration<FC>
function InsertToStreamTIFF(Stream: TStream): integer;
<FM>Description<FN>
Insert a frame in a TIFF stream at position specified by <A TIOParams.ImageIndex>. The stream position must be at the beginning.
Because ImageEn can only write Little-endian TIFF the input file cannot be Big-endian (see <A TIOParams.TIFF_ByteOrder>).
Returns the number of images inside the file.
<FM>Example<FC>
ImageEnView1.IO.Params.ImageIndex := 1; // prepare to insert as second image
ImageEnView1.IO.InsertToStreamTIFF(outstream);
!!}
function TImageEnIO.InsertToStreamTIFF(Stream: TStream): integer;
var
Progress: TProgressRec;
begin
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStreamRetInt(self, InsertToStreamTIFF, Stream);
result := -1;
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
result := 0;
if not MakeConsistentBitmap([]) then
exit;
fAborting := false;
Stream.Position := 0;
result := TIFFWriteStream(Stream, true, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.ReplaceFileTIFF
<FM>Declaration<FC>
function ReplaceFileTIFF(const FileName: WideString): Integer;
<FM>Description<FN>
Save the current image into the specified multi-page TIFF file, replacing the image at the index specified by <A TImageEnIO.Params>.<A TIOParams.TIFF_ImageIndex>.
Because ImageEn can only write Little-endian TIFF the input file cannot be Big-endian (see <A TIOParams.TIFF_ByteOrder>).
<FM>Examples<FC>
// We have a multipage tiff, named 'multipage.tif'.
// We want to change only the second page (index 1), making it negative.
ImageEnView1.IO.Params.TIFF_ImageIndex := 1; // select page
ImageEnView1.IO.LoadFromFile('D:\multipage.tif');
ImageEnView1.Proc.Negative;
ImageEnView1.IO.ReplaceFileTIFF('D:\multipage.tif');
// Update the file for the selected frame of a multi-page TIFF in a TImageEnMView
IO := TImageEnIO.Create(nil);
IO.Params.TIFF_ImageIndex := ImageEnMView1.SelectedImage; // select page
IO.IEBitmap.Assign( ImageEnMView1.IEBitmap );
IO.ReplaceFileTIFF( ImageEnMView1.MIO.LastFilename );
IO.Free;
!!}
// replace based on TIFF_ImageIndex
function TImageEnIO.ReplaceFileTIFF(const FileName: WideString): integer;
begin
DeleteTIFFIm(FileName, fParams.TIFF_ImageIndex);
result := InsertToFileTIFF(FileName);
end;
{!!
<FS>TImageEnIO.ReplaceFileGIF
<FM>Declaration<FC>
function ReplaceFileGIF(const FileName: WideString): Integer;
<FM>Description<FN>
Save the current image into the specified multi-page GIF file, replacing the image at the index specified by <A TImageEnIO.Params>.<A TIOParams.GIF_ImageIndex>.
<FM>Example<FC>
// We have a multipage GIF, named 'multipage.gif'.
// We want to change only the second page (index 1), making it negative.
ImageEnView1.IO.Params.GIF_ImageIndex := 1; // select page
ImageEnView1.IO.LoadFromFile('D:\multipage.gif');
ImageEnView1.Proc.Negative;
ImageEnView1.IO.ReplaceFileTIFF('D:\multipage.gif');
!!}
// replace based on GIF_ImageIndex
function TImageEnIO.ReplaceFileGIF(const FileName: WideString): integer;
begin
DeleteGIFIm(FileName, fParams.GIF_ImageIndex);
result := InsertToFileGIF(FileName);
end;
// Performs same function as IEExtToFileFormat but by checking each known extension rather than parsing IEGlobalSettings().FileFormats
// IncludeMultiOnly also checks for ioAVI
function IEFilenameToInternalFileType(const FileName: String; IncludeMultiOnly: Boolean = false): TIOFileType;
var
ex: string;
begin
Result := ioUnknown;
ex := string(IEExtractFileExtW(FileName));
if IEFileExtInExtensions( ex, '*.jpg;*.jpeg;*.jpe;*.jif') then
result := ioJPEG
{$IFDEF IEINCLUDEJPEG2000}
else
if IEFileExtInExtensions( ex, '*.jp2') then
result := ioJP2
else
if IEFileExtInExtensions( ex, '*.j2k;*.jpc;*.j2c') then
result := ioJ2K
{$ENDIF}
else
if IEFileExtInExtensions( ex, '*.pcx') then
result := ioPCX
else
if IEFileExtInExtensions( ex, '*.dcx') then
result := ioDCX
else
if IEFileExtInExtensions( ex, '*.gif') then
result := ioGIF
else
if IEFileExtInExtensions( ex, '*.tif;*.tiff;*.fax;*.g3f;*.g3n') then
result := ioTIFF
{$IFDEF IEINCLUDEPNG}
else
if IEFileExtInExtensions( ex, '*.png') then
result := ioPNG
{$ENDIF}
else
if IEFileExtInExtensions( ex, '*.bmp;*.dib;*.rle') then
result := ioBMP
else
if IEFileExtInExtensions( ex, '*.tga;*.targa;*.vda;*.icb;*.vst;*.win') then
result := ioTGA
else
if IEFileExtInExtensions( ex, '*.pxm;*.pbm;*.pgm;*.ppm') then
result := ioPXM
else
if IEFileExtInExtensions( ex, '*.ico') then
result := ioICO
else
if IEFileExtInExtensions( ex, '*.wbmp') then
result := ioWBMP
else
if IEFileExtInExtensions( ex, '*.ps;*.eps') then
result := ioPS
{$ifdef IEINCLUDEPDFWRITING}
else
if IEFileExtInExtensions( ex, '*.pdf') and ( IEFileFormatGetInfo( ioPDF ) <> nil ) then
result := ioPDF
{$endif}
{$ifdef IEINCLUDEPSD}
else
if IEFileExtInExtensions( ex, '*.psd;*.psb') then
result := ioPSD
{$endif}
{$ifdef IEINCLUDEWIC}
else
if IEFileExtInExtensions( ex, '*.hdp;*.wdp;*.jxr') then
result := ioHDP
{$endif}
{$ifdef IEINCLUDEDICOM}
else
if IEFileExtInExtensions( ex, '*.dcm;*.dic;*.dicom;*.v2') then
result := ioDICOM
{$endif}
else
if IEFileExtInExtensions( ex, '*.all') then
result := ioALL
else
if IEFileExtInExtensions( ex, '*.ien;*.imageen;*.lyr') then
result := ioIEN
else
if IEFileExtInExtensions( ex, '*.cur') then
result := ioCUR
else
if IEFileExtInExtensions( ex, '*.emf') then
result := ioEMF
else
if IEFileExtInExtensions( ex, '*.wmf') then
result := ioWMF
else
if IEFileExtInExtensions( ex, '*.iev') then
result := ioIEV
else
if IEFileExtInExtensions( ex, '*.svg') then
result := ioSVG
else
if IEFileExtInExtensions( ex, Camera_Raw_File_Extensions ) then
result := ioRAW
else
if IncludeMultiOnly and IEFileExtInExtensions( ex, '*.avi') then
Result := ioAVI
end;
{!!
<FS>TImageEnIO.SaveToFile
<FM>Declaration<FC>
procedure SaveToFile(const FileName: WideString; ImageFormat: TIOFileType = -1);
<FM>Description<FN>
Saves the current image to Jpeg, Jpeg2000, PNG, TIFF, BMP, WBMP, PS, PDF, PCX, DCX, TGA, PXM, ICO, HDP, GIF, DICOM and any other supported format.
<FC>FileName<FN> is the file name including extension.
If <FC>FImageFormat<FN> is -1, then SaveToFile detects the file format from the extension of the specified filename.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
ImageEnView1.IO.SaveToFile('D:\rome.jpg');
ImageEnView1.IO.SaveToFile('D:\florence.tif');
ImageEnView1.IO.SaveToFile('D:\venice.gif');
// Saves a 16 color bitmap
ImageEnView1.IO.Params.BitsPerSample := 4 ;
ImageEnView1.IO.Params.SamplesPerPixel := 1;
ImageEnView1.IO.SaveToFile('D:\Italy.bmp');
// Saves a jpeg into output.dat
ImageEnView1.IO.SaveToFile('D:\output.dat', ioJPEG);
!!}
procedure TImageEnIO.SaveToFile(const FileName: WideString; ImageFormat: TIOFileType = -1);
var
fpi: TIEFileFormatInfo;
fs: TIEWideFileStream;
Progress: TProgressRec;
saveFormat: TIOFileType;
begin
if FileName = '' then
exit;
saveFormat := ImageFormat;
if saveFormat <= ioUnknown then
saveFormat := IEFilenameToInternalFileType( FileName );
if not ( saveFormat in [ ioIEN, ioSVG ]) then
CheckHaveValidBitmap();
if saveFormat = ioJPEG then
SaveToFileJpeg(FileName)
{$IFDEF IEINCLUDEJPEG2000}
else
if saveFormat = ioJP2 then
SaveToFileJP2(FileName)
else
if saveFormat = ioJ2K then
SaveToFileJ2K(FileName)
{$ENDIF}
else
if saveFormat = ioPCX then
SaveToFilePCX(FileName)
else
if saveFormat = ioDCX then
SaveToFileDCX(FileName)
else
if saveFormat = ioGIF then
SaveToFileGIF(FileName)
else
if saveFormat = ioTIFF then
SaveToFileTIFF(FileName)
{$IFDEF IEINCLUDEPNG}
else
if saveFormat = ioPNG then
SaveToFilePNG(FileName)
{$ENDIF}
else
if saveFormat = ioBMP then
SaveToFileBMP(FileName)
else
if saveFormat = ioTGA then
SaveToFileTGA(FileName)
else
if saveFormat = ioPXM then
SaveToFilePXM(FileName)
else
if saveFormat = ioICO then
SaveToFileICO(FileName)
else
if saveFormat = ioWBMP then
SaveToFileWBMP(FileName)
else
if saveFormat = ioPS then
SaveToFilePS(FileName)
{$ifdef IEINCLUDEPDFWRITING}
else
if ( saveFormat = ioPDF ) or ( saveFormat = iomscWPPDF ) then
SaveToFilePDF(FileName)
{$endif}
{$ifdef IEINCLUDEPSD}
else
if saveFormat = ioPSD then
SaveToFilePSD(FileName)
{$endif}
{$ifdef IEINCLUDEWIC}
else
if saveFormat = ioHDP then
SaveToFileHDP(FileName)
{$endif}
{$ifdef IEINCLUDEDICOM}
else
if saveFormat = ioDICOM then
SaveToFileDICOM(FileName)
{$endif}
else
if saveFormat = ioIEN then
SaveToFileIEN(FileName)
else
if (saveFormat = ioALL) and (fImageEnView <> nil) then
(fImageEnView as TImageEnVect).SaveToFileAll(FileName)
else
if (saveFormat = ioIEV) and (fImageEnView <> nil) then
(fImageEnView as TImageEnVect).SaveToFileIEV(FileName)
else
if saveFormat = ioSVG then
SaveToFileSVG(FileName)
else
begin
// try registered file formats
if ImageFormat > -1 then
fpi := IEFileFormatGetInfo(ImageFormat)
else
fpi := IEFileFormatGetInfo2( IEExtractFileExtS( FileName ));
if assigned(fpi) and assigned(fpi.WriteFunction) then
with fpi do
begin
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileIF(self, SaveToFile, FileName, ImageFormat);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
fParams.FileName := FileName;
fParams.FileType := FileType;
try
WriteFunction(fs, fIEBitmap, fParams, Progress);
finally
FreeAndNil(fs);
end;
fParams.FileName := FileName;
fParams.FileType := fpi.FileType;
finally
DoFinishWork;
end;
end
else
fAborting := True;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamGif
<FM>Declaration<FC>
procedure SaveToStreamGif(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in GIF format.
If <A TImageEnIO.StreamHeaders> property is true, then a special header is added as required for multi-image streams.
<FM>Example<FC>
// Saves images in ImageEnView1 and ImageEnView2 to the file Images.dat
// Note: images.dat isn't loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('C:\images.dat', fmCreate);
ImageEnView1.IO.StreamHeaders := True;
ImageEnView1.IO.SaveToStreamGIF(fs);
ImageEnView2.IO.StreamHeaders := True;
ImageEnView2.IO.SaveToStreamGIF(fs);
fs.free;
End;
// Saves a single image to image.gif
// image.gif is loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('image.gif');
ImageEnView1.IO.StreamHeaders := False;
ImageEnView1.IO.SaveToFileGIF(fs);
End;
!!}
procedure TImageEnIO.SaveToStreamGIF(Stream: TStream);
var
Progress: TProgressRec;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamGIF, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
WriteGIFStream(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnIO.Acquire
<FM>Declaration<FC>
function Acquire(bResetParams : Boolean = False) : boolean;
<FM>Description<FN>
Perform a single image acquisition from the <A TImageEnIO.SelectedAcquireSource>, which may be a camera card, Twain or WIA device. <A TImageEnIO.SelectedAcquireSource> is set when the user chooses a source if you have called <A TImageEnIO.SelectAcquireSource> or manually set a source using <A TImageEnIO.SetAcquireSource>.
If bResetParams is True then <A TIOParams.SetDefaultParams> is called before Acquire to reset the <L TIOParams>IO parameters</L> (if you have already loaded an image from file).
Result is true if there was a successful acquisition.
Note: For acquisition of multiple images use <L TImageEnMIO.Acquire>TImageEnMIO.Acquire</L>.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\AllAcquire\AllAcquire.dpr </C> </R>
</TABLE>
<FM>Examples<FC>
// Prompt the user to choose a scanner source and then acquire
if ImageEnView1.IO.SelectAcquireSource([ieaTwain, ieaWIA, ieaDCIM]) then
ImageEnView1.IO.Acquire;
// Capture from the default WIA device
if ImageEnView1.IO.SetSource(ieaWIA, Default_Device) then
ImageEnView1.IO.Acquire;
// Select the second Twain device and capture
if ImageEnView1.IO.SetSource(ieaTwain, 1) then
ImageEnView1.IO.Acquire;
// Capture from the Twain device named, CanoScan FB620
if ImageEnView1.IO.SetSource(ieaTwain, 'CanoScan FB620') then
ImageEnView1.IO.Acquire;
// Retrieve from the camera card listed as H:\ drive
if ImageEnView1.IO.SetSource(ieaDCIM, 'H') then
ImageEnView1.IO.Acquire;
// Capture without a dialog
ImageEnView1.IO.AcquireParams.VisibleDialog := False;
if ImageEnView1.IO.Acquire then
ImageEnView1.IO.SaveToFile('D:\newimage.jpg'); // save scanned image
!!}
function TImageEnIO.Acquire(bResetParams : Boolean) : boolean;
var
bHandled: Boolean;
begin
// calling Acquire after TwainAcquireOpen!!!!
if assigned(fgrec) then
begin
result := true; // there is already a scanner dialog open
exit;
end;
//
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateAcquire(self, Acquire, bResetParams);
result := true;
exit;
end;
try
fAborting := false;
result := false;
if not MakeConsistentBitmap([]) then
exit;
if bResetParams then
Params.SetDefaultParams;
Result := fAcquireParams.Acquire(fIEBitmap, Params, fOnProgress, NativePixelFormat);
if Result then
DoAcquireBitmap(fIEBitmap, Params.DpiX, Params.DpiY, bHandled); // Note: bHandled is not used by this Acquire method
if Result and (fAcquireParams.SelectedSourceApi = ieaTwain) then
begin
if fAutoAdjustDPI then
AdjustDPI;
end;
Update();
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnIO.SelectAcquireSource
<FM>Declaration<FC>
function SelectAcquireSource(Apis: <A TIEAcquireApis> = [ieaTwain, ieaWIA]) : boolean;
<FM>Description<FN>
Prompts the user with a dialog to select a Twain, WIA or DCIM device. Use Apis 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 press "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]) then
begin
ImageEn1.IO.Acquire;
ImageEn1.IO.SaveToFile('D:\MyImage.jpg');
end;
!!}
function TImageEnIO.SelectAcquireSource(Apis : TIEAcquireApis = [ieaTwain, ieaWIA]): boolean;
// NPC: 16/11/11
begin
Result := fAcquireParams.SelectSource(Apis);
end;
{!!
<FS>TImageEnIO.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 TImageEnIO.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>Examples<FC>
// Acquire from the default Twain device
if ImageEnView1.IO.SetAcquireSource(ieaTwain, Default_Device) then
ImageEnView1.IO.Acquire;
// Select a Twain scanner by name
ImageEnView1.IO.SetAcquireSource(ieaTwain, 'CanoScan FB620');
// Select the second WIA device
ImageEnView1.IO.SetAcquireSource(ieaWIA, 1);
// Acquire from the camera card on H drive
if ImageEnView1.IO.SetAcquireSource(ieaDCIM, 'H') then
ImageEnView1.IO.Acquire;
// Read and restore a source
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
...
// Read the selected device
sDevice := AcquireSourceToStr(ImageEnView1.IO.SelectedAcquireSource);
...
end;
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
...
// Restore the device selection
ADevice := StrToAcquireSource(sDevice);
ImageEnView1.IO.SetAcquireSource(ADevice.Api, ADevice.Location);
...
end;
<FM>See Also<FN>
- <A TImageEnIO.Acquire>
- <A TImageEnIO.SelectedAcquireSource>
!!}
function TImageEnIO.SetAcquireSource(Api: TIEAcquireApi; Location : Variant) : boolean;
// NPC: 16/11/11
begin
Result := fAcquireParams.SetSource(Api, Location);
end;
{!!
<FS>TImageEnIO.SelectedAcquireSource
<FM>Declaration<FC>
property SelectedAcquireSource : <A TIEAcquireSource>; (Read only)
<FM>Description<FN>
Returns the acquisition source that is currently active due to selection by the user with <A TImageEnIO.SelectAcquireSource> or programatically using <A TImageEnIO.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>Examples<FC>
// Display the selected source
if ImageEnView1.IO.SelectedAcquireSource.Api = ieaNone then
ShowMessage('No device is selected')
else
ShowMessage('The selected device is ' + ImageEnView1.IO.SelectedAcquireSource.Name);
// Read and restore the selected source
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
...
// Read the selected device
sDevice := AcquireSourceToStr(ImageEnView1.IO.SelectedAcquireSource);
...
end;
var
sDevice : string;
ADevice : TIEAcquireSource;
begin
...
// Restore the device selection
ADevice := StrToAcquireSource(sDevice);
ImageEnView1.IO.SetAcquireSource(ADevice.Api, ADevice.Location);
...
end;
<FM>See Also<FN>
- <A TImageEnIO.SelectAcquireSource>
- <A TImageEnIO.SetAcquireSource>
!!}
function TImageEnIO.GetSelectedAcquireSource : TIEAcquireSource;
// NPC: 16/11/11
begin
Result := fAcquireParams.SelectedSource;
end;
procedure TImageEnIO.InitializeAcquireSource(bIncludeWIA : Boolean);
// NPC: 16/11/11
begin
AcquireParams.AttachedTwainParams := fTwainParams;
{$IFDEF IEINCLUDEWPD}
AcquireParams.AttachedDCIMParams := fDcimParams;
{$ENDIF}
if bIncludeWIA then
AcquireParams.AttachedWIAParams := WIAParams;
end;
{$ENDIF}
function TImageEnIO.SyncLoadFromStreamGIF(Stream: TStream): integer;
var
p1: int64;
bmp, merged, prev: TIEBitmap;
numi, reqidx: integer;
Progress, Progress2: TProgressRec;
im: integer;
tempAlphaChannel: TIEMask;
dummy2, dummy3: pinteger;
act: TIEGIFAction;
backx, backy, backw, backh: integer;
dx, dy: integer;
OriginalPixelFormat: TIEPixelFormat;
begin
result := 0;
bmp := nil;
merged := nil;
prev := nil;
try
fAborting := False;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
if fParams.GIF_RAWLoad then
begin
tempAlphaChannel := nil;
ReadGIFStream(Stream, fIEBitmap, numi, fParams, Progress, False, tempAlphaChannel, false);
CheckDPI;
if assigned(tempAlphaChannel) then
begin
fIEBitmap.AlphaChannel.CopyFromTIEMask(tempAlphaChannel);
FreeAndNil(tempAlphaChannel);
end;
if assigned(fImageEnView) and (fImageEnView is TImageEnView) then
begin
with (fImageEnView as TImageEnView).CurrentLayer do
begin
PosX := fParams.GIF_XPos;
PosY := fParams.GIF_YPos;
end;
end;
end
else
begin
p1 := Stream.Position;
im := 0;
merged := TIEBitmap.Create();
merged.Location := ieMemory;
act := ioGIF_None;
backw := 0;
backh := 0;
backx := 0;
backy := 0;
reqidx := fParams.GIF_ImageIndex;
if reqidx > 0 then
Progress2 := NullProgressRec( fAborting, False )
else
Progress2 := Progress;
repeat
bmp := TIEBitmap.Create();
Stream.position := p1;
fParams.GIF_ImageIndex := im;
tempAlphaChannel := nil;
ReadGIFStream(Stream, bmp, numi, fParams, Progress2, False, tempAlphaChannel, false);
OriginalPixelFormat := bmp.PixelFormat;
CheckDPI;
dx := imax(fParams.GIF_WinWidth, bmp.Width);
dy := imax(fParams.GIF_WinHeight, bmp.Height);
if assigned(tempAlphaChannel) then
begin
bmp.AlphaChannel.CopyFromTIEMask(tempAlphaChannel);
FreeAndNil(tempAlphaChannel);
end;
if numi > 1 then
begin
if fParams.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(fParams.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, ie24RGB);
merged.Fill(TRGB2TColor(fParams.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(fparams.GIF_Background), 255, iehLeft, ievTop);
dummy2 := nil;
dummy3 := nil;
bmp.RenderToTIEBitmap(merged, dummy2, dummy3, nil, fParams.GIF_XPos, fParams.GIF_YPos, bmp.Width, bmp.Height, 0, 0, bmp.Width, bmp.Height, true, false, 255, rfNone, true, ielNormal);
bmp.MergeAlphaRectTo(merged, 0, 0, fParams.GIF_XPos, fParams.GIF_YPos, bmp.Width, bmp.Height);
merged.AlphaChannel.Full := false;
backw := bmp.Width;
backh := bmp.Height;
backx := fParams.GIF_XPos;
backy := fParams.GIF_YPos;
FreeAndNil(bmp);
bmp := merged;
act := fParams.GIF_Action; // act refers to the action of next image
fParams.GIF_Action := ioGIF_DrawBackground;
fParams.GIF_XPos := 0;
fParams.GIF_YPos := 0;
end;
if fAborting then
begin
if bmp <> merged then
FreeAndNil(bmp);
break;
end;
if numi > 0 then
begin
Progress.per1 := 100 / numi;
fIEBitmap.Assign(bmp);
fIEBitmap.PixelFormat := originalPixelFormat;
end;
if bmp <> merged then
FreeAndNil(bmp)
else
bmp := nil;
with Progress do
if assigned(fOnProgress) then
fOnProgress(Sender, trunc(per1 * im));
if fAborting then
break;
inc(im);
until (im >= numi) or (im - 1 = reqidx);
if bmp = merged then
bmp := nil;
FreeAndNil(merged);
fParams.GIF_ImageIndex := reqidx;
end;
result := numi;
if fAutoAdjustDPI then
AdjustDPI;
if fParams.GIF_FlagTranspColor then
Background := TRGB2TCOLOR(fParams.GIF_TranspColor)
else
Background := TRGB2TCOLOR(fParams.GIF_Background);
fParams.FileType := ioGIF;
fParams.FileName := '';
Update();
ResetModified();
finally
prev.Free();
bmp.Free();
merged.Free();
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileGIF
<FM>Declaration<FC>
function LoadFromFileGIF(const FileName: WideString): integer;
<FM>Description<FN>
Loads an image from a GIF file (87a, 89a and animated GIF).
<FC>FileName<FN> is the file name including extension.
Returns the number of images contained in GIF file (if this is an animated GIF) or -1 if an error was encountered while loading, such as the file not being GIF format (<A TImageEnIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: If <A TImageEnIO.AsyncMode>=True the result will always be -1
<FM>Example<FC>
// Loads the third frame of an animated gif
ImageEnView1.IO.Params.GIF_ImageIndex := 2;
ImageEnView1.IO.LoadFromFileGIF('D:\anim.gif');
!!}
// return remaining images
function TImageEnIO.LoadFromFileGIF(const FileName: WideString): integer;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetInt(self, LoadFromFileGIF, FileName);
result := -1;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
try
result := SyncLoadFromStreamGIF(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamGIF
<FM>Declaration<FC>
function LoadFromStreamGIF(Stream: TStream): integer;
<FM>Description<FN>
Loads an image from a stream containing a GIF file.
Returns the number of images contained in the stream (if this is an animated stream) or -1 if an error was encountered while loading, such as the file not being GIF format (<A TImageEnIO.Aborting> will be true). File access errors will raise an exception. If <A TImageEnIO.AsyncMode>=True the result will always be -1.
Note: If <A TImageEnIO.StreamHeaders> property is True, the stream must have a special header (saved using <A TImageEnIO.SaveToStreamGIF>).
<FM>Example<FC>
// loads a GIF file with LoadfFromStreamGIF
var
fs: TFileStream;
Begin
fs := TFileStream.Create('C:\myfile.gif', fmOpenRead);
ImageEnView1.IO.LoadFromStreamGIF(fs);
fs.free;
End;
!!}
// returns remaining images
function TImageEnIO.LoadFromStreamGIF(Stream: TStream): integer;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetInt(self, LoadFromStreamGIF, Stream);
result := -1;
end
else
begin
result := SyncLoadFromStreamGIF(Stream);
if fAborting then
Result := -1;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileDCX
<FM>Declaration<FC>
function LoadFromFileDCX(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a DCX file.
<FC>FileName<FN> is the file name including extension. Result will be false if the file is not a DCX format (and <A TImageEnIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: You can set the page to load using <A TImageEnIO.Params>.<A TIOParams.DCX_ImageIndex> property.
<FM>Example<FC>
// I want the second page of 'input.dat' (which is a DCX file)
ImageEnView1.IO.Params.DCX_ImageIndex := 1;
ImageEnView1.IO.LoadFromFileDCX('C:\input.dat');
!!}
function TImageEnIO.LoadFromFileDCX(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileDCX, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamDCX(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamDCX
<FM>Declaration<FC>
function LoadFromStreamDCX(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a DCX file. The result will be false if an error is encountered, e.g. the file in the stream is not DCX format (<A TImageEnIO.Aborting> will be true).
Note: You can set the page to load using <A TImageEnIO.Params>.<A TIOParams.DCX_ImageIndex> property.
!!}
function TImageEnIO.LoadFromStreamDCX(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamDCX, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamDCX(Stream);
end;
end;
function TImageEnIO.SyncLoadFromStreamDCX(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
IEDCXReadStream(Stream, fIEBitmap, fParams, Progress, false);
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioDCX;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
function TImageEnIO.SyncLoadFromStreamPCX(Stream: TStream; streamhead: boolean): Boolean;
var
SHead: PCXSHead;
lp1: int64;
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
lp1 := 0;
if streamhead then
begin
// load header
lp1 := Stream.Position;
Stream.Read(SHead, sizeof(PCXSHead));
if IECopy(SHead.id, 1, 3) <> 'PCX' then
begin
fAborting := true;
exit;
end;
if SHead.id <> 'PCX2' then
begin
Stream.Position := lp1 + 4;
SHead.dim := Stream.Size;
end;
end
else
SHead.dim := Stream.Size;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
fIEBitmap.RemoveAlphaChannel;
ReadPcxStream(Stream, fIEBitmap, fParams, SHead.dim, Progress, false);
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioPCX;
Update();
ResetModified();
if streamhead and (SHead.id = 'PCX2') then
Stream.Position := lp1 + sizeof(SHead) + SHead.dim; // posiziona alla fine del blocco PCX
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamPCX
<FM>Declaration<FC>
function LoadFromStreamPCX(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a PCX file. The result will be false if an error is encountered, e.g. the file in the stream is not PCX format (<A TImageEnIO.Aborting> will be true).
Note: If <A TImageEnIO.StreamHeaders> property is True, the stream must have a special header (saved using <A TImageEnIO.SaveToStreamPCX>).
<FM>Example<FC>
// loads a PCX file with LoadfFromStreamPCX
var
fs: TFileStream;
Begin
fs := TFileStream.Create('myfile.pcx', fmOpenRead);
if ImageEnView1.IO.LoadFromStreamPCX(fs) = False then
ShowMessage('Not a PCX file!');
fs.free;
End;
!!}
function TImageEnIO.LoadFromStreamPCX(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamPCX, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamPCX(Stream, fStreamHeaders);
end;
end;
{!!
<FS>TImageEnIO.LoadFromFilePCX
<FM>Declaration<FC>
function LoadFromFilePCX(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a PCX file. Result will be false if the file is not PCX format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FC>FileName<FN> is the file name including extension.
<FM>Example<FC>
ImageEnView1.IO.LoadFromFilePCX('C:\alfa.pcx');
!!}
function TImageEnIO.LoadFromFilePCX(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFilePCX, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamPCX(fs, false);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
function TImageEnIO.SyncLoadFromStreamTIFF(Stream: TStream; streamhead: boolean): integer;
var
SHead: TIFFSHead;
Progress: TProgressRec;
p0: int64;
tmpAlphaChannel: TIEMask;
BufStream: TIEBufferedReadStream;
begin
BufStream := TIEBufferedReadStream.Create(Stream, 8192, IEGlobalSettings().UseRelativeStreams);
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
try
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
p0 := 0;
if streamhead then
begin
BufStream.read(SHead, sizeof(SHead));
p0 := BufStream.Position;
if SHead.id <> 'TIFF' then
begin
fAborting := true;
result := 0;
exit;
end;
end;
fIEBitmap.RemoveAlphaChannel;
tmpAlphaChannel := nil;
TIFFReadStream(fIEBitmap, BufStream, result, fParams, Progress, false, tmpAlphaChannel, not streamhead, false, false, false);
CheckDPI;
if assigned(tmpAlphaChannel) then
begin
fIEBitmap.AlphaChannel.CopyFromTIEMask(tmpAlphaChannel);
FreeAndNil(tmpAlphaChannel);
end;
if fAutoAdjustDPI then
AdjustDPI;
if streamhead then
BufStream.Position := p0 + SHead.dim;
fParams.FileName := '';
fParams.FileType := ioTIFF;
Update();
ResetModified();
finally
BufStream.Free;
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamTIFF
<FM>Declaration<FC>
function LoadFromStreamTIFF(Stream: TStream): integer;
<FM>Description<FN>
Loads an image from a stream containing a TIFF file (rev. 6.0, Packbits, LZW, CCITT G.3 and G.4).
Returns the number of images contained in the stream or -1 if an error was encountered while loading, such as the file not being TIFF format (<A TImageEnIO.Aborting> will be true). Result will always be -1 if <A TImageEnIO.AsyncMode>=True.
Note: If <A TImageEnIO.StreamHeaders> property is True, the stream must have a special header (saved using <A TImageEnIO.SaveToStreamTIFF>).
<FM>Example<FC>
// loads a TIFF file with LoadfFromStreamTIFF
var
fs: TFileStream;
Begin
fs := TFileStream.Create('C:\myfile.tif', fmOpenRead);
ImageEnView1.IO.LoadFromStreamTIFF(fs);
fs.free;
End;
!!}
function TImageEnIO.LoadFromStreamTIFF(Stream: TStream): integer;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetInt(self, LoadFromStreamTIFF, Stream);
result := -1;
end
else
begin
result := SyncLoadFromStreamTIFF(Stream, fStreamHeaders);
if fAborting then
Result := -1;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileTIFF
<FM>Declaration<FC>
function LoadFromFileTIFF(const FileName: WideString): integer:
<FM>Description<FN>
Loads an image from a TIFF file (rev. 6.0, Packbits, LZW, CCITT G.3 and G.4).
<FC>FileName<FN> is the file name including extension.
Returns the number of images contained in TIFF file. Result will be -1 if an error was encountered while loading, such as the file not being TIFF format (<A TImageEnIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
Note: If <A TImageEnIO.AsyncMode> = True then the result will always be -1.
<FM>Example<FC>
// Load the second image in the MyImage.tif file
ImageEnView1.IO.Params.TIFF_ImageIndex := 1;
ImageEnView1.IO.LoadFromFileTIFF('D:\MyImage.tif');
!!}
function TImageEnIO.LoadFromFileTIFF(const FileName: WideString): integer;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetInt(self, LoadFromFileTIFF, FileName);
result := -1;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
result := SyncLoadFromStreamTIFF(fs, false);
if fAborting then
Result := -1;
finally
FreeAndNil(fs);
end;
fParams.FileName := FileName;
end;
function TImageEnIO.LoadVectStream(Stream: TStream; ft: TIOFileType): Boolean;
var
r: TRect;
tempIE: TImageEnVect;
begin
CheckHaveValidBitmap();
Result := False;
case ft of
ioIEV:
begin
if assigned(fImageEnView) and (fImageEnView is TImageEnVect) then
with (fImageEnView as TImageEnVect) do
begin
Result := LoadFromStreamIEV( Stream );
r := ObjectsExtents;
Proc.ImageResize(r.Right, r.Bottom);
Proc.Fill(CreateRGB(255, 255, 255));
AlphaChannel.Fill(0);
end
else
begin
// TImageEnView not associated, renderize image
tempIE := TImageEnVect.Create(nil);
try
tempIE.LegacyBitmap := False;
Result := tempIE.LoadFromStreamIEV( Stream );
r := TempIE.ObjectsExtents;
tempIE.Proc.ImageResize(r.Right, r.Bottom);
tempIE.Proc.Fill(CreateRGB(255, 255, 255));
tempIE.CopyObjectsToBack();
IEBitmap.Assign( tempIE.IEBitmap );
finally
tempIE.Free;
DoFinishWork;
end;
end;
end;
ioALL:
begin
if assigned(fImageEnView) and (fImageEnView is TImageEnVect) then
Result := (fImageEnView as TImageEnVect).LoadFromStreamALL( Stream )
else
begin
// TImageEnView not associated, renderize image
tempIE := TImageEnVect.Create(nil);
try
tempIE.LegacyBitmap := False;
Result := tempIE.LoadFromStreamALL( Stream );
tempIE.LayersMergeAll;
tempIE.CopyObjectsToBack();
IEBitmap.Assign( tempIE.IEBitmap );
finally
tempIE.Free;
DoFinishWork;
end;
end;
end;
end;
Params.FileType := ft;
end;
function TImageEnIO.LoadVectFile(const fileName: WideString; ft: TIOFileType): Boolean;
var
fs: TIEWideFileStream;
begin
Result := False;
if not ft in [ ioIEV, ioALL ] then
exit;
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
LoadVectStream( fs, ft );
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
Params.FileType := ft;
end;
{!!
<FS>TImageEnIO.LoadFromFile
<FM>Declaration<FC>
function LoadFromFile(const FileName: WideString; bCheckUnknown: Boolean = True): Boolean; overload;
function LoadFromFile(const FileName: WideString; FileFormat: <A TIOFileType>): Boolean; overload;
<FM>Description<FN>
Loads an image from the specified file. It recognizes the image format from the filename extension (if <FC>ImageFormat<FN> is not specified).
The source can be also an URL if it has the form 'http://'.
<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 (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
Notes:
- By default, this routine will fail for files with an invalid extension (e.g. a GIF file named MyImage.jpg) or unknown extension. To avoid this you can use the <FC>bCheckUnknown<FN> overload or <A TImageEnIO.LoadFromFileAuto>
- Can load IEV (<A TImageEnVect> objects) and IEN+IEV formats when <A TImageEnIO.AttachedImageEn> is TImageEnView or TImageEnVect.
<FM>Example<FC>
// Load the second image in the MyImage.tif file
ImageEnView1.IO.Params.TIFF_ImageIndex := 1;
ImageEnView1.IO.LoadFromFile('D:\MyImage.tif');
// Load a file even if this file extension is incorrect
ImageEnView1.IO.LoadFromFile(sFilename, True);
<FM>See Also<FN>
- <A TImageEnIO.LoadFromFileAuto>
!!}
function TImageEnIO.LoadFromFile(const FileName: WideString; FileFormat: TIOFileType): Boolean;
var
ext: string;
fpi: TIEFileFormatInfo;
fs: TIEWideFileStream;
Progress: TProgressRec;
begin
Result := False;
if not assigned(fIEBitmap) then
exit;
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;
if FileFormat <> ioIEN then
CheckHaveValidBitmap();
if FileFormat = ioAVI then
begin
OpenAVIFile(FileName);
if fAborting then
begin
DoFinishWork;
exit;
end;
LoadFromAVI(fParams.ImageIndex);
CloseAVIFile;
Params.Filename := FileName;
Params.FileType := ioAVI;
Result := True;
exit;
end;
ext := string(IEExtractFileExtW(FileName));
fpi := IEFileFormatGetInfo( FileFormat );
{$ifdef IEINCLUDEDIRECTSHOW}
// IEFileFormatGetInfo does not include video files so check if it is one
if (fpi = nil) and IEFileExtInExtensions(ext, Supported_MPEG_File_Extensions + Supported_WMV_File_Extensions) then
begin
OpenMediaFile(FileName);
if fAborting then
Exit;
LoadFromMediaFile(fParams.ImageIndex);
CloseMediaFile;
Params.Filename := FileName;
if Lowercase(ext) = '.wmv' then
Params.FileType := ioWMV
else
Params.FileType := ioMPEG;
Result := True;
Exit;
end;
{$endif}
if fpi = nil then
begin
fAborting := True;
DoFinishWork;
exit;
end;
if fpi.InternalFormat then
case fpi.FileType of
ioJPEG : begin Result := LoadFromFileJpeg(FileName); exit; end;
{$IFDEF IEINCLUDEJPEG2000}
ioJP2 : begin Result := LoadFromFileJP2(FileName); exit; end;
ioJ2K : begin Result := LoadFromFileJ2K(FileName); exit; end;
{$ENDIF}
{$IFDEF IEINCLUDEPNG}
ioPNG : begin Result := LoadFromFilePNG(FileName); exit; end;
{$ENDIF}
{$ifdef IEINCLUDEDICOM}
ioDICOM : begin Result := LoadFromFileDICOM(FileName); exit; end;
{$endif}
ioTIFF : begin
LoadFromFileTIFF(FileName);
Result := Not fAborting;
exit;
end;
ioPCX : begin Result := LoadFromFilePCX(FileName); exit; end;
ioDCX : begin Result := LoadFromFileDCX(FileName); exit; end;
ioGIF : begin
LoadFromFileGIF(FileName);
Result := Not fAborting;
exit;
end;
ioWMF,
ioEMF : begin Result := ImportMetaFile(FileName, -1, -1, true); exit; end;
ioBMP : begin Result := LoadFromFileBMP(FileName); exit; end;
ioCUR : begin Result := LoadFromFileCUR(FileName); exit; end;
ioICO : begin Result := LoadFromFileICO(FileName); exit; end;
ioTGA : begin Result := LoadFromFileTGA(FileName); exit; end;
ioPXM : begin Result := LoadFromFilePXM(FileName); exit; end;
ioWBMP : begin Result := LoadFromFileWBMP(FileName); exit; end;
{$ifdef IEINCLUDERAWFORMATS}
ioRAW : begin Result := LoadFromFileRAW(FileName); exit; end;
{$endif}
{$ifdef IEINCLUDEPSD}
ioPSD : begin Result := LoadFromFilePSD(FileName); exit; end;
{$endif}
{$ifdef IEINCLUDEWIC}
ioHDP : begin Result := LoadFromFileHDP(FileName); exit; end;
{$endif}
ioIEN : begin Result := LoadFromFileIEN(FileName); exit; end;
ioIEV, ioALL:
begin Result := LoadVectFile(FileName, fpi.FileType); exit; end;
end;
// try external formats
fAborting := true; // So that fAborting is True if the file is not found
fParams.ResetInfo;
Params.Filename := '';
Params.FileType := ioUnknown;
// try registered file formats
if assigned(fpi.ReadFunction) = False then
begin
DoFinishWork;
end
else
begin
// file format supported
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileIFRetBool(self, LoadFromFile, FileName, FileFormat);
exit;
end;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
fAborting := false;
try
fParams.FileName := FileName;
fParams.FileType := fpi.FileType;
fpi.ReadFunction(fs, fIEBitmap, fParams, Progress, False);
if fAutoAdjustDPI then
AdjustDPI;
Update();
ResetModified();
Result := Not fAborting;
finally
FreeAndNil(fs);
DoFinishWork;
end;
end;
end;
function TImageEnIO.LoadFromFile(const FileName: WideString; bCheckUnknown: Boolean = True): Boolean;
var
ff, ff2: TIOFileType;
begin
Result := False;
fAborting := True; // Handle all failures
ff2 := ioUnknown; // avoid warning
// FIRST LOAD - get type from extension
if string(IEExtractFileExtW(FileName)) = '.avi' then
ff := ioAVI
else
ff := IEFilenameToFileFormat( FileName );
if ff <> ioUnknown then
Result := LoadFromFile(FileName, ff);
// SECOND LOAD - get type from content
if ( result = False ) and bCheckUnknown then
begin
ff2 := FindFileFormat(FileName, ffContentOnly);
if ff <> ff2 then
Result := LoadFromFile(FileName, ff2);
end;
// Has DoFinishWork been called?
if ( ff = ioUnknown ) and
(( bCheckUnknown = False ) or ( ff2 = ioUnknown )) then
DoFinishWork;
end;
{!!
<FS>TImageEnIO.LoadFromFileAuto
<FM>Declaration<FC>
function LoadFromFileAuto(const FileName: WideString): Boolean; dynamic;
<FM>Description<FN>
Loads an image from file. Unlike <A TImageEnIO.LoadFromFile> it ignores the file extension, instead it analyzes the file content to determine its format. Result will be false if the file is not a recognized file type (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
Note: This method can load IEV (<A TImageEnVect> objects) and IEN+IEV formats when <A TImageEnIO.AttachedImageEn> is TImageEnView or TImageEnVect.
<FM>Example<FC>
ImageEnView1.IO.LoadFromFileAuto('C:\input.dat');
ImageEnView1.IO.LoadFromFileAuto('C:\input.tif'); // a tiff or a RAW?
if ImageEnView1.IO.LoadFromFileAuto(sFilename) = False then
ShowMessage('Not a supported file type!');
<FM>See Also<FN>
- <A TImageEnIO.LoadFromFile>
!!}
function TImageEnIO.LoadFromFileAuto(const FileName: WideString): Boolean;
var
ff: TIOFileType;
begin
ff := FindFileFormat(FileName, ffFallbackToExtension);
Result := LoadFromFile(FileName, ff);
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function TImageEnIO.LoadFromFileFormat(const FileName: WideString; FileFormat: TIOFileType): Boolean;
begin
Result := False;
fAborting := True;
if FileFormat <> ioUnknown then
Result := LoadFromFile( FileName, FileFormat );
end;
{$endif}
{!!
<FS>TImageEnIO.LoadThumbnailFromExplorer
<FM>Declaration<FC>
function LoadThumbnailFromExplorer(const FileName : WideString; iDesiredWidth : Integer = 120; iDesiredHeight : Integer = 120): Boolean;
<FM>Description<FN>
Retrieve the thumbnail for the specified file from Windows Explorer. This should work for any format that displays a thumbnail in Windows Explorer, including images and videos.
Use <FC>iDesiredWidth<FN> and <FC>iDesiredHeight<FN> to specify the size of the thumbnail that you require.
The <A TImageEnIO.Aborting> property will be true if the load fails (e.g. if there is not a thumbnail for this file type).
<FM>Example<FC>
// Load a thumbnail for a video
if ImageEnView1.IO.LoadThumbnailFromExplorer('D:\MyVideo.wmv') = False then
ShowMessage('Load Error!');
!!}
{$IFDEF VIDEO_THUMBNAILS}
function TImageEnIO.LoadThumbnailFromExplorer(const FileName : WideString; iDesiredWidth : Integer = 120; iDesiredHeight : Integer = 120): Boolean;
var
ABitmap : TBitmap;
ex: string;
begin
Result := False;
if not assigned(fIEBitmap) then
exit;
CheckHaveValidBitmap();
ABitmap := TBitmap.create;
try
if FileName = '' then
begin
fAborting := True;
exit;
end;
fAborting := False;
if (ExtractExplorerThumbnail(FileName, ABitmap, iDesiredWidth, iDesiredHeight) = False) or (ABitmap.Width < 10) then
begin
fAborting := True;
exit;
end;
fIEBitmap.CopyFromTBitmap(ABitmap);
Params.ResetInfo;
Params.Filename := FileName;
Params.FileType := FindFileFormat( FileName, ffContentOnly );
if Params.FileType = ioUnknown then
begin
ex := string(IEExtractFileExtW(FileName));
if IEFileExtInExtensions(ex, Supported_WMV_File_Extensions) then
Params.FileType := ioWMV
else
if IEFileExtInExtensions(ex, Supported_MPEG_File_Extensions) then
Params.FileType := ioMPEG;
end;
Result := Not fAborting;
finally
ABitmap.Free;
DoFinishWork;
end;
end;
{$ENDIF}
procedure TImageEnIO.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = fImageEnView) and (Operation = opRemove) then
begin
fImageEnView.RemoveBitmapChangeEvent(fImageEnViewBitmapChangeHandle);
fImageEnView := nil;
end;
if (AComponent = fTImage) and (Operation = opRemove) then
fTImage := nil;
end;
procedure TImageEnIO.UpdateAPP138BimResolution;
type
TPSDResolutionInfo=packed record
hRes: longint; // fixed point number: pixels per inch
hResUnit: word; // 1=pixels per inch, 2=pixels per centimeter
WidthUnit: word; // 1=in, 2=cm, 3=pt, 4=picas, 5=columns
vRes: longint; // fixed point number: pixels per inch
vResUnit: word; // 1=pixels per inch, 2=pixels per centimeter
HeightUnit: word; // 1=in, 2=cm, 3=pt, 4=picas, 5=columns
end;
PPSDResolutionInfo=^TPSDResolutionInfo;
var
idx: Integer;
data: PAnsiChar;
len: Integer;
p: Integer;
q: Integer;
ri: PPSDResolutionInfo;
begin
idx := fParams.JPEG_MarkerList.IndexOf( JPEG_APP13 );
if idx > - 1 then
begin
data := fParams.JPEG_MarkerList.MarkerData[idx];
len := fParams.JPEG_MarkerList.MarkerLength[idx];
for p := 0 to len - 1 do
begin
if CompareMem(@data[p], PAnsiChar('8BIM'#3#237), 6) then // 0x03 0xED (resolution identifier)
begin
inc(data, p+6);
q := IESwapWord(pword(data)^); // name length
inc(data, 2);
inc(data, q);
q := IESwapDWord(pdword(data)^); // structure length
inc(data, 4);
if q>=sizeof(TPSDResolutionInfo) then
begin
ri := PPSDResolutionInfo(data);
ri^.hRes := IESwapDWord(fParams.DpiX*65536);
ri^.vRes := IESwapDWord(fParams.DpiY*65536);
ri^.hResUnit := IESwapWord(1); // 1=pixels per inch
ri^.vResUnit := IESwapWord(1); // 1=pixels per inch
ri^.WidthUnit := IESwapWord(1); // 1=in
ri^.HeightUnit := IESwapWord(1); // 1=in
end;
break;
end;
end;
end;
end;
{!!
<FS>TImageEnIO.SaveToStream
<FM>Declaration<FC>
procedure SaveToStream(Stream: TStream; FileType: <A TIOFileType>);
<FM>Description<FN>
SaveToStream saves the image to a stream. You must specify the <L TIOFileType>file format</L> (if ioUnknown is specified, the current <L TIOParams.FileType>file type</L> is used).
If <A TImageEnIO.StreamHeaders> property is True, an additional special header is added, which is needed for multi-image streams.
!!}
procedure TImageEnIO.SaveToStream(Stream: TStream; FileType: TIOFileType);
var
fpi: TIEFileFormatInfo;
Progress: TProgressRec;
begin
if FileType = ioUnknown then
FileType := fParams.FileType;
if FileType = ioUnknown then
FileType := ioJPEG;
if not ( FileType in [ ioIEN, ioSVG ]) then
CheckHaveValidBitmap();
case FileType of
ioTIFF: SaveToStreamTIFF(Stream);
ioGIF: SaveToStreamGIF(Stream);
ioJPEG: SaveToStreamJPEG(Stream);
{$IFDEF IEINCLUDEJPEG2000}
ioJP2: SaveToStreamJP2(Stream);
ioJ2K: SaveToStreamJ2K(Stream);
{$ENDIF}
ioPCX: SaveToStreamPCX(Stream);
ioDCX: SaveToStreamDCX(Stream);
ioBMP: SaveToStreamBMP(Stream);
{$IFDEF IEINCLUDEPNG}
ioPNG: SaveToStreamPNG(Stream);
{$ENDIF}
ioTGA: SaveToStreamTGA(Stream);
ioPXM: SaveToStreamPXM(Stream);
ioICO: SaveToStreamICO(Stream);
ioWBMP: SaveToStreamWBMP(Stream);
ioPS: SaveToStreamPS(Stream);
{$ifdef IEINCLUDEPDFWRITING}
iomscWPPDF,
ioPDF: SaveToStreamPDF(Stream);
{$endif}
{$ifdef IEINCLUDEPSD}
ioPSD: SaveToStreamPSD(Stream);
{$endif}
{$ifdef IEINCLUDEWIC}
ioHDP: SaveToStreamHDP(Stream);
{$endif}
{$ifdef IEINCLUDEDICOM}
ioDICOM: SaveToStreamDICOM(Stream);
{$endif}
ioIEN: SaveToStreamIEN(Stream);
ioSVG: SaveToStreamSVG(Stream);
else
begin
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStreamFF(self, SaveToStream, Stream, FileType);
exit;
end;
fpi := IEFileFormatGetInfo(FileType);
if assigned(fpi) and assigned(fpi.WriteFunction) then
with fpi do
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fParams.FileType := FileType;
WriteFunction(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end
else
fAborting := True;
end;
end;
end;
{!!
<FS>TImageEnIO.LoadFromBuffer
<FM>Declaration<FC>
procedure LoadFromBuffer(Buffer: Pointer; BufferSize: Integer; Format: <A TIOFileType> = ioUnknown);
<FM>Description<FN>
Loads an 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>
See also: <A TImageEnIO.ParamsFromBuffer>
<FM>Example<FC>
ImageEnView1.IO.LoadFromBuffer(mybuffer, mybufferlength, ioJPEG);
!!}
procedure TImageEnIO.LoadFromBuffer(Buffer: Pointer; BufferSize: Integer; Format: TIOFileType);
var
stream: TIEMemStream;
begin
if (Buffer = nil) or (BufferSize = 0) then
begin
fAborting := true;
exit;
end;
stream := TIEMemStream.Create(Buffer, BufferSize);
try
LoadFromStream( stream, Format );
finally
FreeAndNil(stream);
end;
end;
{!!
<FS>TImageEnIO.SaveToText
<FM>Declaration<FC>
procedure SaveToText(Stream: TStream; ImageFormat: <A TIOFileType>; TextFormat: <A TIETextFormat> = ietfASCIIArt);
procedure SaveToText(const FileName: WideString; ImageFormat: <A TIOFileType>; TextFormat: <A TIETextFormat> = ietfASCIIArt);
<FM>Description<FN>
Saves the current image in the specified text format.
Parameters:
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>FileName<FN></C> <C>Output file name.</C> </R>
<R> <C><FC>Stream<FN></C> <C>Output stream.</C> </R>
<R> <C><FC>ImageFormat<FN></C> <C>Wanted file format.</C> </R>
<R> <C><FC>TextFormat<FN></C> <C>Output text format. See allowed values in <A TIETextFormat>.</C> </R>
</TABLE>
See Also: <A TImageEnIO.LoadFromText>
<FM>Example<FC>
ImageEnView1.IO.LoadFromFile('C:\input.jpg');
ImageEnView1.Proc.Resample(128, -1);
ImageEnView1.IO.SaveToText('D:\output.txt', ioUnknown, ietfASCIIArt);
!!}
procedure TImageEnIO.SaveToText(const FileName: WideString; ImageFormat: TIOFileType; TextFormat: TIETextFormat);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
fs := TIEWideFileStream.Create(FileName, fmCreate);
try
fParams.FileName := FileName;
SaveToText(fs, ImageFormat, TextFormat);
finally
fs.Free();
end;
end;
(*
ietfPascal:
const
'FileName_Extension_Size' = nnnn;
'FileName_Extension' : array [0..'FileName_Extension_Size' - 1] of byte = ( $xx,$xx );
ietfHEX
0xaa,0xbb,etc
ietfBase64
/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYF....
*)
procedure TImageEnIO.SaveToText(Stream: TStream; ImageFormat: TIOFileType; TextFormat: TIETextFormat);
const
GR: array [0..9] of AnsiChar = 'W@#*+:., ';
var
ss, s1: AnsiString;
i, j, v: Integer;
blen: Integer;
ms: TMemoryStream;
b: byte;
px: PRGB;
RedToGrayCoef, GreenToGrayCoef, BlueToGrayCoef: integer;
procedure PrepareStream();
begin
ss := AnsiString(fParams.FileName);
i := IEPos('.', ss);
if i > 0 then
ss[i] := '_';
s1 := ss + '_Size';
ms := TMemoryStream.Create();
SaveToStream(ms, ImageFormat);
ms.Position := 0;
blen := ms.Size;
end;
begin
CheckHaveValidBitmap();
ms := nil;
try
case TextFormat of
ietfPascal:
begin
PrepareStream();
IEStreamWriteLn(Stream, 'const' );
IEStreamWriteLn(Stream, ' ' + s1 + ' = ' + IEIntToStr(blen) + ';');
IEStreamWriteLn(Stream, ' ' + ss + ' : array [0..' + s1 + ' - 1] of byte = (' );
ss := '';
for i := 0 to blen - 2 do
begin
ms.Read(b, 1);
ss := ss + '$' + IEIntToHex(b, 2) + ',';
if length(ss) > 70 then
begin
IEStreamWriteLn(Stream, ' ' + ss);
ss := '';
end;
end;
ms.Read(b, 1);
IEStreamWriteLn(Stream, ' ' + ss + '$' + IEIntToHex(b, 2) + ');');
end;
ietfHEX:
begin
PrepareStream();
IEStreamWriteLn(Stream, '\\ Size=' + IEIntToStr(blen));
ss := '';
for i := 0 to blen - 2 do
begin
ms.Read(b, 1);
ss := ss + '0x' + IEIntToHex(b, 2) + ',';
if length(ss) > 70 then
begin
IEStreamWriteLn(Stream, ss);
ss := '';
end;
end;
ms.Read(b, 1);
IEStreamWriteLn(Stream, ss + '0x' + IEIntToHex(b, 2));
end;
ietfBase64:
begin
PrepareStream();
IEEncode64(ms, Stream, 76);
end;
ietfASCIIArt:
begin
if not MakeConsistentBitmap([ie24RGB]) then
exit;
RedToGrayCoef := IEGlobalSettings().RedToGrayCoef;
GreenToGrayCoef := IEGlobalSettings().GreenToGrayCoef;
BlueToGrayCoef := IEGlobalSettings().BlueToGrayCoef;
for i := 0 to fIEBitmap.Height - 1 do
begin
ss := '';
px := fIEBitmap.Scanline[i];
for j := 0 to fIEBitmap.Width - 1 do
begin
with px^ do
v := (r * RedToGrayCoef + g * GreenToGrayCoef + b * BlueToGrayCoef) div 100;
v := Trunc((v / 255) * 9);
ss := ss + GR[v];
inc(px);
end;
IEStreamWriteLn(Stream, ss);
end;
end;
end;
finally
ms.Free();
end;
end;
{!!
<FS>TImageEnIO.LoadFromText
<FM>Declaration<FC>
procedure LoadFromText(const FileName: WideString; TextFormat: <A TIETextFormat> = ietfBase64);
procedure LoadFromText(Stream: TStream; TextFormat: <A TIETextFormat> = ietfBase64);
<FM>Description<FN>
Loads image from text.
Parameters:
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>FileName<FN></C> <C>Input file name.</C> </R>
<R> <C><FC>Stream<FN></C> <C>Input stream.</C> </R>
<R> <C><FC>TextFormat<FN></C> <C>Input text format. Only ietfBase64 is currently supported.</C> </R>
</TABLE>
See Also: <A TImageEnIO.SaveToText>
<FM>Example<FC>
// save as base64 (inside there is a jpeg)
ImageEnView1.IO.LoadFromFile('image.jpg');
ImageEnView1.IO.SaveToText('image.base64', ioJpeg, ietfBase64);
// reload back
ImageEnView1.IO.LoadFromText('image.base64', ietfBase64);
!!}
procedure TImageEnIO.LoadFromText(const FileName: WideString; TextFormat: TIETextFormat);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromText(fs, TextFormat);
finally
fs.Free();
end;
end;
procedure TImageEnIO.LoadFromText(Stream: TStream; TextFormat: TIETextFormat);
var
ms: TMemoryStream;
begin
CheckHaveValidBitmap();
case TextFormat of
ietfPascal,
ietfHex,
ietfASCIIArt:
raise EIEException.create('Unsupported text format');
ietfBase64:
begin
ms := TMemoryStream.Create();
try
IEDecode64(Stream, ms);
ms.Position := 0;
LoadFromStream(ms);
finally
ms.Free();
end;
end;
end;
end;
{!!
<FS>TImageEnIO.LoadFromStream
<FM>Declaration<FC>
function LoadFromStream(Stream: TStream; FileFormat: <A TIOFileType> = ioUnknown): Boolean;
<FM>Description<FN>
Load an image from the specified stream into the attached <A TImageEnView> or <A TIEBitmap>.
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 TImageEnIO.Aborting> will be true).
If the <A TImageEnIO.StreamHeaders> property is True, the stream must have a special header (saved with <A TImageEnIO.SaveToStream>).
Note: This method can load IEV (<A TImageEnVect> objects) and IEN+IEV formats when <A TImageEnIO.AttachedImageEn> is TImageEnView or TImageEnVect.
<FM>Examples<FC>
// load an image from a stream
if ImageEnView1.IO.LoadFromStreamFormat( stm ) = False then
ShowMessage('Not an image!');
// load a jpeg from a stream
if ImageEnView1.IO.LoadFromStreamFormat( stm, ioJPEG ) = False then
ShowMessage('Not a JPEG!');
!!}
function TImageEnIO.LoadFromStream(Stream: TStream; FileFormat: TIOFileType = ioUnknown): Boolean;
var
lp: int64;
fpi: TIEFileFormatInfo;
Progress: TProgressRec;
begin
Result := False;
if FileFormat = ioUnknown then
begin
lp := Stream.Position;
FileFormat := FindStreamFormat(Stream);
Stream.Position := lp;
end;
if FileFormat <> ioIEN then
CheckHaveValidBitmap();
fpi := IEFileFormatGetInfo( FileFormat );
if fpi = nil then
begin
fAborting := true;
exit;
end;
if fpi.InternalFormat then
case FileFormat of
ioTIFF : begin
LoadFromStreamTIFF(Stream);
Result := Not fAborting;
end;
ioGIF : begin
LoadFromStreamGIF(Stream);
Result := Not fAborting;
end;
ioJPEG : Result := LoadFromStreamJPEG(Stream);
ioPCX : Result := LoadFromStreamPCX(Stream);
ioDCX : Result := LoadFromStreamDCX(Stream);
ioBMP : Result := LoadFromStreamBMP(Stream);
ioICO : Result := LoadFromStreamICO(Stream);
ioCUR : Result := LoadFromStreamCUR(Stream);
{$IFDEF IEINCLUDEPNG}
ioPNG : Result := LoadFromStreamPNG(Stream);
{$ENDIF}
{$ifdef IEINCLUDEDICOM}
ioDICOM : Result := LoadFromStreamDICOM(Stream);
{$endif}
ioTGA : Result := LoadFromStreamTGA(Stream);
ioPXM : Result := LoadFromStreamPXM(Stream);
ioWBMP : Result := LoadFromStreamWBMP(Stream);
{$IFDEF IEINCLUDEJPEG2000}
ioJP2 : Result := LoadFromStreamJP2(Stream);
ioJ2K : Result := LoadFromStreamJ2K(Stream);
{$ENDIF}
{$ifdef IEINCLUDERAWFORMATS}
ioRAW : Result := LoadFromStreamRAW(Stream);
{$endif}
ioBMPRAW: Result := LoadFromStreamBMPRAW(Stream);
{$ifdef IEINCLUDEPSD}
ioPSD : Result := LoadFromStreamPSD(Stream);
{$endif}
{$ifdef IEINCLUDEWIC}
ioHDP : Result := LoadFromStreamHDP(Stream);
{$endif}
ioIEN : Result := LoadFromStreamIEN(Stream);
ioIEV, ioALL: begin Result := LoadVectStream(Stream, FileFormat); exit; end;
ioWMF, ioEMF: Result := ImportMetafile(Stream);
end
else
begin
// unknown or user registered file formats
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStreamFTRetBool(self, LoadFromStream, Stream, FileFormat);
Result := True;
exit;
end;
fParams.ResetInfo;
Params.Filename := '';
Params.FileType := ioUnknown;
if assigned(fpi) and assigned(fpi.ReadFunction) then
with fpi do
begin
// file format supported
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.FileType := FileType;
ReadFunction(Stream, fIEBitmap, fParams, Progress, False);
if fAutoAdjustDPI then
AdjustDPI;
Result := Not fAborting;
Update();
ResetModified();
finally
DoFinishWork;
end;
end
else
begin
fAborting := True;
DoFinishWork;
end;
end;
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function TImageEnIO.LoadFromStreamFormat(Stream: TStream; FileFormat: TIOFileType): Boolean;
begin
Result := LoadFromStream( Stream, FileFormat );
end;
{$endif}
{!!
<FS>TImageEnIO.SaveToFilePCX
<FM>Declaration<FC>
procedure SaveToFilePCX(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in PCX format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
// Saves a 256 color PCX
ImageEnView1.IO.Params.BitsPerSample := 8;
ImageEnView1.IO.Params.SamplesPerPixel := 1;
ImageEnView1.IO.SaveToFilePCX('D:\image.pcx');
!!}
procedure TImageEnIO.SaveToFilePCX(const FileName: WideString);
var
Progress: TProgressRec;
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFilePCX, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
WritePcxStream(fs, fIEBitmap, fParams, Progress);
fParams.FileName := FileName;
fParams.FileType := ioPCX;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
function TImageEnIO.SyncLoadFromStreamTGA(Stream: TStream): Boolean;
var
tmpAlphaChannel: TIEMask;
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
tmpAlphaChannel := nil;
ReadTGAStream(Stream, fIEBitmap, fParams, Progress, false, tmpAlphaChannel, false);
CheckDPI;
if assigned(tmpAlphaChannel) then
begin
fIEBitmap.AlphaChannel.CopyFromTIEMask(tmpAlphaChannel);
FreeAndNil(tmpAlphaChannel);
end;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioTGA;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileTGA
<FM>Declaration<FC>
function LoadFromFileTGA(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a TGA file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not TGA format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
!!}
function TImageEnIO.LoadFromFileTGA(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileTGA, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamTGA( fs );
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamTGA
<FM>Declaration<FC>
function LoadFromStreamTGA(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a TGA file. The result will be false if an error is encountered, e.g. the file in the stream is not TGA format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamTGA(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamTGA, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamTGA( Stream );
end;
end;
{!!
<FS>TImageEnIO.SavetoFileTGA
<FM>Declaration<FC>
procedure SaveToFileTGA(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in TGA format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnIO.SaveToFileTGA(const FileName: WideString);
var
Progress: TProgressRec;
fs: TIEWideFileStream;
iemask: TIEMask;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileTGA, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
if fIEBitmap.HasAlphaChannel then
begin
iemask := TIEMask.Create;
fIEBitmap.AlphaChannel.CopyToTIEMask(iemask);
WriteTGAStream(fs, fIEBitmap, fParams, Progress, iemask);
FreeAndNil(iemask);
end
else
WriteTGAStream(fs, fIEBitmap, fParams, Progress, nil);
fParams.FileName := FileName;
fParams.FileType := ioTGA;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamTGA
<FM>Declaration<FC>
procedure SaveToStreamTGA(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in TGA format.
Stream is the image stream.
!!}
procedure TImageEnIO.SaveToStreamTGA(Stream: TStream);
var
Progress: TProgressRec;
iemask: TIEMask;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamTGA, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
if fIEBitmap.HasAlphaChannel then
begin
iemask := TIEMask.Create;
fIEBitmap.AlphaChannel.CopyToTIEMask(iemask);
WriteTGAStream(Stream, fIEBitmap, fParams, Progress, iemask);
FreeAndNil(iemask);
end
else
WriteTGAStream(Stream, fIEBitmap, fParams, Progress, nil);
finally
DoFinishWork;
end;
end;
procedure TImageEnIO.SyncSaveToStreamBMP(Stream: TStream);
var
Progress: TProgressRec;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
BMPWriteStream(Stream, fIEBitmap, fParams, Progress, fParams.BMP_HandleTransparency);
finally
DoFinishWork;
end;
end;
procedure TImageEnIO.SyncSaveToStreamDCX(Stream: TStream);
var
Progress: TProgressRec;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
IEDCXInsertStream(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamDCX
<FM>Declaration<FC>
procedure SaveToStreamDCX(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in DCX format.
!!}
procedure TImageEnIO.SaveToStreamDCX(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamDCX, Stream);
end
else
begin
Stream.Size := 0; // this avoid that this function inserts
SyncSaveToStreamDCX(Stream);
end;
end;
{!!
<FS>TImageEnIO.SaveToFileDCX
<FM>Declaration<FC>
procedure SaveToFileDCX(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in DCX format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnIO.SaveToFileDCX(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileDCX, FileName);
exit;
end;
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmCreate);
SyncSaveToStreamDCX(fs);
fParams.FileName := FileName;
fParams.FileType := ioDCX;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.InsertToFileDCX
<FM>Declaration<FC>
procedure InsertToFileDCX(const FileName: WideString);
<FM>Description<FN>
Inserts the current image into the specified DCX file, at the position specified by <A TImageEnIO.Params>.<A TIOParams.DCX_ImageIndex>.
<FM>Example<FC>
ImageEnView1.IO.Params.DCX_ImageIndex := 1;
ImageEnView1.IO.InsertToFileDCX('D:\multipage.dcx');
!!}
procedure TImageEnIO.InsertToFileDCX(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, InsertToFileDCX, FileName);
exit;
end;
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenReadWrite);
SyncSaveToStreamDCX(fs);
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamBMP
<FM>Declaration<FC>
procedure SaveToStreamBMP(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in BMP format.
If <A TImageEnIO.StreamHeaders> property is True, it adds an additional special header as needed for multi-image streams.
<FM>Example<FC>
// Saves ImageEnView1 and ImageEnView2 images in file images.dat
// images.dat isn't loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('bmpimages.dat', fmCreate);
ImageEnView1.IO.StreamHeaders := True;
ImageEnView1.IO.SaveToStreamBMP(fs);
ImageEnView2.IO.StreamHeaders := True;
ImageEnView2.IO.SaveToStreamBMP(fs);
fs.free;
End;
// Saves a single image in image.bmp
// image.bmp is loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('image.bmp');
ImageEnView1.IO.StreamHeaders := False;
ImageEnView1.IO.SaveToFileBMP(fs);
End;
!!}
procedure TImageEnIO.SaveToStreamBMP(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamBMP, Stream);
end
else
begin
SyncSaveToStreamBMP(Stream);
end;
end;
{!!
<FS>TImageEnIO.SaveToFileBMP
<FM>Declaration<FC>
procedure SaveToFileBMP(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in BMP format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
// Saves a 256 color compressed bitmap bitmap
ImageEnView1.IO.Params.BitsPerSample := 8;
ImageEnView1.IO.Params.SamplesPerPixel := 1;
ImageEnView1.IO.Params.BMP_Compression := ioBMP_RLE;
ImageEnView1.IO.SaveToFile('D:\Italy.bmp');
!!}
procedure TImageEnIO.SaveToFileBMP(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileBMP, FileName);
exit;
end;
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmCreate);
SyncSaveToStreamBMP(fs);
fParams.FileName := FileName;
fParams.FileType := ioBMP;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.SaveToFileTIFF
<FM>Declaration<FC>
procedure SaveToFileTIFF(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in TIFF format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
ImageEnView1.IO.Params.DocumentName := 'My document';
ImageEnView1.IO.SaveToFileTIFF('C:\image.tiff');
!!}
procedure TImageEnIO.SaveToFileTIFF(const FileName: WideString);
var
Progress: TProgressRec;
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileTIFF, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
TIFFWriteStream(fs, false, fIEBitmap, fParams, Progress);
fParams.FileName := FileName;
fParams.FileType := ioTIFF;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamTIFF
<FM>Declaration<FC>
procedure SaveToStreamTIFF(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in TIFF format.
If <A TImageEnIO.StreamHeaders> property is True, it adds an additional special header as needed for multi-image streams.
<FM>Example<FC>
// Saves ImageEnView1 and ImageEnView2 attached images in file images.dat
// images.dat isn't loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('bmpimages.dat', fmCreate);
ImageEnView1.IO.StreamHeaders := True;
ImageEnView1.IO.SaveToStreamTIFF(fs);
ImageEnView2.IO.StreamHeaders := True;
ImageEnView2.IO.SaveToStreamTIFF(fs);
fs.free;
End;
// Saves a single image in image.tif
// image.tif is loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('image.tif');
ImageEnView1.IO.StreamHeaders := False;
ImageEnView1.IO.SaveToFileTIFF(fs);
End;
!!}
procedure TImageEnIO.SaveToStreamTIFF(Stream: TStream);
var
SHead: TIFFSHead;
lp1, lp2: int64;
Progress: TProgressRec;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamTIFF, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
lp1 := 0;
if fStreamHeaders then
begin
lp1 := Stream.position;
Stream.write(SHead, sizeof(SHead)); // create space for TIFF stream header
end;
TIFFWriteStream(Stream, false, fIEBitmap, fParams, Progress);
if fStreamHeaders then
begin
// salve HEADER-TIFF-STREAM
lp2 := Stream.position;
Stream.position := lp1;
SHead.id := 'TIFF';
SHead.dim := lp2 - lp1 - sizeof(SHead);
Stream.Write(SHead, sizeof(SHead));
Stream.position := lp2;
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamPCX
<FM>Declaration<FC>
procedure SaveToStreamPCX(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in PCX format.
If <A TImageEnIO.StreamHeaders> property is True, it adds an additional special header as needed for multi-image streams.
<FM>Example<FC>
// Saves ImageEnView1 and ImageEnView2 attached images in file images.dat
// images.dat isn't loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('bmpimages.dat', fmCreate);
ImageEnView1.IO.StreamHeaders := True;
ImageEnView1.IO.SaveToStreamPCX(fs);
ImageEnView2.IO.StreamHeaders := True;
ImageEnView2.IO.SaveToStreamPCX(fs);
fs.free;
End;
// Saves a single image in image.pcx
// image.pcx is loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('image.pcx');
ImageEnView1.IO.StreamHeaders := False;
ImageEnView1.IO.SaveToFilePCX(fs);
End;
!!}
procedure TImageEnIO.SaveToStreamPCX(Stream: TStream);
var
SHead: PCXSHead;
lp1, lp2: int64;
Progress: TProgressRec;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamPCX, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
lp1 := 0;
if fStreamHeaders then
begin
lp1 := Stream.position;
Stream.write(SHead, sizeof(SHead)); // lascia spazio per header PCX stream
end;
WritePcxStream(Stream, fIEBitmap, fParams, Progress);
if fStreamHeaders and not fAborting then
begin
// salva HEADER-PCX-STREAM
lp2 := Stream.position;
Stream.position := lp1;
SHead.id := 'PCX2';
SHead.dim := lp2 - lp1 - sizeof(SHead);
Stream.Write(SHead, sizeof(SHead));
Stream.position := lp2;
end;
finally
DoFinishWork;
end;
end;
// do parameters previews
// return True if user press OK
{$IFDEF IEINCLUDEDIALOGIO}
{!!
<FS>TImageEnIO.DoPreviews
<FM>Declaration<FC>
function DoPreviews(pp: <A TPreviewParams> = [ppAll]): boolean;
<FM>Description<FN>
Executes the Previews dialog allowing the user to review and modify the parameters of image file formats (for example, JPEG quality, TIFF compression, etc).
<FC>pp<FN> is the set of image formats parameters to show in the dialog.
The style of the dialog is affected by <A TImageEnIO.SimplifiedParamsDialogs>
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\FullApps\PhotoEn3\ImageEx.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.LoadFromFile('C:\myimage.gif'); // loads a GIF image
ImageEnView1.IO.DoPreviews([ppGIF]); // sets GIF parameters (background, transparency...)
ImageEnView1.IO.SaveToFile('D:\newimage.gif'); // saves some image with new parameters
!!}
function TImageEnIO.DoPreviews(pp: TPreviewParams = [ppAll]): boolean;
var
fIOPreviews: TfIOPreviews;
Handled: boolean;
begin
Handled := false;
if assigned(fOnDoPreviews) then
fOnDoPreviews(self, Handled);
if not Handled then
begin
result := false;
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fIOPreviews := TfIOPreviews.Create(self);
fIOPreviews.DefaultLockPreview := ioppDefaultLockPreview in PreviewsParams;
fIOPreviews.btnApply.Visible := ioppApplyButton in PreviewsParams;
fIOPreviews.Params := GetParams;
fIOPreviews.Simplified := fSimplifiedParamsDialogs;
fIOPreviews.fDefaultDitherMethod := fDefaultDitherMethod;
fIOPreviews.UpdateLanguage();
if fPreviewFontEnabled then
fIOPreviews.Font.Assign(fPreviewFont)
else
fIOPreviews.Font.Assign(IEGetDefaultDialogFont);
fIOPreviews.ienSource.SetExternalBitmap( fIEBitmap );
// Use same mouse wheel settings as owner component
if assigned( fImageEnView ) and ( fImageEnView is TImageEnView ) then
with TImageEnView( fImageEnView ) do
begin
fIOPreviews.ienSource .MouseWheelParams.Assign( MouseWheelParams );
fIOPreviews.ienPreview.MouseWheelParams.Assign( MouseWheelParams );
end;
fIOPreviews.ienSource.Update();
fIOPreviews.ienPreview.Blank;
if fIOPreviews.SetPreviewParams(pp) then
begin
if assigned(fOnIOPreview) then
fOnIOPreview(self, fIOPreviews);
result := fIOPreviews.ShowModal = mrOk;
end;
fIOPreviews.ienSource.SetExternalBitmap( nil );
fIOPreviews.Release;
Update();
end
else
result := true; // handled
end;
{$ENDIF}
function TImageEnIO.SyncLoadFromStreamJPEG(Stream: TStream; bCheckHeader: Boolean): Boolean;
var
sh: TStreamJpegHeader;
lp: int64;
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
lp := 0; // avoid warning
if bCheckHeader then
begin
lp := Stream.Position;
Stream.Read(sh, sizeof(sh)); // carica header TStreamJpegHeader
if sh.ID <> 'JFIF' then
// stream header don't exist, reset to beginning
Stream.Position := lp;
end;
fIEBitmap.RemoveAlphaChannel;
ReadJpegStream(Stream, nil, fIEBitmap, fParams, Progress, False, false, true, false, true, true, -1, fParams.IsNativePixelFormat);
CheckDPI;
if bCheckHeader and ( sh.ID = 'JFIF' ) then
Stream.Position := lp + sizeof(sh) + sh.dim;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioJPEG;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileJpeg
<FM>Declaration<FC>
function LoadFromFileJpeg(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a JPEG file. Result will be false if the file is not JPEG format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FC>FileName<FN> is the file name including extension.
<FM>Example<FC>
ImageEnView1.IO.LoadFromFileJpeg('C:\alfa.jpg');
!!}
function TImageEnIO.LoadFromFileJpeg(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
XStream: TIEBufferedReadStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileJpeg, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
XStream := TIEBufferedReadStream.Create(fs, 65536);
try
Result := SyncLoadFromStreamJPEG( XStream, False );
fParams.FileName := FileName;
finally
FreeAndNil(XStream);
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamJpeg
<FM>Declaration<FC>
function LoadFromStreamJpeg(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a JPEG file. The result will be false if an error is encountered, e.g. the file in the stream is not JPEG format (<A TImageEnIO.Aborting> will be true).
Note: If <A TImageEnIO.StreamHeaders> property is True, the stream must have a special header (saved with <A TImageEnIO.SaveToStreamJPEG>).
<FM>Example<FC>
// loads a JPEG file with LoadfFromStreamJPEG
var
fs: TFileStream;
Begin
fs := TFileStream.Create('C:\myfile.jpg', fmOpenRead);
ImageEnView1.IO.LoadFromStreamJPG(fs);
fs.free;
End;
!!}
// at the beginning could be a TStreamJpegHeader structure
function TImageEnIO.LoadFromStreamJpeg(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamJpeg, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamJPEG( Stream, True );
end;
end;
procedure TImageEnIO.SyncSaveToStreamJpeg(Stream: TStream; streamhead: boolean);
var
sh: TStreamJpegHeader;
lp, lp2: int64;
Progress: TProgressRec;
buf: pointer;
dummy: Boolean;
lbuf, mi, i: integer;
begin
try
fAborting := false;
Progress.Aborting := @fAborting;
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
lp := 0;
if streamhead then
begin
lp := Stream.position; // save initial position
Stream.write(sh, sizeof(sh)); // leaves spaces for the header
end;
// update APP13 - 8BIM dpi info (Photoshop) resolution. This is overwritten if IPTC is written.
UpdateAPP138BimResolution;
// update APP13 marker with IPTC_Info
if (fParams.IPTC_Info.UserChanged) or ( (fParams.IPTC_Info.Count > 0) and (fParams.JPEG_MarkerList.Count = 0) ) then
begin
fParams.IPTC_Info.SaveToStandardBuffer(buf, lbuf, true);
mi := fParams.JPEG_MarkerList.IndexOf(JPEG_APP13);
if buf <> nil then
begin
// replace or add IPTC marker
if mi >= 0 then
fParams.JPEG_MarkerList.SetMarker(mi, JPEG_APP13, buf, lbuf)
else
fParams.JPEG_MarkerList.AddMarker(JPEG_APP13, buf, lbuf);
freemem(buf);
end
else
if mi >= 0 then
// remove IPTC marker
fParams.JPEG_MarkerList.DeleteMarker(mi);
end;
// Exif info
if fParams.EXIF_HasExifData then
begin
// save in temporary buffer
SaveEXIFToStandardBuffer(fParams, buf, lbuf, true);
// remove previous EXIF data
with fParams.JPEG_MarkerList do
for i := 0 to Count - 1 do
if (MarkerType[i] = JPEG_APP1) and CheckEXIFFromStandardBuffer(MarkerData[i], MarkerLength[i]) then
begin
DeleteMarker(i);
break;
end;
// save in APP1
fParams.JPEG_MarkerList.AddMarker(JPEG_APP1, buf, lbuf);
freemem(buf);
end;
// XMP
// remove previous XMP data
with fParams.JPEG_MarkerList do
for i := 0 to Count - 1 do
if (MarkerType[i] = JPEG_APP1) and (IEFindXMPFromJpegTag(MarkerData[i], MarkerLength[i]) <> nil) then
begin
DeleteMarker(i);
break;
end;
if fParams.XMP_Info <> '' then
begin
// save in temporary buffer
IESaveXMPToJpegTag(fParams, buf, lbuf);
// save in APP1
fParams.JPEG_MarkerList.AddMarker(JPEG_APP1, buf, lbuf);
freemem(buf);
end;
// ImageEn annotations (TImageEnVect objects)
// remove previous ImageEn Annot data
with fParams.JPEG_MarkerList do
for i := 0 to Count - 1do
if (MarkerType[i] = JPEG_APP1) and TIEImageEnAnnot.BufferContainsImageEnAnnot(MarkerData[i], MarkerLength[i], dummy) then
begin
DeleteMarker(i);
break;
end;
if not fParams.ImageEnAnnot.IsEmpty() then
begin
// save in temporary buffer
fParams.ImageEnAnnot.SaveToBuffer(buf, lbuf);
// save in APP1
fParams.JPEG_MarkerList.AddMarker(JPEG_APP1, buf, lbuf);
freemem(buf);
end;
// save jpeg
Progress.fOnProgress := fOnIntProgress;
Progress.Sender := Self;
WriteJpegStream(Stream, fIEBitmap, fParams, Progress);
if streamhead then
begin
lp2 := Stream.position; // saves final position
Stream.position := lp; // return to initial position
sh.ID := 'JFIF';
sh.dim := lp2 - lp - sizeof(sh);
Stream.Write(sh, sizeof(sh)); // Saves header TStreamJpegHeader
Stream.position := lp2; // return to final position
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamJpeg
<FM>Declaration<FC>
procedure SaveToStreamJpeg(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in JPEG format.
If <A TImageEnIO.StreamHeaders> property is True, it adds an additional special header as needed for multi-image streams.
<FM>Example<FC>
// Saves ImageEnView1 and ImageEnView2 attached images in file images.dat
// images.dat isn't loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('bmpimages.dat', fmCreate);
ImageEnView1.IO.StreamHeaders := True;
ImageEnView1.IO.SaveToStreamJPEG(fs);
ImageEnView2.IO.StreamHeaders := True;
ImageEnView2.IO.SaveToStreamJPEG(fs);
fs.free;
End;
// Saves a single image in image.jpg
// image.jpg is loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('image.jpg');
ImageEnView1.IO.StreamHeaders := False;
ImageEnView1.IO.SaveToFileJPEG(fs);
End;
!!}
procedure TImageEnIO.SaveToStreamJpeg(Stream: TStream);
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamJpeg, Stream);
exit;
end;
SyncSaveToStreamJpeg(Stream, fStreamHeaders);
end;
{!!
<FS>TImageEnIO.SaveToFileJpeg
<FM>Declaration<FC>
procedure SaveToFileJpeg(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in JPEG format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
// Saves a gray levels, progressive jpeg image with quality 70
ImageEnView1.IO.Params.JPEG_ColorSpace := ioJPEG_GRAYLEV;
ImageEnView1.IO.Params.JPEG_Quality := 70;
ImageEnView1.IO.Params.JPEG_Progressive := True;
ImageEnView1.IO.SaveToFileJpeg('C:\image.jpg');
!!}
procedure TImageEnIO.SaveToFileJpeg(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileJpeg, FileName);
exit;
end;
fs := TIEWideFileStream.Create(FileName, fmCreate);
try
SyncSaveToStreamJpeg(fs, false);
fParams.FileName := FileName;
fParams.FileType := ioJPEG;
finally
fs.Free();
end;
end;
{!!
<FS>TImageEnIO.PreviewFont
<FM>Declaration<FC>
property PreviewFont: TFont;
<FM>Description<FN>
If <A TImageEnIO.PreviewFontEnabled> is set to True then <FC>PreviewFont<FN> specifies the font used in the <A TImageEnIO.DoPreviews> dialog.
Note: You should ensure the size of the font matches the length of the dialog controls.
<FM>Example<FC>
ImageEnView1.IO.PreviewFont.Name := 'MS Times New Roman';
ImageEnView1.IO.PreviewFontEnabled := True;
ImageEnView1.IO.DoPreviews([ppAll]);
!!}
procedure TImageEnIO.SetPreviewFont(f: TFont);
begin
fPreviewFont.assign(f);
end;
{!!
<FS>TImageEnIO.PreviewFontEnabled
<FM>Declaration<FC>
property PreviewFontEnabled: Boolean;
<FM>Description<FN>
When set to True then you can use <A TImageEnIO.PreviewFont> to specify a custom font for the <A TImageEnIO.DoPreviews> dialogs.
<FM>Example<FC>
ImageEnView1.IO.PreviewFont.Name := 'MS Times New Roman';
ImageEnView1.IO.PreviewFontEnabled := True;
ImageEnView1.IO.DoPreviews([ppAll]);
!!}
procedure TImageEnIO.SetPreviewFontEnabled(Value : Boolean);
begin
fPreviewFontEnabled := Value;
end;
function TImageEnIO.SyncLoadFromStreamBMP(Stream: TStream): Boolean;
var
Progress: TProgressRec;
tmpAlphaChannel: TIEMask;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
tmpAlphaChannel := nil;
BMPReadStream(Stream, fIEBitmap, 0, fParams, Progress, false, false, tmpAlphaChannel, not fParams.BMP_HandleTransparency);
CheckDPI;
if assigned(tmpAlphaChannel) then
begin
fIEBitmap.AlphaChannel.CopyFromTIEMask(tmpAlphaChannel);
FreeAndNil(tmpAlphaChannel);
end;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioBMP;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamBMP
<FM>Declaration<FC>
function LoadFromStreamBMP(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a BMP file. The result will be false if an error is encountered, e.g. the file in the stream is not BMP format (<A TImageEnIO.Aborting> will be true).
Note: If <A TImageEnIO.StreamHeaders> property is True, the stream must have a special header (saved with <A TImageEnIO.SaveToStreamBMP>).
<FM>Example<FC>
// loads a BMP file with LoadfFromStreamBMP
var
fs: TFileStream;
Begin
fs := TFileStream.Create('C:\myfile.bmp', fmOpenRead);
ImageEnView1.IO.LoadFromStreamBMP(fs);
fs.free;
End;
!!}
function TImageEnIO.LoadFromStreamBMP(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamBMP, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamBMP(Stream);
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileBMP
<FM>Declaration<FC>
function LoadFromFileBMP(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a BMP file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not BMP format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FM>Example<FC>
ImageEnView1.IO.LoadFromFileBMP('C:\myimage.bmp');
!!}
function TImageEnIO.LoadFromFileBMP(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileBMP, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamBMP(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.AssignParams
<FM>Declaration<FC>
procedure AssignParams(Source: TObject);
<FM>Description<FN>
Assign the file format parameters from another TImageEnIO component or <A TIOParams> object.
!!}
// Copy only Params
procedure TImageEnIO.AssignParams(Source: TObject);
begin
if Source is TImageEnIO then
fParams.assign((Source as TImageEnIO).Params)
else
if Source is TIOParams then
fParams.assign(Source as TIOParams);
end;
// reset fBitmap (called from RegisterBitmapChangeEvent)
procedure TImageEnIO.OnBitmapChange(Sender: TObject; destroying: boolean);
begin
if destroying then
begin
fImageEnView := nil;
end
else
if assigned(fImageEnView) then
begin
if assigned(fIEBitmap) then
begin
fIEBitmap := fImageEnView.IEBitmap;
fBitmap := nil; // both fBitmap and fIEBitmap aren't allowed if not encapsulated
end
else
if assigned(fBitmap) then
begin
fBitmap := fImageEnView.Bitmap;
if fIEBitmapCreated then
fIEBitmap.EncapsulateTBitmap(fBitmap, true)
end;
end;
end;
{$IFDEF IEINCLUDEPNG}
function TImageEnIO.SyncLoadFromStreamPNG(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fParams.PNG_Background := tcolor2trgb(Background);
fIEBitmap.RemoveAlphaChannel;
ReadPNGStream(Stream, fIEBitmap, fParams, Progress, false);
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioPNG;
Background := TRGB2TCOLOR(fParams.PNG_Background);
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFilePNG
<FM>Declaration<FC>
function LoadFromFilePNG(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a PNG file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not PNG format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
!!}
function TImageEnIO.LoadFromFilePNG(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFilePNG, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamPNG(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEPNG}
{!!
<FS>TImageEnIO.LoadFromStreamPNG
<FM>Declaration<FC>
function LoadFromStreamPNG(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a PNG file. The result will be false if an error is encountered, e.g. the file in the stream is not PNG format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamPNG(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamPNG, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamPNG(Stream);
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEPNG}
{!!
<FS>TImageEnIO.SaveToFilePNG
<FM>Declaration<FC>
procedure SaveToFilePNG(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in PNG format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
<FM>Example<FC>
// Set best compression
ImageEnView1.IO.Params.PNG_Filter := ioPNG_FILTER_PAETH;
ImageEnView1.IO.Params.PNG_Compression := 9;
// Save PNG
ImageEnView1.IO.SaveToFilePNG('D:\max.png');
!!}
procedure TImageEnIO.SaveToFilePNG(const FileName: WideString);
var
fs: TIEWideFileStream;
Progress: TProgressRec;
iemask: TIEMask;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFilePNG, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
if fIEBitmap.HasAlphaChannel then
begin
iemask := TIEMask.Create();
fIEBitmap.AlphaChannel.CopyToTIEMask(iemask);
WritePNGStream(fs, fIEBitmap, fParams, Progress, iemask);
FreeAndNil(iemask);
end
else
WritePNGStream(fs, fIEBitmap, fParams, Progress, nil);
fParams.FileName := FileName;
fParams.FileType := ioPNG;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEPNG}
{!!
<FS>TImageEnIO.SaveToStreamPNG
<FM>Declaration<FC>
procedure SaveToStreamPNG(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in PNG format.
<FM>Example<FC>
// Set best compression
ImageEnView1.IO.Params.PNG_Filter := ioPNG_FILTER_PAETH;
ImageEnView1.IO.Params.PNG_Compression := 9;
// Save PNG
ImageEnView1.IO.SaveToStreamPNG(Stream);
!!}
procedure TImageEnIO.SaveToStreamPNG(Stream: TStream);
var
Progress: TProgressRec;
iemask: TIEMask;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamPNG, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if fIEBitmap.HasAlphaChannel then
begin
iemask := TIEMask.Create;
fIEBitmap.AlphaChannel.CopyToTIEMask(iemask);
WritePNGStream(Stream, fIEBitmap, fParams, Progress, iemask);
FreeAndNil(iemask);
end
else
WritePNGStream(Stream, fIEBitmap, fParams, Progress, nil);
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$ifdef IEINCLUDEDICOM}
function TImageEnIO.SyncLoadFromStreamDICOM(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
IEDicomRead(Stream, fParams, fIEBitmap, Progress, false);
fParams.FileName := '';
fParams.FileType := ioDICOM;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileDICOM
<FM>Declaration<FC>
function LoadFromFileDICOM(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a DICOM file. This method is necessary for DICOM files that don't have an extension or a valid DICOM header, but you know to be DICOM format.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not DICOM format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
Note: DICOM parameters are stored in <A TIOParams.DICOM_Tags>
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\Dicom\Dicom.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.LoadFromFileDICOM('heart.dcm');
Load the second image of a multiple image DICOM
ImageEnView1.IO.Params.ImageIndex := 1;
ImageEnView1.IO.LoadFromFileDICOM('D:\MyImage.dcm');
!!}
function TImageEnIO.LoadFromFileDICOM(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileDICOM, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamDICOM(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamDICOM
<FM>Declaration<FC>
function LoadFromStreamDICOM(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a DICOM file. The result will be false if an error is encountered, e.g. the file in the stream is not DICOM format (<A TImageEnIO.Aborting> will be true).
Note: DICOM parameters are stored in <A TIOParams.DICOM_Tags>.
!!}
function TImageEnIO.LoadFromStreamDICOM(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamDICOM, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamDICOM(Stream);
end;
end;
procedure TImageEnIO.SyncSaveToStreamDICOM(Stream: TStream);
var
Progress: TProgressRec;
context: pointer;
iBitsPerSample, iSamplesPerPixel: Integer;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if not ( fIEBitmap.PixelFormat in [ ie1g, ie8g, ie16g, ie24RGB ] ) then
raise EIEException.Create('DICOM saving: unsupported pixel format');
IEPixelFormatToBPSAndSPP( fIEBitmap.PixelFormat, iBitsPerSample, iSamplesPerPixel );
fParams.BitsPerSample := iBitsPerSample;
fParams.SamplesPerPixel := iSamplesPerPixel;
fParams.Width := fIEBitmap.Width;
fParams.Height := fIEBitmap.Height;
context := IEDicomWrite_init(Stream, fParams, 1, Progress);
IEDicomWrite_addImage(context, fIEBitmap);
IEDicomWrite_finalize(context);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamDicom
<FM>Declaration<FC>
procedure SaveToStreamDicom(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in DICOM format.
If <A TImageEnIO.StreamHeaders> property is true, then a special header is added as required for multi-image streams.
<FM>Example<FC>
// Saves images in ImageEnView1 and ImageEnView2 to the file Images.dat
// Note: images.dat isn't loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('C:\images.dat', fmCreate);
ImageEnView1.IO.StreamHeaders := True;
ImageEnView1.IO.SaveToStreamDicom(fs);
ImageEnView2.IO.StreamHeaders := True;
ImageEnView2.IO.SaveToStreamDicom(fs);
fs.free;
End;
// Saves a single image to image.Dicom
// image.Dicom is loadable with LoadFromFileXXX methods
var
fs: TFileStream;
Begin
fs := TFileStream.Create('image.Dicom');
ImageEnView1.IO.StreamHeaders := False;
ImageEnView1.IO.SaveToFileDicom(fs);
End;
!!}
procedure TImageEnIO.SaveToStreamDICOM(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamDICOM, Stream);
end
else
begin
SyncSaveToStreamDICOM(Stream);
end;
end;
{!!
<FS>TImageEnIO.SaveToFileDicom
<FM>Declaration<FC>
procedure SaveToFileDicom(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in Dicom medical imaging format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.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\InputOutput\Dicom\Dicom.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.SaveToFileDicom('D:\image.dicom');
!!}
procedure TImageEnIO.SaveToFileDICOM(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileDICOM, FileName);
exit;
end;
fs := TIEWideFileStream.Create(FileName, fmCreate);
try
SyncSaveToStreamDICOM(fs);
fParams.FileName := FileName;
fParams.FileType := ioDICOM;
finally
FreeAndNil(fs);
end;
end;
{$endif} // IEINCLUDEDICOM
{!!
<FS>TImageEnIO.PreviewsParams
<FM>Declaration<FC>
property PreviewsParams: <A TIOPreviewsParams>;
<FM>Description<FN>
Specifies the features of the <L TImageEnIO.DoPreviews>File Format Parameters dialog</L>.
<FM>Example<FC>
ImageEnView1.IO.PreviewsParams := [ioppDefaultLockPreview];
ImageEnView1.IO.DoPreviews([ppTIFF]);
!!}
procedure TImageEnIO.SetIOPreviewParams(v: TIOPreviewsParams);
begin
fPreviewsParams := v;
end;
function TImageEnIO.GetIOPreviewParams: TIOPreviewsParams;
begin
result := fPreviewsParams;
end;
function TImageEnIO.SyncLoadFromStreamICO(Stream: TStream): Boolean;
var
Progress: TProgressRec;
tmpAlphaChannel: TIEMask;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
tmpAlphaChannel := nil;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
ICOReadStream(Stream, fIEBitmap, fParams, false, Progress, tmpAlphaChannel, false);
CheckDPI;
if assigned(tmpAlphaChannel) then
fIEBitmap.AlphaChannel.CopyFromTIEMask(tmpAlphaChannel);
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioICO;
Update();
ResetModified();
finally
tmpAlphaChannel.Free;
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileICO
<FM>Declaration<FC>
function LoadFromFileICO(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from an icon file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not ICO format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\FullApps\PlainIconEditor\PlainIconEditor.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.LoadFromFileICO('C:\gates.ico');
!!}
function TImageEnIO.LoadFromFileICO(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileICO, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamICO(fs);
finally
FreeAndNil(fs);
end;
fParams.FileName := FileName;
end;
{!!
<FS>TImageEnIO.LoadFromStreamICO
<FM>Declaration<FC>
function LoadFromStreamICO(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing an icon file. The result will be false if an error is encountered, e.g. the file in the stream is not ICO format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamICO(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamICO, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamICO(Stream);
end;
end;
function TImageEnIO.SyncLoadFromStreamCUR(Stream: TStream): Boolean;
var
Progress: TProgressRec;
tmpAlphaChannel: TIEMask;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
tmpAlphaChannel := nil;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
CURReadStream(Stream, fIEBitmap, fParams, false, Progress, tmpAlphaChannel, false);
CheckDPI;
if assigned(tmpAlphaChannel) then
fIEBitmap.AlphaChannel.CopyFromTIEMask(tmpAlphaChannel);
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioCUR;
Update();
ResetModified();
finally
tmpAlphaChannel.Free;
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamCUR
<FM>Declaration<FC>
function LoadFromStreamCUR(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a cursor file. The result will be false if an error is encountered, e.g. the file in the stream is not CUR format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamCUR(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamCUR, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamCUR(Stream);
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileCUR
<FM>Declaration<FC>
function LoadFromFileCUR(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a cursor file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not ICO format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FM>Example<FC>
ImageEnView1.IO.LoadFromFileCUR('C:\gates.cur');
!!}
function TImageEnIO.LoadFromFileCUR(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileCUR, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamCUR(fs);
finally
FreeAndNil(fs);
end;
fParams.FileName := FileName;
end;
procedure IEMetafileCalcDestSize(metaWidth, metaheight: integer; requiredWidth, requiredHeight: integer; out dstWidth: integer; out dstHeight: integer);
begin
dstWidth := metaWidth;
dstHeight := metaHeight;
if (requiredWidth > 0) or (requiredHeight > 0) then
begin
if (requiredWidth > 0) and (requiredHeight > 0) then
begin
dstWidth := requiredWidth;
dstHeight := requiredHeight;
end
else
begin
if requiredWidth < 0 then
begin
dstWidth := (metaWidth * requiredHeight) div metaHeight;
dstHeight := requiredHeight;
end
else
if requiredHeight < 0 then
begin
dstHeight := (metaHeight * requiredWidth) div metaWidth;
dstWidth := requiredWidth;
end;
end;
end;
if (dstWidth > IEGlobalSettings().MaxImageEMFSize) or (dstHeight > IEGlobalSettings().MaxImageEMFSize) then
begin
if dstHeight > dstWidth then
begin
dstWidth := (dstWidth * IEGlobalSettings().MaxImageEMFSize) div dstHeight;
dstHeight := IEGlobalSettings().MaxImageEMFSize;
end
else
begin
dstHeight := (dstHeight * IEGlobalSettings().MaxImageEMFSize) div dstWidth;
dstWidth := IEGlobalSettings().MaxImageEMFSize;
end;
end;
end;
{!!
<FS>TImageEnIO.ImportMetafile
<FM>Declaration<FC>
function ImportMetafile(const FileName: WideString; Width, Height: Integer; WithAlpha: Boolean): Boolean;
function ImportMetafile(Stream: TStream; Width: Integer = -1; Height: Integer = -1; WithAlpha: boolean = True): Boolean;
function ImportMetafile(meta: TMetafile; Width: Integer = -1; Height: Integer = -1; WithAlpha: Boolean = True): Boolean;
function ImportMetafile(meta: TIEMetafile; Width: Integer = -1; Height: Integer = -1; WithAlpha: Boolean = True); Boolean;
<FM>Description<FN>
Imports a WMF or EMF vectorial image. If the file does not represent a valid image format, ImportMetafile raises an <FC>EInvalidGraphic<FN> exception.
<FC>Width<FN> and <FC>Height<FN> specify the image size (the rectangle where the vectorial image will be painted).
To maintain the image aspect ratio set only one size, assigning -1 to the other, e.g. ImportMetafile('axi.emf', -1, 500);
If <FC>WithAlpha<FN> is true then ImportMetaFile creates an alpha channel, making only the metafile content visible.
Note: ImportMetafile converts the vectorial image to a raster image, so you must limit the rasterized image sizes. The maximum allowed size is stored in the public field named <A TIEImageEnGlobalSettings.MaxImageEMFSize>.
<FM>Example<FC>
// import vectorial image 'alfa.wmf', resizing to 500xHHH (HHH is autocalculated)
ImageEnView1.IO.ImportMetafile('C:\alfa.wmf', 500, -1, true);
!!}
// If Width or Height is -1 then it is auto-calculated maintain aspect ratio
// Import... because this is a vectorial image
// SHOULD NOT BE IN THREADS BECAUSE USE TCANVAS AND TMETAFILE!!
function TImageEnIO.ImportMetaFile(meta: TMetaFile; Width, Height: Integer; WithAlpha: Boolean): Boolean;
var
dib: TIEDibBitmap;
dibcanvas: TCanvas;
x, y: integer;
px: pbyte;
p_rgb: PRGB;
w, h: integer;
dstWidth, dstHeight: integer;
begin
Result := False;
fAborting := false;
if (meta.Width = 0) or (meta.Height = 0) then
begin
fAborting := true;
exit;
end;
if (Width = 0) or (Height = 0) then
exit;
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo();
IEMetafileCalcDestSize(meta.Width, meta.Height, Width, Height, dstWidth, dstHeight);
meta.Width := dstWidth;
meta.Height := dstHeight;
dib := TIEDibBitmap.Create;
dibcanvas := TCanvas.Create;
try
dib.AllocateBits(meta.Width, meta.Height, 24);
dibcanvas.Handle := dib.HDC;
fParams.FileName := '';
if meta.Enhanced then
fParams.FileType := ioEMF
else
fParams.FileType := ioWMF;
fParams.BitsPerSample := 8;
fParams.SamplesPerPixel := 3;
fParams.Width := dib.Width;
fParams.Height := dib.Height;
fParams.ImageCount := 1;
fParams.OriginalWidth := dib.Width;
fParams.OriginalHeight := dib.Height;
fParams.DpiX := IEGlobalSettings().DefaultDPIX;
fParams.DpiY := IEGlobalSettings().DefaultDPIY;
fParams.FreeColorMap;
dibCanvas.Brush.Color := GetReBackground;
dibcanvas.Brush.Style := bsSolid;
dibCanvas.FillRect(rect(0, 0, dib.Width, dib.Height));
dibCanvas.Draw(0, 0, meta);
fIEBitmap.CopyFromTDibBitmap(dib);
finally
FreeAndNil(dibcanvas);
FreeAndNil(dib);
end;
// alpha channel
fIEBitmap.RemoveAlphaChannel();
if WithAlpha then
begin
dib := TIEDibBitmap.Create;
dibcanvas := TCanvas.Create;
try
dib.AllocateBits(meta.Width, meta.Height, 24);
dibcanvas.Handle := dib.HDC;
dibCanvas.Brush.Color := $00010203; // transparent color (we hope it isn't in the image)
dibcanvas.Brush.Style := bsSolid;
dibCanvas.FillRect(rect(0, 0, dib.Width, dib.Height));
dibcanvas.Draw(0, 0, meta);
w := fIEBitmap.AlphaChannel.Width;
h := fIEBitmap.AlphaChannel.Height;
for y := 0 to h - 1 do
begin
px := fIEBitmap.AlphaChannel.Scanline[y];
p_rgb := dib.Scanline[y];
for x := 0 to w - 1 do
begin
with p_rgb^ do
if (b = $01) and (g = $02) and (r = $03) then
px^ := 0
else
px^ := 255;
inc(p_rgb);
inc(px);
end;
end;
fIEBitmap.AlphaChannel.SyncFull;
finally
FreeAndNil(dibcanvas);
FreeAndNil(dib);
end;
end;
Result := Not fAborting;
Update();
ResetModified();
end;
function TImageEnIO.ImportMetafile(meta: TIEMetafile; Width: Integer; Height: Integer; WithAlpha: Boolean): Boolean;
var
i, j: integer;
px: PRGBA;
dstWidth, dstHeight: integer;
bmp: TIEBitmap;
bg: TRGB;
begin
Result := False;
fAborting := false;
if (meta.Width = 0) or (meta.Height = 0) then
begin
fAborting := true;
exit;
end;
if (Width = 0) or (Height = 0) then
exit;
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo();
IEMetafileCalcDestSize(meta.Width, meta.Height, Width, Height, dstWidth, dstHeight);
bmp := TIEBitmap.Create(dstWidth, dstHeight, ie32RGB);
try
fParams.FileName := '';
if meta.IsWmf() then
fParams.FileType := ioWMF
else
fParams.FileType := ioEMF;
fParams.BitsPerSample := 8;
fParams.SamplesPerPixel := 3;
fParams.Width := dstWidth;
fParams.Height := dstHeight;
fParams.ImageCount := 1;
fParams.OriginalWidth := dstWidth;
fParams.OriginalHeight := dstHeight;
fParams.DpiX := IEGlobalSettings().DefaultDPIX;
fParams.DpiY := IEGlobalSettings().DefaultDPIY;
fParams.FreeColorMap;
bg := TColor2TRGB(GetReBackground());
if meta.IsWmf() or meta.IsEmf() then
begin
// handle alpha channel manually
bmp.Fill(CreateRGBA(0, 1, 2, 0)); // uses (0,1,2) as key color for transparent background
bmp.IECanvas.Draw(meta, 0, 0, dstWidth, dstHeight);
for i := 0 to dstHeight - 1 do
begin
px := bmp.ScanLine[i];
for j := 0 to dstWidth - 1 do
begin
if (px^.r = 0) and (px^.g = 1) and (px^.b = 2) then
begin
// this is the transparent background
px^.r := bg.r;
px^.g := bg.g;
px^.b := bg.b;
px^.a := 0;
end
else
begin
// this is the foreground
px^.a := 255;
end;
inc(px);
end;
end;
end
else
begin
// direct draw on BGRA bitmap
bmp.Fill(CreateRGBA(bg.r, bg.g, bg.b, 0));
bmp.IECanvas.Draw(meta, 0, 0, dstWidth, dstHeight);
end;
if WithAlpha then
bmp.SynchronizeRGBA(true)
else
bmp.RemoveAlphaChannel();
bmp.PixelFormat := ie24RGB;
fIEBitmap.Assign(bmp);
finally
bmp.Free();
end;
Result := Not fAborting;
Update();
ResetModified();
end;
procedure TImageEnIO.ParamsFromMetaFile(stream: TStream);
var
meta: TMetaFile;
begin
meta := TMetaFile.Create;
meta.LoadFromStream(stream);
try
fParams.FileName := '';
if meta.Enhanced then
fParams.FileType := ioEMF
else
fParams.FileType := ioWMF;
fParams.BitsPerSample := 8;
fParams.SamplesPerPixel := 3;
fParams.Width := meta.Width;
fParams.Height := meta.Height;
fParams.OriginalWidth := meta.Width;
fParams.OriginalHeight := meta.Height;
fParams.DpiX := IEGlobalSettings().DefaultDPIX;
fParams.DpiY := IEGlobalSettings().DefaultDPIY;
fParams.FreeColorMap;
finally
meta.Free;
end;
end;
function TImageEnIO.ImportMetafile(const FileName: WideString; Width, Height: integer; WithAlpha: boolean): Boolean;
var
meta: TIEMetafile;
begin
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateImportMetaFileRetBool(self, ImportMetaFile, FileName, Width, Height, WithAlpha);
Result := True;
exit;
end;
try
meta := TIEMetaFile.Create(FileName);
try
Result := ImportMetaFile(meta, Width, Height, WithAlpha);
fParams.FileName := FileName;
finally
FreeAndNil(meta);
end;
finally
DoFinishWork;
end;
end;
function TImageEnIO.ImportMetafile(Stream: TStream; Width: Integer = -1; Height: Integer = -1; WithAlpha: boolean = True): Boolean;
var
meta: TIEMetafile;
begin
try
meta := TIEMetaFile.Create(Stream);
try
Result := ImportMetaFile(meta, Width, Height, WithAlpha);
fParams.FileName := '';
finally
FreeAndNil(meta);
end;
finally
DoFinishWork;
end;
end;
function TImageEnIO.ParamsFromFileOrStream(const FileName: WideString; Stream: TStream; Format: TIOFileType): Boolean;
var
idummy: integer;
fpi: TIEFileFormatInfo;
fs: TIEWideFileStream;
NullProgress: TProgressRec;
tempAlphaChannel: TIEMask;
BufStream: TIEBufferedReadStream;
bIsFile: Boolean;
begin
Result := True;
fs := nil;
BufStream := nil;
bIsFile := Stream = nil;
try
if Format = ioUnknown then
try
if bIsFile then
Format := FindFileFormat( FileName, ffFallbackToExtension )
else
Format := FindStreamFormat(Stream);
except
// Unexpected error
end;
if Format = ioUnknown then
begin
fParams.FileType := ioUnknown;
DoFinishWork;
Result := False;
exit;
end;
try
fParams.FileType := Format;
fParams.ResetInfo;
fAborting := true; // So that fAborting is True if the file is not found
NullProgress := NullProgressRec( fAborting, False );
tempAlphaChannel := nil;
if bIsFile then
begin
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
BufStream := TIEBufferedReadStream.Create(fs, 8192, IEGlobalSettings().UseRelativeStreams);
end
else
begin
BufStream := TIEBufferedReadStream.Create(Stream, 8192, IEGlobalSettings().UseRelativeStreams);
end;
fAborting := false;
case fParams.FileType of
ioTIFF: TIFFReadStream(fIEBitmap, BufStream, idummy, fParams, NullProgress, True, tempAlphaChannel, true, true, false, false);
ioGIF: ReadGIFStream(BufStream, fIEBitmap, idummy, fParams, NullProgress, True, tempAlphaChannel, true);
ioJPEG: ReadJpegStream(BufStream, nil, fIEBitmap, fParams, NullProgress, True, false, true, false, true, true, -1, fParams.IsNativePixelFormat);
ioICO: ICOReadStream(BufStream, fIEBitmap, fParams, True, NullProgress, tempAlphaChannel, true);
ioCUR: CURReadStream(BufStream, fIEBitmap, fParams, True, NullProgress, tempAlphaChannel, true);
ioPCX: ReadPcxStream(BufStream, fIEBitmap, fParams, BufStream.size, NullProgress, True);
ioDCX: IEDCXReadStream(BufStream, fIEBitmap, fParams, NullProgress, True);
ioBMP: BMPReadStream(BufStream, fIEBitmap, BufStream.size, fParams, NullProgress, True, false, tempAlphaChannel, true);
{$IFDEF IEINCLUDEPNG}
ioPNG: ReadPNGStream(BufStream, fIEBitmap, fParams, NullProgress, true);
{$ENDIF}
{$ifdef IEINCLUDEDICOM}
ioDICOM: IEDicomRead(BufStream, fParams, fIEBitmap, NullProgress, true);
{$endif}
ioTGA: ReadTGAStream(BufStream, fIEBitmap, fParams, NullProgress, true, tempAlphaChannel, true);
ioPXM: PXMReadStream(BufStream, fIEBitmap, fParams, NullProgress, true);
ioWBMP: WBMPReadStream(BufStream, fIEBitmap, fParams, NullProgress, true);
{$IFDEF IEINCLUDEJPEG2000}
ioJP2: J2KReadStream(BufStream, fIEBitmap, fParams, NullProgress, true);
ioJ2K: J2KReadStream(BufStream, fIEBitmap, fParams, NullProgress, true);
{$ENDIF}
{$ifdef IEINCLUDERAWFORMATS}
ioRAW: IEReadCameraRAWStream(BufStream, fIEBitmap, fParams, NullProgress, true);
{$endif}
{$ifdef IEINCLUDEPSD}
ioPSD: IEReadPSD(BufStream, nil, fParams, NullProgress, false, nil);
{$endif}
{$ifdef IEINCLUDEWIC}
ioHDP: if bIsFile then
IEHDPRead(BufStream, fIEBitmap, fParams, NullProgress, true)
else
IEHDPRead(BufStream, nil, fParams, NullProgress, false);
{$endif}
ioWMF, ioEMF: ParamsFromMetaFile(BufStream);
ioIEN: ParamsFromStreamIEN(BufStream);
else
begin
fpi := IEFileFormatGetInfo(fParams.FileType);
if assigned( fpi ) and assigned( fpi.ReadFunction ) then
fpi.ReadFunction(BufStream, fIEBitmap, fParams, NullProgress, true)
else
Result := False;
end;
end;
except
on e:Exception do
begin
if e.message = IERS_IEVISIONNOTFOUND then
raise;
fParams.FileType := ioUnknown;
Result := False;
end;
end;
if fAborting then
begin
fParams.FileType := ioUnknown;
Result := False;
end;
if bIsFile then
fParams.FileName := FileName;
finally
FreeAndNil( BufStream );
FreeAndNil( fs );
end;
DoFinishWork;
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function TImageEnIO.ParamsFromFileFormat(const FileName: WideString; Format: TIOFileType): Boolean;
begin
Result := ParamsFromFileOrStream( FileName, nil, Format );
end;
{$endif}
{!!
<FS>TImageEnIO.ParamsFromFile
<FM>Declaration<FC>
function ParamsFromFile(const FileName: WideString; bUseExtension: Boolean = False): Boolean; overload;
function ParamsFromFile(const FileName: WideString; Format: <A TIOFileType>): Boolean; overload;
<FM>Description<FN>
Reads the <L TImageEnIO.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 BMP file, but we will examine the content to be sure)
ImageEnView1.IO.ParamsFromFile( 'C:\alfa.bmp' );
Label1.Caption := 'alfa.bmp has ' + inttostr(ImageEnView1.IO.Params.BitsPerSample) + ' bits per sample';
// Load the parameters of a BMP
ImageEnView1.IO.ParamsFromFile( 'C:\alfa.bmp', ioBMP );
Label1.Caption := 'alfa.bmp has ' + inttostr(ImageEnView1.IO.Params.BitsPerSample) + ' bits per sample';
// Load the parameters of a file. It will be assumed to a BMP because of the file extension
ImageEnView1.IO.ParamsFromFile( 'C:\alfa.bmp', True );
Label1.Caption := 'alfa.bmp has ' + inttostr(ImageEnView1.IO.Params.BitsPerSample) + ' bits per sample';
// Show the EXIF date of an image
IO := TImageEnIO.Create( nil );
try
IO.ParamsFromFile( sFilename );
ShowMessage( DateTimeToStr(( IO.IOParams.EXIF_DateTimeOriginal2 ));
finally
IO.Free;
end;
!!}
function TImageEnIO.ParamsFromFile(const FileName: WideString; Format: TIOFileType): Boolean;
begin
Result := ParamsFromFileOrStream( FileName, nil, Format );
end;
function TImageEnIO.ParamsFromFile(const FileName: WideString; bUseExtension: Boolean = False): Boolean;
var
Format: TIOFileType;
begin
Format := ioUnknown;
if bUseExtension then
Format := IEFilenameToFileFormat( FileName );
Result := ParamsFromFileOrStream( FileName, nil, Format );
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-16)
function TImageEnIO.ParamsFromStreamFormat(Stream: TStream; format: TIOFileType): Boolean;
begin
Result := ParamsFromFileOrStream( '', Stream, Format );
end;
{$endif}
{!!
<FS>TImageEnIO.ParamsFromStream
<FM>Declaration<FC>
function ParamsFromStream(Stream: TStream; Format: <A TIOFileType> = ioUnknown): Boolean;
<FM>Description<FN>
Reads the <L TImageEnIO.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 TImageEnIO.ParamsFromStream(Stream: TStream; Format: TIOFileType = ioUnknown): Boolean;
begin
Result := ParamsFromFileOrStream( '', Stream, Format );
end;
{!!
<FS>TImageEnIO.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 TImageEnIO.LoadFromBuffer>
<FM>Example<FC>
ImageEnView1.IO.ParamsFromBuffer(mybuffer, mybufferlength, ioJPEG);
!!}
function TImageEnIO.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;
function TImageEnIO.SyncLoadFromStreamPXM(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
PXMReadStream(Stream, fIEBitmap, fParams, Progress, false);
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioPXM;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFilePXM
<FM>Declaration<FC>
function LoadFromFilePXM(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a PBM, PGM or PPM file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not a recognized file type (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
!!}
function TImageEnIO.LoadFromFilePXM(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFilePXM, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamPXM( fs );
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamPXM
<FM>Declaration<FC>
function LoadFromStreamPXM(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a PBM, PGM or PPM file. The result will be false if an error is encountered, e.g. the file in the stream is not a recognized format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamPXM(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamPXM, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamPXM( Stream );
end;
end;
{!!
<FS>TImageEnIO.SaveToFilePXM
<FM>Declaration<FC>
procedure SaveToFilePXM(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in PBM, PGM or PPM format.
<FC>FileName<FN> is the file name including extension.
If the PBM (Portable Bitmap) contains only 1 bpp images (black/white), then the values must be Params.BitsPerPixel = 1 and Params.SamplesPerPixel = 1.
If the PGM (Portable Graymap) contains only 8 bpp images (gray scale), then the values must be Params.BitsPerPixel = 8 and Params.SamplesPerPixel = 1.
If the PPM (Portable Pixmap) contains only 24 bpp images (true color), then the values must be Params.BitsPerPixel = 8 and Params.SamplesPerPixel = 3.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnIO.SaveToFilePXM(const FileName: WideString);
var
Progress: TProgressRec;
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFilePXM, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) and (fIEBitmap.PixelFormat<>ie48RGB) then
fIEBitmap.PixelFormat := ie24RGB;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
PXMWriteStream(fs, fIEBitmap, fParams, Progress);
fParams.FileName := FileName;
fParams.FileType := ioPXM;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamPXM
<FM>Declaration<FC>
procedure SaveToStreamPXM(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in PBM, PGM or PPM format.
If the PBM (Portable Bitmap) contains only 1 bpp images (black/white), then the values must be Params.BitsPerPixel=1 and Params.SamplesPerPixel=1.
If the PGM (Portable Graymap) contains only 8 bpp images (gray scale), then the values must be Params.BitsPerPixel=8 and Params.SamplesPerPixel=1.
If the PPM (Portable Pixmap) contains only 24 bpp images (true color), then the values must be Params.BitsPerPixel=8 and Params.SamplesPerPixel=3.
!!}
procedure TImageEnIO.SaveToStreamPXM(Stream: TStream);
var
Progress: TProgressRec;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamPXM, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
PXMWriteStream(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
procedure PrintImagePos_func1(x, y: dword; pixel: pointer; UserData: pointer);
begin
with PRGB(pixel)^ do
begin
r := pbytearray(UserData)^[r];
g := pbytearray(UserData)^[g];
b := pbytearray(UserData)^[b];
end;
end;
// Creates fPrintBitmap, optionally drawing annotations and layers
// Note: must free fPrintBitmap
procedure TImageEnIO.GeneratePrintBitmap(PrintAnnotations, PrintLayers: Boolean);
const
Antialias_Annot = True; // Objects are merged with anti-aliasing
var
iev: TImageEnView;
wasBG: TColor;
begin
FreeAndNil( fPrintBitmap );
fPrintBitmap := TIEBitmap.Create();
iev := nil;
if assigned( fImageEnView ) and ( fImageEnView is TImageEnView ) then
iev := TImageEnView( fImageEnView );
// Layers
if PrintLayers and assigned( iev ) and ( iev.LayersCount > 1 ) then
begin
// Ensure transparency is printed white
wasBG := iev.Background;
iev.Background := clWhite;
iev.LayersSaveMergedTo( fPrintBitmap );
iev.Background := wasBG;
end
else
fPrintBitmap.Assign( fIEBitmap );
// Annotations
if PrintAnnotations then
begin
{$ifdef IEINCLUDEIMAGINGANNOT}
if GetParams.ImagingAnnot.ObjectsCount > 0 then
GetParams.ImagingAnnot.DrawToBitmap( fPrintBitmap, Antialias_Annot )
else
{$endif}
if GetParams.ImageEnAnnot.IsEmpty = False then
GetParams.ImageEnAnnot.DrawToBitmap( fPrintBitmap, Antialias_Annot );
end;
end;
// dpix, dpiy cannot be 0
procedure TImageEnIO.PrintImagePosEx(PrintBMP: TIEBitmap; PrtCanvas: TCanvas; dpix, dpiy: integer; x, y: double; Width, Height: double; GammaCorrection: double);
var
px, py, pWidth, pHeight: integer;
zz: double;
begin
IEPrintLogWrite('TImageEnIO.PrintImagePosEx: begin');
px := trunc(x * dpix);
py := trunc(y * dpiy);
pWidth := trunc(Width * dpix);
pHeight := trunc(Height * dpiy);
zz := pWidth / PrintBMP.Width;
//
if ( fPrintingFilterOnSubsampling <> rfNone ) and ( zz < 1 ) then
begin
IEPrintLogWrite('TImageEnIO.PrintImagePosEx: calling RenderToCanvas with subsampling filter');
PrintBMP.RenderToCanvas(PrtCanvas, px, py, pWidth, pHeight, fPrintingFilterOnSubsampling, GammaCorrection);
end
else
begin
IEPrintLogWrite('TImageEnIO.PrintImagePosEx: calling RenderToCanvas without subsampling filter');
PrintBMP.RenderToCanvas(PrtCanvas, px, py, pWidth, pHeight, rfNone, GammaCorrection);
end;
IEPrintLogWrite('TImageEnIO.PrintImagePosEx: end');
end;
{!!
<FS>TImageEnIO.PrintImagePos
<FM>Declaration<FC>
procedure PrintImagePos(PrtCanvas: TCanvas; x, y: double; Width, Height: double; GammaCorrection: double = 1; PrintAnnotations: Boolean = False; PrintLayers: Boolean = False);
<FM>Description<FN>
Prints the current image at a specified absolute position and size.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>PrtCanvas<FN></C> <C>The canvas to bring to. Specify nil to use Printer.Canvas</C> </R>
<R> <C>FC>x, y<FN></C> <C> Top-left starting point in inches </C> </R>
<R> <C>FC>Width, Height<FN></C> <C> Printed image size in inches. </C> </R>
<R> <C><FC>GammaCorrection<FN></C> <C>The gamma correction value (Specify 1.0 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>
<R> <C>FC>PrintLayers<FN></C> <C> If true and the attached <A TImageEnView> image contains <L TImageEnView.Layers>multiple layers</L>, they will be printed. If False, only the image (i.e. current layer) is printed </C> </R>
</TABLE>
<FM>Example<FC>
// Add Printers unit to your uses clause...
uses
Printers;
// print the image two inches from the top and left of the page, and at a width and height of 10 inches (the image will be stretched)
Printer.BeginDoc;
ImageEnView1.IO.PrintImagePos( Printer.Canvas, 2, 2, 10, 10 );
Printer.EndDoc;
!!}
// if width = 0 and/or height = 0, PrintImagePos autocalculates for normal size
procedure TImageEnIO.PrintImagePos(PrtCanvas: TCanvas; x, y: double; Width, Height: double; GammaCorrection: double; PrintAnnotations: Boolean; PrintLayers: Boolean);
var
dpix, dpiy: integer;
begin
if not MakeConsistentBitmap([]) then
exit;
if PrtCanvas = nil then
PrtCanvas := Printer.Canvas;
GeneratePrintBitmap( PrintAnnotations, PrintLayers );
dpix := GetDeviceCaps(PrtCanvas.Handle, LOGPIXELSX);
dpiy := GetDeviceCaps(PrtCanvas.Handle, LOGPIXELSY);
PrintImagePosEx( fPrintBitmap, PrtCanvas, dpix, dpiy, x, y, Width, Height, GammaCorrection );
FreeAndNil( fPrintBitmap );
end;
// dpix, dpiy are dpi of destination device, cannot be 0
// bPrinting = True when printing, False when previewing
procedure TImageEnIO.PrintImageEx(PrintBMP: TIEBitmap; PrtCanvas: TCanvas; dpix, dpiy: integer; pagewidth, pageheight: double; MarginLeft, MarginTop, MarginRight, MarginBottom: double; VerticalPos: TIEVerticalPos; HorizontalPos: TIEHorizontalPos; Size: TIESize; SpecWidth, SpecHeight: double; GammaCorrection: double; bPrinting: Boolean = True);
var
x, y, width, height: double;
z: double;
bitmapwidth, bitmapheight: double; // in inches
imgdpix, imgdpiy: integer;
PageCountX, PageCountY: Integer;
aPrintBmp : TIEBitmap;
PrintX, PrintY, OutX, OutY, OutWidth, OutHeight: Double;
ipx, ipy: Integer;
begin
IEPrintLogWrite('TImageEnIO.PrintImageEx: begin');
if PrtCanvas = nil then
PrtCanvas := Printer.Canvas;
if dpix = -1 then
dpix := GetDeviceCaps(PrtCanvas.Handle, LOGPIXELSX);
if dpiy = -1 then
dpiy := GetDeviceCaps(PrtCanvas.Handle, LOGPIXELSY);
if pagewidth = -1 then
pagewidth := GetDeviceCaps(PrtCanvas.Handle, HORZRES) / dpix;
if pageheight = -1 then
pageheight := GetDeviceCaps(PrtCanvas.Handle, VERTRES) / dpiy;
imgdpix := Params.DpiX;
if imgdpix <= 1 then
imgdpix := dpix;
imgdpiy := Params.DpiY;
if imgdpiy <= 1 then
imgdpiy := dpiy;
IEPrintLogWrite('TImageEnIO.PrintImageEx: setting page sizes');
pagewidth := pagewidth - (MarginLeft + MarginRight);
pageheight := pageheight - (MarginTop + MarginBottom);
width := 0;
height := 0;
x := 0;
y := 0;
z := 1;
PageCountX := 1;
PageCountY := 1;
case Size of
iesNormal:
begin
width := PrintBMP.Width / imgdpix;
height := PrintBMP.Height / imgdpiy;
end;
iesFitToPage:
begin
bitmapwidth := PrintBMP.Width / dpix;
bitmapheight := PrintBMP.Height / dpiy;
z := dmin(pagewidth / bitmapwidth, pageheight / bitmapheight);
width := bitmapwidth * z;
height := bitmapheight * z;
end;
iesFitToPageStretch:
begin
width := pagewidth;
height := pageheight;
end;
iesFillPage:
begin
bitmapwidth := PrintBMP.Width / dpix;
bitmapheight := PrintBMP.Height / dpiy;
z := dmax(pagewidth / bitmapwidth, pageheight / bitmapheight);
width := bitmapwidth * z;
height := bitmapheight * z;
end;
iesSpecifiedSize:
begin
width := SpecWidth;
height := SpecHeight;
end;
iesMultiplePages:
begin
bitmapwidth := PrintBMP.Width / dpix;
bitmapheight := PrintBMP.Height / dpiy;
z := dmin( Trunc( SpecWidth ) * PageWidth / bitmapwidth, Trunc( SpecHeight ) * pageheight / bitmapheight);
width := bitmapwidth * z;
height := bitmapheight * z;
PageCountX := round( Width / PageWidth + 0.49999 ); // Not ceil(). We don't want that much accuracy
PageCountY := round( Height / PageHeight + 0.49999 );
end;
end;
case HorizontalPos of
iehpLEFT:
x := 0;
iehpCENTER:
x := (PageCountX * pagewidth - width) / 2;
iehpRIGHT:
x := PageCountX * pagewidth - width;
end;
case VerticalPos of
ievpTOP:
y := 0;
ievpCenter:
y := (PageCountY * pageheight - height) / 2;
ievpBOTTOM:
y := PageCountY * pageheight - height;
end;
if Size <> iesMultiplePages then
PrintImagePosEx( PrintBMP, PrtCanvas, dpix, dpiy, MarginLeft + x, MarginTop + y, width, height, GammaCorrection )
else
begin
aPrintBmp := TIEBitmap.create;
aPrintBmp.PixelFormat := PrintBMP.PixelFormat;
try
OutY := 0;
for ipy := 0 to PageCountY - 1 do
begin
if ipy = 0 then
begin
PrintY := Y;
OutHeight := PageHeight - Y;
end
else
begin
PrintY := 0;
OutHeight := PageHeight;
end;
if OutY + OutHeight > Height then
OutHeight := Height - OutY;
OutX := 0;
for ipx := 0 to PageCountX - 1 do
begin
if ipx = 0 then
begin
PrintX := X;
OutWidth := PageWidth - X;
end
else
begin
PrintX := 0;
OutWidth := PageWidth;
end;
if OutX + OutWidth > Width then
OutWidth := Width - OutX;
aPrintBmp.Width := Trunc( OutWidth * dpix / z );
aPrintBmp.Height := Trunc( OutHeight * dpiy / z );
PrintBMP.CopyRectTo( aPrintBmp, Trunc( OutX * dpix / z ), Trunc( OutY * dpiy / z ), 0, 0, aPrintBmp.Width, aPrintBmp.Height, false );
if bPrinting and ( ipx + ipy > 0 ) then
Printer.NewPage;
PrintImagePosEx( aPrintBmp, PrtCanvas, dpix, dpiy, MarginLeft + PrintX, MarginTop + PrintY, OutWidth, OutHeight, GammaCorrection );
OutX := OutX + OutWidth;
if bPrinting = False then
exit; // Just show first page
end;
OutY := OutY + OutHeight;
end;
finally
aPrintBmp.Free;
end;
end;
IEPrintLogWrite('TImageEnIO.PrintImageEx: end');
end;
{!!
<FS>TImageEnIO.PrintImage
<FM>Declaration<FC>
procedure PrintImage(PrtCanvas: TCanvas = nil; MarginLeft: double = 1; MarginTop: double = 1; MarginRight: double = 1; MarginBottom: double = 1; VerticalPos: <A TIEVerticalPos> = ievpCenter; HorizontalPos: <A TIEHorizontalPos> = iehpCENTER; Size: <A TIESize> = iesFitToPage; SpecWidth: double = 0; SpecHeight: double = 0; GammaCorrection: double = 1; PrintAnnotations: Boolean = False; PrintLayers: Boolean = False);
<FM>Description<FN>
Print the current image by specifying margins, vertical position, horizontal position and size.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>PrtCanvas<FN></C> <C>The canvas to bring to. Specify nil to use 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>How the image is vertically aligned on the page</C> </R>
<R> <C><FC>HorizontalPos<FN></C> <C>How the image horizontally aligned on the page</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>The gamma correction value (Specify 1.0 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>
<R> <C>FC>PrintLayers<FN></C> <C> If true and the attached <A TImageEnView> image contains <L TImageEnView.Layers>multiple layers</L>, they will be printed. If False, only the image (i.e. current layer) is printed </C> </R>
</TABLE>
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\FullApps\PhotoEn3\ImageEx.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// Add Printers unit to your uses clause...
uses
Printers;
// Print the image in the center of the page at the original size
Printer.BeginDoc;
ImageEnView1.IO.PrintImage( Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesNormal );
Printer.EndDoc;
// Print the image in the center of the page stretched to page dimensions (respecting the proportions)
Printer.BeginDoc;
ImageEnView1.IO.PrintImage( Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesFitToPage );
Printer.EndDoc;
// Print the image as a poster, four pages wide and six pages high
Printer.BeginDoc;
ImageEnView1.IO.PrintImage( Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesMultiplePages, 4, 6, 1 );
Printer.EndDoc;
// Print all pages of a TIFF
Printer.BeginDoc;
for I := 0 to ImageEnView1.IO.Params.ImageCount - 1 do
begin
ImageEnView1.IO.Params.ImageIndex := I;
ImageEnView1.IO.LoadFromFile( 'C:\input.tif' );
ImageEnView1.IO.PrintImage();
end;
Printer.EndDoc;
// Print the image in the center with layers
Printer.BeginDoc;
ImageEnView1.IO.PrintImage( Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesNormal, 0, 0, 1, False, True );
Printer.EndDoc;
!!}
procedure TImageEnIO.PrintImage(PrtCanvas: TCanvas; MarginLeft, MarginTop, MarginRight, MarginBottom: double; VerticalPos: TIEVerticalPos; HorizontalPos: TIEHorizontalPos; Size: TIESize; SpecWidth, SpecHeight: double; GammaCorrection: double; PrintAnnotations: Boolean; PrintLayers: Boolean);
begin
IEPrintLogWrite('TImageEnIO.PrintImage: begin');
if not MakeConsistentBitmap([]) then
exit;
if assigned(fTImage) then
begin
if (fTImage.Picture.Bitmap.PixelFormat <> pf1bit) and (fTImage.Picture.Bitmap.PixelFormat <> pf24bit) then
fTImage.Picture.Bitmap.PixelFormat := pf24bit;
end;
GeneratePrintBitmap( PrintAnnotations, PrintLayers );
PrintImageEx( fPrintBitmap, PrtCanvas, -1, -1, -1, -1, MarginLeft, MarginTop, MarginRight, MarginBottom, VerticalPos, HorizontalPos, Size, SpecWidth, SpecHeight, GammaCorrection, True);
FreeAndNil( fPrintBitmap );
IEPrintLogWrite('TImageEnIO.PrintImage: end');
end;
{!!
<FS>TImageEnIO.PreviewPrintImage
<FM>Declaration<FC>
procedure PreviewPrintImage(DestBitmap: TBitmap; MaxBitmapWidth: Integer; MaxBitmapHeight: Integer; PrinterObj: TPrinter = nil; MarginLeft: Double = 1; MarginTop: Double = 1; MarginRight: Double = 1; MarginBottom: Double = 1; VerticalPos: <A TIEVerticalPos> = ievpCenter; HorizontalPos: <A TIEHorizontalPos> = iehpCenter; Size: <A TIESize> = iesFitToPage; SpecWidth: Double = 0; SpecHeight: Double = 0; GammaCorrection: Double = 1);
<FM>Description<FN>
Draws a preview of the printing of the current image by specifying margins, vertical position, horizontal position and size.
It also paints a rectangle over the image to show the margin limits.
<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>MarginLeft<FN></C> <C>Left page margin in inches. Specying zero causes no margin to be used.</C> </R>
<R> <C><FC>MarginTop<FN></C> <C>Top page margin in inches. Specying zero causes no margin to be used.</C> </R>
<R> <C><FC>MarginRight<FN></C> <C>Right page margin in inches. Specying zero causes no margin to be used.</C> </R>
<R> <C><FC>MarginBottom<FN></C> <C>Bottom page margin in inches. Specying zero causes no margin to be used.</C> </R>
<R> <C><FC>VerticalPos<FN></C> <C>Determines how the image vertically aligns within the page.</C> </R>
<R> <C><FC>HorizontalPos<FN></C> <C>Determines how the image horizontally aligns within the page.</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>The gamma correction value, use 1.0 to disable gamma correction.</C> </R>
</TABLE>
<FM>Example<FC>
// Paint and display the preview in ImageEnView2 component.
ImageEnView1.IO.PreviewPrintImage(ImageEnView2.Bitmap, ImageEnView2.Width, ImageEnView2.Height, Printer, 0, 0, 0, 0, ievpCenter, iehpCenter, iesFitToPage , 0 , 0 , 1);
ImageEnView2.Update;
!!}
procedure TImageEnIO.PreviewPrintImage(DestBitmap: TBitmap; MaxBitmapWidth, MaxBitmapHeight: integer; PrinterObj: TPrinter;
MarginLeft, MarginTop, MarginRight, MarginBottom: double;
VerticalPos: TIEVerticalPos; HorizontalPos: TIEHorizontalPos; Size: TIESize;
SpecWidth, SpecHeight: double; GammaCorrection: double);
begin
if not MakeConsistentBitmap([]) then
exit;
if assigned(fTImage) then
begin
if (fTImage.Picture.Bitmap.PixelFormat <> pf1bit) and (fTImage.Picture.Bitmap.PixelFormat <> pf24bit) then
fTImage.Picture.Bitmap.PixelFormat := pf24bit;
end;
PreviewPrintImageEx( fIEBitmap, DestBitmap, MaxBitmapWidth, MaxBitmapHeight, PrinterObj,
MarginLeft, MarginTop, MarginRight, MarginBottom,
VerticalPos, HorizontalPos, Size,
SpecWidth, SpecHeight, GammaCorrection );
end;
procedure TImageEnIO.PreviewPrintImageEx(PrintBMP: TIEBitmap; DestBitmap: TBitmap; MaxBitmapWidth, MaxBitmapHeight: integer; PrinterObj: TPrinter;
MarginLeft, MarginTop, MarginRight, MarginBottom: double;
VerticalPos: TIEVerticalPos; HorizontalPos: TIEHorizontalPos; Size: TIESize;
SpecWidth, SpecHeight: double; GammaCorrection: double);
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 (dpix <= 0) or (dpiy <= 0) then
exit;
PrintImageEx( PrintBMP, DestBitmap.Canvas, dpix, dpiy, PageWidth / dpix, PageHeight / dpiy, MarginLeft, MarginTop, MarginRight, MarginBottom, VerticalPos, HorizontalPos, Size, SpecWidth, SpecHeight, GammaCorrection, False);
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>TImageEnIO.InjectJpegIPTC
<FM>Declaration<FC>
function InjectJpegIPTC(const FileName: WideString): Boolean;
<FM>Description<FN>
Replaces the IPTC information in the specified JPEG file with the current IPTC (in <A TImageEnIO.Params>) without loading or modifying the original image.
The method returns False if the operation could not be performed.
<FM>Example<FC>
// copy the IPTC info (not the image) from file one.jpg to the inside of file two.jpg, without loading any images
ImageEnView1.IO.ParamsFromFile('D:\one.jpg');
ImageEnView1.IO.InjectJpegIPTC('D:\two.jpg');
// removes IPTC info from image.jpg
ImageEnView1.IO.Params.IPTC_Info.Clear;
ImageEnView1.IO.InjectJpegIPTC('D:\image.jpg');
!!}
function TImageEnIO.InjectJpegIPTC(const FileName: WideString): boolean;
var
fr: TMemoryStream;
fm: TMemoryStream;
Progress: TProgressRec;
begin
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
fr := TMemorystream.Create;
fm := TMemoryStream.Create;
try
fr.LoadFromFile(FileName);
fr.Position := 0;
fm.Size := fr.Size;
result := IEJpegInjectIPTC(fr, fm, fParams.IPTC_Info, Progress);
fm.Size := fm.Position;
if result then
fm.SaveToFile(FileName);
finally
FreeAndNil(fr);
FreeAndNil(fm);
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.InjectJpegIPTCStream
<FM>Declaration<FC>
function InjectJpegIPTCStream(InputStream, OutputStream: TStream): Boolean;
<FM>Description<FN>
Replaces the IPTC information of the JPEG file in the InputStream stream with the current IPTC (in <A TImageEnIO.Params>) without loading or modifying the original image.
<FC>OutputStream<FN> contains the modified stream.
The method returns False if the operation could not be performed.
!!}
function TImageEnIO.InjectJpegIPTCStream(InputStream, OutputStream: TStream): boolean;
var
Progress: TProgressRec;
begin
Progress.fOnProgress := nil;
result := IEJpegInjectIPTC(InputStream, OutputStream, fParams.IPTC_Info, Progress);
end;
{!!
<FS>TImageEnIO.InjectJpegEXIF
<FM>Declaration<FC>
function InjectJpegEXIF(const FileName: WideString): Boolean;
<FM>Description<FN>
Replaces the EXIF information in the specified JPEG file with the current EXIF (in <A TImageEnIO.Params>) without loading or modifying the original image.
The method returns False if the operation could not be performed.
<FM>Example<FC>
// copy the EXIF info (not the image) from file one.jpg inside two.jpg, without loading any image
ImageEnView1.IO.ParamsFromFile('D:\one.jpg');
ImageEnView1.IO.InjectJpegEXIF('D:\two.jpg');
// removes EXIF info from image.jpg
ImageEnView1.IO.Params.EXIF_HasExifData := false;
ImageEnView1.IO.InjectJpegEXIF('D:\image.jpg');
!!}
function TImageEnIO.InjectJpegEXIF(const FileName: WideString): boolean;
var
fr: TMemoryStream;
fm: TMemoryStream;
Progress: TProgressRec;
begin
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
fr := TMemoryStream.Create;
fm := TMemoryStream.Create;
try
fr.LoadFromFile(FileName);
fr.Position := 0;
fm.Size := fr.Size;
result := IEJpegInjectEXIF(fr, fm, fParams, Progress);
fm.Size := fm.Position;
if result then
fm.SaveToFile(FileName);
finally
FreeAndNil(fr);
FreeAndNil(fm);
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.InjectJpegEXIFStream
<FM>Declaration<FC>
function InjectJpegEXIFStream(InputStream, OutputStream: TStream): Boolean;
<FM>Description<FN>
Replaces the EXIF information in the JPEG file in InputStream stream with the current EXIF (in <A TImageEnIO.Params>) without loading or modifying the original image.
<FC>OutputStream<FN> contains the modified stream.
The method returns False if the operation could not be performed.
!!}
function TImageEnIO.InjectJpegEXIFStream(InputStream, OutputStream: TStream): boolean;
var
Progress: TProgressRec;
begin
Progress.fOnProgress := nil;
result := IEJpegInjectEXIF(InputStream, OutputStream, fParams, Progress);
end;
{!!
<FS>TImageEnIO.InjectTIFFEXIF
<FM>Declaration<FC>
function InjectTIFFEXIF(const FileName: WideString; pageIndex: Integer): boolean;
function InjectTIFFEXIF(const InputFileName, OutputFileName: WideString; pageIndex: Integer): boolean;
function InjectTIFFEXIF(InputStream, OutputStream: TStream; pageIndex: Integer): boolean;
<FM>Description<FN>
Replaces the EXIF information in the specified TIFF or InputStream stream with the current EXIF (in <A TImageEnIO.Params>) without loading or modifying the original image.
<FC>OutputStream<FN> contains the modified stream.
The method returns <FC>false<FN> if the operation could not be performed.
Note: InjectTIFFEXIF works only with TIFF and Microsoft HD Photo file formats.
!!}
{$ifdef IEINCLUDETIFFHANDLER}
function TImageEnIO.InjectTIFFEXIF(const FileName: WideString; pageIndex: Integer): boolean;
begin
result := IEInjectTIFFEXIF(nil, nil, FileName, FileName, pageIndex, fParams);
end;
function TImageEnIO.InjectTIFFEXIF(const InputFileName, OutputFileName: WideString; pageIndex: Integer = 0): boolean;
begin
result := IEInjectTIFFEXIF(nil, nil, InputFileName, OutputFileName, pageIndex, fParams);
end;
function TImageEnIO.InjectTIFFEXIF(InputStream, OutputStream: TStream; pageIndex: Integer): boolean;
begin
result := IEInjectTIFFEXIF(InputStream, OutputStream, '', '', pageIndex, fParams);
end;
{$endif}
{$IFDEF IEINCLUDEOPENSAVEDIALOGS}
{!!
<FS>TImageEnIO.ExecuteOpenDialog
<FM>Declaration<FC>
function ExecuteOpenDialog(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) : WideString; overload;
function ExecuteOpenDialog(const Title : WideString; DefaultFilter : <A TIOFileType>; LimitToFileType : <A TIOFileType> = -1; AlwaysAnimate : boolean = False) : WideString; overload;
<FM>Description<FN>
Executes the open dialog allowing the user to browse for an image file. 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. 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</L>, plus "All Supported Types" and "All Files" (only relevant if Filter is not set). Default is -1</C> </R>
</TABLE>
Returns a null string ('') if the user clicks Cancel.
<FM>Examples<FC>
// Prompt to load a file into an ImageEnView
sFilename := ImageEnView1.IO.ExecuteOpenDialog;
if sFilename <> '' then
ImageEnView1.IO.LoadFromFile(sFileName);
// Prompt to load an image, defaulting to JPEG format (second overloaded method)
sFilename := ImageEnView1.IO.ExecuteOpenDialog('Select an Image', ioJPEG);
if sFilename <> '' then
ImageEnView1.IO.LoadFromFile(sFileName);
// Prompt to load an image, forcing GIF format (second overloaded method)
sFilename := ImageEnView1.IO.ExecuteOpenDialog('Select an Image', -1, ioGIF);
if sFilename <> '' then
ImageEnView1.IO.LoadFromFile(sFileName);
!!}
function TImageEnIO.ExecuteOpenDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False) : WideString;
begin
Result := ExecuteOpenDialog('', '', AlwaysAnimate, 0, '', Title, '', DefaultFilter, LimitToFileType);
end;
function TImageEnIO.ExecuteOpenDialog(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) : WideString;
var
fOpenImageEnDialog: TOpenImageEnDialog;
begin
result := '';
fOpenImageEnDialog := TOpenImageEnDialog.Create(self);
try
fOpenImageEnDialog.InitialDir := string(InitialDir);
fOpenImageEnDialog.FileName := InitialFileName;
{$IFDEF IEINCLUDEMULTIVIEW}
fOpenImageEnDialog.AlwaysAnimate := AlwaysAnimate;
{$ENDIF}
fOpenImageEnDialog.Options := fOpenImageEnDialog.Options + [OFENABLESIZING];
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 := string(ExtendedFilters);
if Title<>'' then
fOpenImageEnDialog.Title := string(Title);
if fOpenImageEnDialog.Execute then
begin
Params.ImageIndex := fOpenImageEnDialog.SelectedFrame;
result := fOpenImageEnDialog.FileNameW;
end;
finally
FreeAndNil(fOpenImageEnDialog);
end;
end;
{$ENDIF} // IEINCLUDEOPENSAVEDIALOGS
{$IFDEF IEINCLUDEOPENSAVEDIALOGS}
{!!
<FS>TImageEnIO.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) : WideString;overload;
function ExecuteSaveDialog(const Title : WideString; DefaultFilter : <A TIOFileType>; LimitToFileType : <A TIOFileType> = -1; AlwaysAnimate : boolean = False) : WideString; overload;
<FM>Description<FN>
Executes the save dialog allowing the user 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. 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 ImageEnView
sFilename := ImageEnView1.IO.ExecuteSaveDialog;
if sFilename <> '' then
ImageEnView1.IO.SaveToFile(sFileName)
// Prompt to save an image, defaulting to JPEG format (second overloaded method)
sFilename := ImageEnView1.IO.ExecuteOpenDialog('Save your Image', ioJPEG);
if sFilename <> '' then
ImageEnView1.IO.SaveToFile(sFileName)
// Prompt to save an image, forcing GIF format (second overloaded method)
sFilename := ImageEnView1.IO.ExecuteOpenDialog('Save your Image', -1, ioGIF);
if sFilename <> '' then
ImageEnView1.IO.SaveToFile(sFileName)
!!}
function TImageEnIO.ExecuteSaveDialog(const Title : WideString; DefaultFilter : TIOFileType; LimitToFileType : TIOFileType = -1; AlwaysAnimate : boolean = False) : WideString;
begin
Result := ExecuteSaveDialog('', '', AlwaysAnimate, 0, '', Title, '', DefaultFilter, LimitToFileType);
end;
function TImageEnIO.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) : WideString;
var
fSaveImageEnDialog: TSaveImageEnDialog;
begin
result := '';
fSaveImageEnDialog := TSaveImageEnDialog.create(self);
try
fSaveImageEnDialog.InitialDir := string(InitialDir);
fSaveImageEnDialog.FileName := InitialFileName;
{$IFDEF IEINCLUDEMULTIVIEW}
fSaveImageEnDialog.AlwaysAnimate := AlwaysAnimate;
{$ENDIF}
fSaveImageEnDialog.Options := fSaveImageEnDialog.Options + [OFENABLESIZING];
if Filter<>'' then
begin
fSaveImageEnDialog.AutoSetFilter := false;
fSaveImageEnDialog.Filter := Filter;
end;
fSaveImageEnDialog.AutoSetFilterFileType := LimitToFileType;
fSaveImageEnDialog.FilterDefault := DefaultFilter;
fSaveImageEnDialog.AttachedImageEnIO := self;
fSaveImageEnDialog.FilterIndex := FilterIndex;
fSaveImageEnDialog.AutoAdjustDPI := AutoAdjustDPI;
fSaveImageEnDialog.FilteredAdjustDPI := FilteredAdjustDPI;
fSaveImageEnDialog.ExtendedFilters := string(ExtendedFilters);
fSaveImageEnDialog.ShowFormats := iesfImagesOnly;
if Title<>'' then
fSaveImageEnDialog.Title := string(Title);
if fSaveImageEnDialog.Execute then
result := fSaveImageEnDialog.FileNameW;
finally
FreeAndNil(fSaveImageEnDialog);
end;
end;
{$ENDIF} // IEINCLUDEOPENSAVEDIALOGS
{!!
<FS>TImageEnIO.CaptureFromScreen
<FM>Declaration<FC>
procedure CaptureFromScreen(Source: <A TIECSSource>; MouseCursor: TCursor = -1);
<FM>Description<FN>
Captures the current desktop or active window.
MouseCursor defines the cursor to draw because ImageEn cannot get it from Windows. Use -1 for none.
<FM>Example<FC>
// Save the current desktop to 'screen.png'
ImageEnView1.io.CaptureFromScreen(iecsScreen, -1);
ImageEnView1.io.SaveToFile('D:\screen.png');
!!}
procedure TImageEnIO.CaptureFromScreen(Source: TIECSSource; MouseCursor: TCursor);
var
hwin, hdc: THandle;
x, y, w, h: integer;
rc: TRect;
vdsk: boolean;
pt: TPoint;
xbmp: TIEDibBitmap;
plc: TWINDOWPLACEMENT;
hCursor: THandle;
MousePt: TPoint;
ClientLeftTop: TPoint;
IconInfo: TIconInfo;
begin
// ASYNC MODE
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateCaptureFromScreen(self, CaptureFromScreen, Source, MouseCursor);
exit;
end;
if not MakeConsistentBitmap([]) then
exit;
getcursorpos(MousePt);
hCursor := Screen.Cursors[-2];
GetIconInfo(hCursor, IconInfo);
try
ClientLeftTop := Point(0, 0);
vdsk := (IEGlobalSettings().OpSys <> ieosWin95) and (IEGlobalSettings().OpSys <> ieosWinNT4);
hwin := 0;
w := 0;
h := 0;
x := 0;
y := 0;
case Source of
iecsScreen:
begin
hwin := GetDesktopWindow;
if vdsk then
begin
x := GetSystemMetrics(76); // SM_XVIRTUALSCREEN
y := GetSystemMetrics(77); // SM_YVIRTUALSCREEN
w := GetSystemMetrics(78); // SM_CXVIRTUALSCREEN
h := GetSystemMetrics(79); // SM_CYVIRTUALSCREEN
end
else
begin
// OLDER VERSIONS OF WINDOWS
w := Screen.Width;
h := Screen.Height;
end;
dec(MousePt.x, integer(IconInfo.xHotspot));
dec(MousePt.y, integer(IconInfo.yHotspot));
Windows.ScreenToClient(hwin, MousePt);
end;
iecsPrimary:
begin
hwin := GetDesktopWindow;
if vdsk then
begin
x := 0;
y := 0;
w := GetSystemMetrics(0); // SM_CXSCREEN
h := GetSystemMetrics(1); // SM_CYSCREEN
end
else
begin
// OLDER VERSIONS OF WINDOWS
w := Screen.Width;
h := Screen.Height;
end;
dec(MousePt.x, integer(IconInfo.xHotspot));
dec(MousePt.y, integer(IconInfo.yHotspot));
Windows.ScreenToClient(hwin, MousePt);
end;
iecsForegroundWindow:
begin
hwin := GetForegroundWindow;
if hwin <> 0 then
begin
plc.length := sizeof(TWINDOWPLACEMENT);
GetWindowPlacement(hwin, @plc);
if GetWindowRect(hwin, rc) then
begin
if plc.showCmd = SW_SHOWMAXIMIZED then
begin
if rc.left < 0 then
x := -rc.left;
if rc.top < 0 then
y := -rc.top;
w := rc.Right - x;
h := rc.Bottom - y;
if rc.left < 0 then
rc.left := 0;
if rc.top < 0 then
rc.top := 0;
end
else
begin
w := rc.Right - rc.Left;
h := rc.Bottom - rc.Top;
end;
Windows.ClientToScreen(hwin, ClientLeftTop);
dec(MousePt.x, -(ClientLeftTop.x - rc.left) + integer(IconInfo.xHotspot));
dec(MousePt.y, -(ClientLeftTop.y - rc.top) + integer(IconInfo.yHotspot));
Windows.ScreenToClient(hwin, MousePt);
end
else
hwin := 0;
end;
end;
iecsForegroundWindowClient:
begin
hwin := GetForegroundWindow;
if hwin <> 0 then
begin
if GetClientRect(hwin, rc) then
begin
pt.x := rc.Left;
pt.y := rc.Top;
Windows.ClientToScreen(hwin, pt);
x := pt.x;
y := pt.y;
pt.x := rc.Right;
pt.y := rc.Bottom;
Windows.ClientToScreen(hwin, pt);
w := pt.x - x;
h := pt.y - y;
hwin := GetDesktopWindow;
dec(MousePt.x, integer(IconInfo.xHotspot) + x);
dec(MousePt.y, integer(IconInfo.yHotspot) + y);
end
else
hwin := 0;
end;
end;
end;
if hwin <> 0 then
begin
xbmp := TIEDibBitmap.Create;
xbmp.AllocateBits(w, h, 24);
hdc := GetWindowDC(hwin);
if hdc <> 0 then
begin
BitBlt(xbmp.HDC, 0, 0, w, h, hdc, x, y, SRCCOPY);
if MouseCursor <> -1 then
DrawIconEx(xbmp.HDC, MousePt.x, MousePt.y, hCursor, 0, 0, 0, 0, DI_DEFAULTSIZE or DI_NORMAL);
fIEBitmap.Allocate(w, h, ie24RGB);
for y := 0 to h - 1 do
CopyMemory(fIEBitmap.Scanline[y], xbmp.Scanline[y], fIEBitmap.RowLen);
FreeAndNil(xbmp);
ReleaseDC(hwin, hdc);
Params.DpiX := IEGlobalSettings().SystemDPIX;
Params.DpiY := IEGlobalSettings().SystemDPIY;
Update();
end;
end;
finally
DeleteObject( IconInfo.hbmMask );
DeleteObject( IconInfo.hbmColor );
end;
DoFinishWork;
end;
{$IFDEF IEINCLUDEPRINTDIALOGS}
constructor TIOPrintPreviewParams.Create;
begin
inherited Create;
fMarginTop := 1;
fMarginLeft := 1;
fMarginRight := 1;
fMarginBottom := 1;
fPosition := ppCenter;
fSize := psFitToPage;
fWidth := -1; // default auto-calculated
fHeight := -1; // default auto-calculated
fGamma := 1;
fPrintThumbnails := False;
fPrintSelected := False;
fThumbnailColumns := 4;
fThumbnailRows := 5;
fThumbnailSpacing := 0.1;
fThumbnailStyle := ptSoftShadow;
fThumbnailShowText := True;
fDlgWidth := 0;
fDlgHeight := 0;
end;
{!!
<FS>TIOPrintPreviewParams.SaveToFile
<FM>Declaration<FC>
procedure SaveToFile(const FileName: WideString);
<FM>Description<FN>
Save all settings of the Print Preview dialog to file.
<FM>Example<FC>
// Show Print dialog (remembering the user's settings)
if FileExists( PrinterSettingsFilename ) then
ImageEnView1.IO.PrintPreviewParams.LoadFromFile( PrinterSettingsFilename );
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog );
ImageEnView1.IO.PrintPreviewParams.SaveToFile( PrinterSettingsFilename );
!!}
procedure TIOPrintPreviewParams.SaveToFile(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
fs := TIEWideFileStream.Create(FileName, fmCreate);
SaveToStream(fs);
FreeAndNil(fs);
end;
{!!
<FS>TIOPrintPreviewParams.LoadFromFile
<FM>Declaration<FC>
procedure LoadFromFile(const FileName: WideString);
<FM>Description<FN>
Load all settings of the Print Preview dialog from file.
<FM>Example<FC>
// Show Print dialog (remembering the user's settings)
if FileExists( PrinterSettingsFilename ) then
ImageEnView1.IO.PrintPreviewParams.LoadFromFile( PrinterSettingsFilename );
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog );
ImageEnView1.IO.PrintPreviewParams.SaveToFile( PrinterSettingsFilename );
!!}
procedure TIOPrintPreviewParams.LoadFromFile(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(fs);
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TIOPrintPreviewParams.SaveToStream
<FM>Declaration<FC>
procedure SaveToStream(Stream: TStream);
<FM>Description<FN>
Save all settings of the Print Preview dialog to a stream.
<FM>Example<FC>
// Show Print dialog (remembering the user's settings)
if FileExists( PrinterSettingsStream ) then
ImageEnView1.IO.PrintPreviewParams.LoadFromStream( PrinterSettingsStream );
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog );
ImageEnView1.IO.PrintPreviewParams.SaveToStream( PrinterSettingsStream );
!!}
procedure TIOPrintPreviewParams.SaveToStream(Stream: TStream);
begin
Stream.Write(fMarginTop, sizeof(double));
Stream.Write(fMarginLeft, sizeof(double));
Stream.Write(fMarginRight, sizeof(double));
Stream.Write(fMarginBottom, sizeof(double));
Stream.Write(fPosition, sizeof(TIOPrintPreviewPosition));
Stream.Write(fSize, sizeof(TIOPrintPreviewSize));
Stream.Write(fWidth, sizeof(double));
Stream.Write(fHeight, sizeof(double));
Stream.Write(fGamma, sizeof(double));
Stream.Write(fPrintThumbnails, sizeof(Boolean));
Stream.Write(fThumbnailColumns, sizeof(Integer));
Stream.Write(fThumbnailRows, sizeof(Integer));
Stream.Write(fThumbnailSpacing, sizeof(double));
Stream.Write(fThumbnailStyle, sizeof(TIOPrintPreviewThumbnailStyle));
Stream.Write(fThumbnailShowText, sizeof(Boolean));
Stream.Write(fDlgWidth, sizeof(Integer));
Stream.Write(fDlgHeight, sizeof(Integer));
Stream.Write(fPrintSelected, sizeof(Boolean));
end;
{!!
<FS>TIOPrintPreviewParams.LoadFromStream
<FM>Declaration<FC>
procedure LoadFromStream(Stream: TStream);
<FM>Description<FN>
Loads all settings of the Print Preview dialog from a stream.
<FM>Example<FC>
// Show Print dialog (remembering the user's settings)
if FileExists( PrinterSettingsStream ) then
ImageEnView1.IO.PrintPreviewParams.LoadFromStream( PrinterSettingsStream );
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog );
ImageEnView1.IO.PrintPreviewParams.SaveToStream( PrinterSettingsStream );
!!}
procedure TIOPrintPreviewParams.LoadFromStream(Stream: TStream);
begin
Stream.Read(fMarginTop, sizeof(double));
Stream.Read(fMarginLeft, sizeof(double));
Stream.Read(fMarginRight, sizeof(double));
Stream.Read(fMarginBottom, sizeof(double));
Stream.Read(fPosition, sizeof(TIOPrintPreviewPosition));
Stream.Read(fSize, sizeof(TIOPrintPreviewSize));
Stream.Read(fWidth, sizeof(double));
Stream.Read(fHeight, sizeof(double));
Stream.Read(fGamma, sizeof(double));
Stream.Read(fPrintThumbnails, sizeof(Boolean));
Stream.Read(fThumbnailColumns, sizeof(Integer));
Stream.Read(fThumbnailRows, sizeof(Integer));
Stream.Read(fThumbnailSpacing, sizeof(double));
Stream.Read(fThumbnailStyle, sizeof(TIOPrintPreviewThumbnailStyle));
Stream.Read(fThumbnailShowText, sizeof(Boolean));
Stream.Read(fDlgWidth, sizeof(Integer));
Stream.Read(fDlgHeight, sizeof(Integer));
Stream.Read(fPrintSelected, sizeof(Boolean));
end;
{!!
<FS>TIOPrintPreviewParams.GetProperty
<FM>Declaration<FC>
function GetProperty(const Prop: WideString): WideString;
<FM>Description<FN>
Read a property of the Print Preview dialog using its string representation.
!!}
function TIOPrintPreviewParams.GetProperty(const Prop: WideString): WideString;
var
ss: WideString;
begin
ss := UpperCase(IERemoveCtrlCharsW(Prop));
if ss = PPP_MARGINTOP then
result := IEFloatToStrW(fMarginTop)
else
if ss = PPP_MARGINLEFT then
result := IEFloatToStrW(fMarginLeft)
else
if ss = PPP_MARGINRIGHT then
result := IEFloatToStrW(fMarginRight)
else
if ss = PPP_MARGINBOTTOM then
result := IEFloatToStrW(fMarginBottom)
else
if ss = PPP_POSITION then
result := IntToStr(integer(fPosition))
else
if ss = PPP_SIZE then
result := IntToStr(integer(fSize))
else
if ss = PPP_WIDTH then
result := IEFloatToStrW(fWidth)
else
if ss = PPP_HEIGHT then
result := IEFloatToStrW(fHeight)
else
if ss = PPP_GAMMA then
result := IEFloatToStrW(fGamma)
else
if ss = PPP_PRINTTHUMBNAILS then
Result := IEBool2StrW(fPrintThumbnails)
else
if ss = PPP_THUMBNAILCOLUMNS then
Result := IntToStr(fThumbnailColumns)
else
if ss = PPP_THUMBNAILROWS then
Result := IntToStr(fThumbnailRows)
else
if ss = PPP_THUMBNAILSPACING then
Result := IEFloatToStrW(fThumbnailSpacing)
else
if ss = PPP_THUMBNAILSTYLE then
Result := IntToStr(Integer(fThumbnailStyle))
else
if ss = PPP_THUMBNAILSHOWTEXT then
Result := IEBool2StrW(fThumbnailShowText)
else
if ss = PPP_DLGWIDTH then
Result := IntToStr(fDlgWidth)
else
if ss = PPP_DLGHEIGHT then
Result := IntToStr(fDlgHeight)
else
if ss = PPP_PRINTSELECTED then
Result := IEBool2StrW(fPrintSelected);
end;
{!!
<FS>TIOPrintPreviewParams.SetProperty
<FM>Declaration<FC>
procedure SetProperty(Prop, Value: WideString);
<FM>Description<FN>
Write a property of the Print Preview dialog using its string representation.
!!}
procedure TIOPrintPreviewParams.SetProperty(Prop, Value: WideString);
var
ss: WideString;
begin
ss := UpperCase(IERemoveCtrlCharsW(Prop));
Value := IERemoveCtrlCharsW(Value);
if ss = PPP_MARGINLEFT then
fMarginLeft := IEStrToFloatDefW(value, 0)
else
if ss = PPP_MARGINRIGHT then
fMarginRight := IEStrToFloatDefW(value, 0)
else
if ss = PPP_MARGINTOP then
fMarginTop := IEStrToFloatDefW(value, 0)
else
if ss = PPP_MARGINBOTTOM then
fMarginBottom := IEStrToFloatDefW(value, 0)
else
if ss = PPP_POSITION then
fPosition := TIOPrintPreviewPosition(StrToIntDef(value, 0))
else
if ss = PPP_SIZE then
fSize := TIOPrintPreviewSize(StrToIntDef(value, 0))
else
if ss = PPP_WIDTH then
fWidth := IEStrToFloatDefW(value, 0)
else
if ss = PPP_HEIGHT then
fHeight := IEStrToFloatDefW(value, 0)
else
if ss = PPP_GAMMA then
fGamma := IEStrToFloatDefW(value, 0)
else
if ss = PPP_PRINTTHUMBNAILS then
fPrintThumbnails := IEStr2BoolW(value)
else
if ss = PPP_THUMBNAILCOLUMNS then
fThumbnailColumns := StrToIntDef(value, 4)
else
if ss = PPP_THUMBNAILROWS then
fThumbnailRows := StrToIntDef(value, 5)
else
if ss = PPP_THUMBNAILSPACING then
fThumbnailSpacing := IEStrToFloatDefW(value, 0)
else
if ss = PPP_THUMBNAILSTYLE then
fThumbnailStyle := TIOPrintPreviewThumbnailStyle(StrToIntDef(value, 0))
else
if ss = PPP_THUMBNAILSHOWTEXT then
fThumbnailShowText := IEStr2BoolW(value)
else
if ss = PPP_DLGWIDTH then
fDlgWidth := StrToIntDef(value, 0)
else
if ss = PPP_DLGHEIGHT then
fDlgHeight := StrToIntDef(value, 0)
else
if ss = PPP_PRINTSELECTED then
fPrintSelected := IEStr2BoolW(value);
end;
{!!
<FS>TImageEnIO.DoPrintPreviewDialog
<FM>Declaration<FC>
function DoPrintPreviewDialog(DialogType: <A TIEDialogType> = iedtDialog; const TaskName: WideString = ''; PrintAnnotations: Boolean = false; const Caption: WideString = ''; PrintLayers: Boolean = false): Boolean;
<FM>Description<FN>
Displays a print preview dialog to allow the user to configure and print the current image.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C>FC>DialogType<FN></C> <C> Select the style of print dialog </C> </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>PrintLayers<FN></C> <C> If true and the attached <A TImageEnView> image contains <L TImageEnView.Layers>multiple layers</L>, they will be printed. If False, only the image (i.e. current layer) is printed </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>Demos<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\FullApps\PhotoEn3\ImageEx.dpr </C> </R>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\PrintSelected\PrintSelected.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog );
<IMG help_images\PrintPreview_sm.gif>
ImageEnView1.IO.DoPrintPreviewDialog( iedtMaxi );
<IMG help_images\PrintMaxi.jpg>
// Preview image with layers
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog, '', False, '', True );
// If an area of the image is selected, print the selection, otherwise print the whole image
procedure TForm1.PrintImageClick(Sender: TObject);
var
bmp: TIEBitmap;
IO: TImageEnIO;
begin
if ImageEnView1.Selected = False then
ImageEnView1.IO.DoPrintPreviewDialog( iedtDialog, '' )
else
begin
bmp := TIEBitmap.Create;
IO := TImageEnIO.CreateFromBitmap( bmp );
try
ImageEnView1.CopySelectionToBitmap( bmp );
IO.DoPrintPreviewDialog( iedtDialog, '' );
finally
IO.Free;
bmp.Free;
end;
end;
end;
<FM>See Also<FN>
- <A TImageEnIO.PrintPreviewParams>
- <A TImageEnIO.DialogsMeasureUnit>
!!}
function TImageEnIO.DoPrintPreviewDialog(DialogType: TIEDialogType; const TaskName: WideString; PrintAnnotations: Boolean; const Caption: WideString; PrintLayers: Boolean): boolean;
var
fieprnform1: tfieprnform1;
fieprnform2: tfieprnform2;
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;
result := false;
if not MakeConsistentBitmap([]) then
exit;
GeneratePrintBitmap( PrintAnnotations, PrintLayers );
if (fPrintBitmap.Width <= 1) and (fPrintBitmap.Height <= 1) then
begin
FreeAndNil( fPrintBitmap );
exit;
end;
case DialogType of
iedtDialog:
begin
fieprnform2 := tfieprnform2.Create(self);
try
fieprnform2.io := self;
fieprnform2.fDialogsMeasureUnit := fDialogsMeasureUnit;
fieprnform2.UpdateLanguage();
if fPreviewFontEnabled then
fieprnform2.Font.Assign(fPreviewFont)
else
fieprnform2.Font.Assign(IEGetDefaultDialogFont);
fieprnform2.fTaskName := TaskName;
fieprnform2.fPrintPreviewParams := fPrintPreviewParams;
fieprnform2.PrintAnnotations := PrintAnnotations;
if Caption <> '' then
fieprnform2.Caption := Caption
else
fieprnform2.Caption := iemsg(IEMSG_PRINT);
if assigned(fOnIOPreview) then
fOnIOPreview(self, fieprnform2);
result := fieprnform2.ShowModal = mrOk;
finally
fieprnform2.Release;
end;
end;
iedtMaxi:
begin
fieprnform1 := tfieprnform1.Create(self);
try
fieprnform1.io := self;
fieprnform1.fDialogsMeasureUnit := fDialogsMeasureUnit;
fieprnform1.UpdateLanguage();
if fPreviewFontEnabled then
fieprnform1.Font.Assign(fPreviewFont)
else
fieprnform1.Font.Assign(IEGetDefaultDialogFont);
fieprnform1.fTaskName := TaskName;
fieprnform1.Left := 0;
fieprnform1.Top := 0;
fieprnform1.fPrintPreviewParams := fPrintPreviewParams;
fieprnform1.PrintAnnotations := PrintAnnotations;
if Caption <> '' then
fieprnform1.Caption := Caption
else
fieprnform1.Caption := iemsg(IEMSG_PRINT);
if assigned(fOnIOPreview) then
fOnIOPreview(self, fieprnform1);
result := fieprnform1.ShowModal = mrOk;
finally
fieprnform1.Release;
end;
end;
end;
FreeAndNil( fPrintBitmap );
end;
{$ENDIF}
procedure TImageEnIO.AdjustDPI;
var
new_w, new_h: integer;
newbmp, oldalpha: TIEBitmap;
begin
if not MakeConsistentBitmap([]) then
exit;
if (fParams.DpiX <> fParams.DpiY) and (fParams.DpiX > 0) and (fParams.DpiY > 0) and
(fIEBitmap.Width > 0) and (fIEBitmap.Height > 0) and (fParams.Height > 0) and (fParams.Width > 0) then
begin
newbmp := TIEBitmap.Create;
if fParams.Width > fParams.Height then
begin
new_h := trunc((fParams.Height / fParams.fDpiY) * fParams.fDpiX);
new_w := fParams.Width;
fParams.fDpiY := fParams.fDpiX;
fParams.Height := new_h;
end
else
begin
new_w := trunc((fParams.Width / fParams.fDpiX) * fParams.fDpiY);
new_h := fParams.Height;
fParams.fDpiX := fParams.fDpiY;
fParams.Width := new_w;
end;
if fIEBitmap.HasAlphaChannel then
begin
oldalpha := TIEBitmap.Create;
oldalpha.assign(fIEBitmap.AlphaChannel);
end
else
oldalpha := nil;
if fFilteredAdjustDPI then
begin
newbmp.Allocate(new_w, new_h, ie24RGB);
if fIEBitmap.PixelFormat <> ie24RGB then
fIEBitmap.PixelFormat := ie24RGB;
_ResampleEx(fIEBitmap, newbmp, nil, IEGlobalSettings().DefaultResampleFilter, nil, nil);
end
else
begin
newbmp.Allocate(new_w, new_h, fIEBitmap.PixelFormat);
_IEBmpStretchEx(fIEBitmap, newbmp, nil, nil);
end;
fIEBitmap.Assign(newbmp);
FreeAndNil(newbmp);
// stretch alpha
if assigned(oldalpha) then
begin
_IEBmpStretchEx(oldalpha, fIEBitmap.AlphaChannel, nil, nil);
FreeAndNil(oldalpha);
end;
end;
end;
// return frame count
{!!
<FS>TImageEnIO.OpenAVIFile
<FM>Declaration<FC>
function OpenAVIFile(const FileName: WideString): Integer;
<FM>Description<FN>
Opens an AVI file without reading any frames. The result is the number of frames contained in the AVI.
<FM>Example<FC>
// Save the first AVI frame to 'frame1.jpg', second frame to 'frame2.jpg'
ImageEnView1.IO.OpenAVIFile( 'C:\film.avi' );
ImageEnView1.IO.LoadFromAVI( 0 );
ImageEnView1.IO.SaveToFile('D:\frame1.jpg');
ImageEnView1.IO.LoadFromAVI( 1 );
ImageEnView1.IO.SaveToFile('D:\frame2.jpg');
...
ImageEnView1.IO.CloseAVIFile;
<FM>See Also<FN>
- <A TImageEnIO.CloseAVIFile>
- <A TImageEnIO.LoadFromAVI>
- <A TImageEnIO.IsOpenAVI>
!!}
function TImageEnIO.OpenAVIFile(const FileName: WideString): integer;
var
psi: TAviStreamInfoW;
begin
fAborting := false;
if fAVI_avf <> nil then
CloseAVIFile();
result := 0;
fParams.AVI_FrameCount := 0;
try
fParams.FileName := FileName;
fParams.FileType := ioUnknown;
if not gAVIFILEinit then
begin
AVIFileInit();
gAVIFILEinit := true;
end;
if AVIFileOpenW(PAVIFILE(fAVI_avf), PWideChar(FileName), OF_READ, nil) <> 0 then
begin
fAborting := True;
exit;
end;
if AVIFileGetStream(PAVIFILE(fAVI_avf), PAVISTREAM(fAVI_avs), streamtypeVIDEO, 0) <> 0 then
begin
AVIFileRelease(fAVI_avf);
fAborting := True;
exit;
end;
if AVIStreamInfoW(PAVISTREAM(fAVI_avs), psi, sizeof(TAVISTREAMINFOW)) <> 0 then
begin
AVIFileRelease(fAVI_avf);
AVIStreamRelease(fAVI_avs);
fAborting := True;
exit;
end;
move(psi, fAVI_psi, sizeof(TAviStreamInfoW_Ex));
fAVI_gf := AVIStreamGetFrameOpen(fAVI_avs, nil);
if fAVI_gf = nil then
begin
AVIFileRelease(fAVI_avf);
AVIStreamRelease(fAVI_avs);
fAborting := True;
exit;
end;
result := fAVI_psi.dwLength;
fParams.AVI_FrameCount := fAVI_psi.dwLength;
fParams.AVI_FrameDelayTime := 1000 / (fAVI_psi.dwRate/fAVI_psi.dwScale);
finally
if fAborting then
begin
fAVI_avf := nil;
fAVI_avs := nil;
fAVI_gf := nil;
end;
end;
end;
{!!
<FS>TImageEnIO.CloseAVIFile
<FM>Declaration<FC>
procedure CloseAVIFile;
<FM>Description<FN>
Closes an AVI file that was opened with <A TImageEnIO.OpenAVIFile> or <A TImageEnIO.CreateAVIFile>.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\VideoCapture\DesktopToAvi\DesktopToAvi.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// Save the first AVI frame to 'frame1.jpg', second frame to 'frame2.jpg'
ImageEnView1.IO.OpenAVIFile( 'C:\film.avi' );
ImageEnView1.IO.LoadFromAVI( 0 );
ImageEnView1.IO.SaveToFile('D:\frame1.jpg');
ImageEnView1.IO.LoadFromAVI( 1 );
ImageEnView1.IO.SaveToFile('D:\frame2.jpg');
...
ImageEnView1.IO.CloseAVIFile;
!!}
procedure TImageEnIO.CloseAVIFile;
begin
if fAVI_avs1 <> nil then
begin
// save
AVISaveOptionsFree(1, PAVICOMPRESSOPTIONS(fAVI_popts));
freemem(fAVI_popts);
if fAVI_avs <> nil then
AVIStreamRelease(fAVI_avs);
AVIStreamRelease(fAVI_avs1);
AVIFileRelease(fAVI_avf);
fAVI_popts := nil;
fAVI_avs := nil;
fAVI_avs1 := nil;
fAVI_avf := nil;
end
else
begin
// load
if fAVI_avf = nil then
exit;
AVIStreamGetFrameClose(fAVI_gf);
AVIStreamRelease(fAVI_avs);
AVIFileRelease(fAVI_avf);
fAVI_avf := nil;
fAVI_avs := nil;
fAVI_gf := nil;
end;
end;
{!!
<FS>TImageEnIO.IsOpenAVI
<FM>Declaration<FC>
function IsOpenAVI: Boolean;
<FM>Description<FN>
Returns True when <A TImageEnIO.OpenAVIFile> has a currently open file.
!!}
function TImageEnIO.IsOpenAVI: Boolean;
begin
result := (fAVI_avf <> nil) and (fAVI_avs <> nil) and (fAVI_gf <> nil);
end;
{!!
<FS>TImageEnIO.LoadFromAVI
<FM>Declaration<FC>
function LoadFromAVI(FrameIndex: Integer): Boolean;
<FM>Description<FN>
Reads the frame of index, <FC>FrameIndex<FN>, opened with <A TImageEnIO.OpenAVIFile>. Result will be false if the file is not a recognized file type (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FM>Example<FC>
// Save first AVI frame to 'frame1.jpg', second frame to 'frame2.jpg'
ImageEnView1.IO.OpenAVIFile( 'C:\film.avi' );
ImageEnView1.IO.LoadFromAVI( 0 );
ImageEnView1.IO.SaveToFile('D:\frame1.jpg');
ImageEnView1.IO.LoadFromAVI( 1 );
ImageEnView1.IO.SaveToFile('D:\frame2.jpg');
...
ImageEnView1.IO.CloseAVIFile;
!!}
function TImageEnIO.LoadFromAVI(FrameIndex: integer): Boolean;
var
pt: pointer;
bitcount: integer;
dib: TIEDibBitmap;
iBitsPerSample, iSamplesPerPixel: Integer;
begin
CheckHaveValidBitmap();
Result := False;
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveIndexRetBool(self, LoadFromAVI, FrameIndex);
exit;
end;
try
fAborting := false;
if not MakeConsistentBitmap([]) then
exit;
if (fAVI_avf = nil) or (fAVI_avs = nil) or (fAVI_gf = nil) then
exit;
if dword(FrameIndex) >= fAVI_psi.dwLength then
exit;
pt := AVIStreamGetFrame(fAVI_gf, FrameIndex);
fParams.AVI_FrameCount := fAVI_psi.dwLength;
fParams.AVI_FrameDelayTime := 1000 / (fAVI_psi.dwRate/fAVI_psi.dwScale);
dib := TIEDibBitmap.create;
if pt <> nil then
begin
bitcount := _IECopyDIB2Bitmap2Ex(uint64(pt), dib, nil, true); // uses drawdibdraw
fIEBitmap.CopyFromTDibBitmap(dib);
BitCountToBPSAndSPP( BitCount, False, iBitsPerSample, iSamplesPerPixel );
fParams.BitsPerSample := iBitsPerSample;
fParams.SamplesPerPixel := iSamplesPerPixel;
fParams.DpiX := IEGlobalSettings().DefaultDPIX;
fParams.DpiY := IEGlobalSettings().DefaultDPIY;
fParams.Width := dib.Width;
fParams.Height := dib.Height;
fParams.OriginalWidth := dib.Width;
fParams.OriginalHeight := dib.Height;
fParams.FreeColorMap;
Update();
Result := Not fAborting;
ResetModified();
end;
FreeAndNil(dib);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.CreateAVIFile
<FM>Declaration<FC>
function CreateAVIFile(const FileName: WideString; rate: Integer; const codec: AnsiString): TIECreateAVIFileResult;
<FM>Description<FN>
Creates a new, empty AVI file.
<FM>FileName<FN>: Full destination path
<FM>Rate<FN>: Specifies the number of frames per second
<FM>Code<FN>: The compression codec to use (must be installed on system) as a four characters string.
For example:
'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>
You can save each frame to the created AVI file using the <A TImageEnIO.SaveToAVI> method.
Finally, call <A TImageEnIO.CloseAVIFile> to close the file.
<FM>Example<FC>
ImageEnView.IO.CreateAVIFile('D:\output.avi', 20, 'DIB ');
// save frame 0
ImageEnView.IO.LoadFromFile('C:\frame0.jpg');
ImageEnView.IO.Params.BitsPerSample := 8;
ImageEnView.IO.Params.SamplesPerPixel := 1;
ImageEnView.IO.SaveToAVI;
// save frame 1
ImageEnView.IO.LoadFromFile('C:\frame1.jpg');
ImageEnView.IO.Params.BitsPerSample := 8;
ImageEnView.IO.Params.SamplesPerPixel := 1;
ImageEnView.IO.SaveToAVI;
// close the file
ImageEnView.IO.CloseAVIFile;
!!}
function TImageEnIO.CreateAVIFile(const FileName: WideString; rate: Double; const codec: AnsiString): TIECreateAVIFileResult;
var
psi: TAviStreamInfoW;
hr: HResult;
num, den: integer;
begin
fAborting := False;
if not gAVIFILEinit then
begin
AVIFileInit;
gAVIFILEinit := true;
end;
if IEFileExistsW(FileName) then
DeleteFileW(PWideChar(FileName));
if AVIFileOpenW(PAVIFILE(fAVI_avf), PWideChar(FileName), OF_WRITE or OF_CREATE, nil) <> 0 then
raise EInvalidGraphic.Create('unable to create AVI file');
ZeroMemory(@psi, sizeof(psi));
psi.fccType := streamtypeVIDEO;
IEDecimalToFraction(rate, num, den);
psi.dwScale := den;
psi.dwRate := num;
psi.dwQuality := $FFFFFFFF;
fAVI_popts := allocmem(sizeof(TAVICOMPRESSOPTIONS));
if (fParams.BitsPerSample = 8) and (fParams.SamplesPerPixel = 1) then
psi.dwSuggestedBufferSize := IEBitmapRowLen(fParams.Width, 8, 32) * fParams.Height
else
psi.dwSuggestedBufferSize := IEBitmapRowLen(fParams.Width, 24, 32) * fParams.Height;
psi.rcFrame := rect(0, 0, fParams.Width, fParams.Height);
AVIFileCreateStreamW(PAVIFILE(fAVI_avf), PAVISTREAM(fAVI_avs1), psi);
if codec = '' then
begin
if not AVISaveOptions(0, 0, 1, @fAVI_avs1, @fAVI_popts) then
begin
AVIStreamRelease(fAVI_avs1);
fAVI_avs1 := nil;
AVIFileRelease(fAVI_avf);
fAVI_avf := nil;
freemem(fAVI_popts);
fAborting := True;
result := ieaviNOCOMPRESSOR;
exit; // EXIT POINT
end;
end
else
begin
PAVICOMPRESSOPTIONS(fAVI_popts)^.fccType := streamtypeVIDEO;
PAVICOMPRESSOPTIONS(fAVI_popts)^.fccHandler := pinteger(PAnsiChar(codec))^;
PAVICOMPRESSOPTIONS(fAVI_popts)^.dwKeyFrameEvery := 0;
PAVICOMPRESSOPTIONS(fAVI_popts)^.dwQuality := $FFFFFFFF;
PAVICOMPRESSOPTIONS(fAVI_popts)^.dwBytesPerSecond := 0;
PAVICOMPRESSOPTIONS(fAVI_popts)^.dwFlags := 0;
PAVICOMPRESSOPTIONS(fAVI_popts)^.lpFormat := nil;
PAVICOMPRESSOPTIONS(fAVI_popts)^.cbFormat := 0;
PAVICOMPRESSOPTIONS(fAVI_popts)^.lpParms := nil;
PAVICOMPRESSOPTIONS(fAVI_popts)^.cbParms := 0;
PAVICOMPRESSOPTIONS(fAVI_popts)^.dwInterleaveEvery := 0;
end;
hr := AVIMakeCompressedStream(PAVISTREAM(fAVI_avs), PAVISTREAM(fAVI_avs1), fAVI_popts, nil);
if hr = AVIERR_NOCOMPRESSOR then
result := ieaviNOCOMPRESSOR
else
if hr = AVIERR_MEMORY then
result := ieaviMEMORY
else
if hr = AVIERR_UNSUPPORTED then
result := ieaviUNSUPPORTED
else
result := ieaviOK;
fAborting := result <> ieaviOK;
fAVI_idx := 0;
end;
{!!
<FS>TImageEnIO.SaveToAVI
<FM>Declaration<FC>
procedure SaveToAVI;
<FM>Description<FN>
Saves the current image to an AVI file opened using <A TImageEnIO.CreateAVIFile>.
It is recommended that you set <A TImageEnIO.Params>.<A TIOParams.BitsPerSample> and <A TImageEnIO.Params>.<A TIOParams.SamplesPerPixel> before calling <A TImageEnIO.SaveToAVI>, because AVI requires all images to have the same color depth.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\VideoCapture\DesktopToAvi\DesktopToAvi.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView.IO.CreateAVIFile('output.avi', 20, 'DIB ');
// save frame 0
ImageEnView.IO.LoadFromFile('C:\frame0.jpg');
ImageEnView.IO.Params.BitsPerSample := 8;
ImageEnView.IO.Params.SamplesPerPixel := 1;
ImageEnView.IO.SaveToAVI();
// save frame 1
ImageEnView.IO.LoadFromFile('C:\frame1.jpg');
ImageEnView.IO.Params.BitsPerSample := 8;
ImageEnView.IO.Params.SamplesPerPixel := 1;
ImageEnView.IO.SaveToAVI();
// close the file
ImageEnView.IO.CloseAVIFile();
!!}
procedure TImageEnIO.SaveToAVI;
type
TBitmapInfoHeader256Ex = packed record
biSize: DWORD;
biWidth: Longint;
biHeight: Longint;
biPlanes: Word;
biBitCount: Word;
biCompression: DWORD;
biSizeImage: DWORD;
biXPelsPerMeter: Longint;
biYPelsPerMeter: Longint;
biClrUsed: DWORD;
biClrImportant: DWORD;
Palette: array[0..255] of TRGBQUAD;
end;
PBitmapInfoHeader256Ex = ^TBitmapInfoHeader256Ex;
var
he: TBitmapInfoHeader256Ex;
i: integer;
sw, sx: integer;
bmp: TIEBitmap;
begin
CheckHaveValidBitmap();
if (fAVI_avs = nil) or (not MakeConsistentBitmap([])) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
bmp := TIEBitmap.Create();
try
bmp.Location := ieMemory;
bmp.Assign(fIEBitmap);
// set video format
he.biSize := sizeof(TBitmapInfoHeader);
he.biWidth := bmp.Width;
he.biHeight := bmp.Height;
he.biPlanes := 1;
he.biCompression := BI_RGB;
he.biXPelsPerMeter := 0;
he.biYPelsPerMeter := 0;
he.biClrImportant := 0;
if (fParams.SamplesPerPixel = 1) and (fParams.BitsPerSample = 8) then
begin
// 256 colors
he.biClrUsed := 256;
bmp.PixelFormat := ie8p;
he.biSizeImage := bmp.RowLen * bmp.Height;
he.biBitCount := 8;
for i := 0 to 255 do
begin
he.Palette[i].rgbRed := bmp.Palette[i].r;
he.Palette[i].rgbGreen := bmp.Palette[i].g;
he.Palette[i].rgbBlue := bmp.Palette[i].b;
he.Palette[i].rgbReserved := 0;
end;
AVIStreamSetFormat(fAVI_avs, fAVI_idx, @he, sizeof(TBITMAPINFOHEADER) + 256 * sizeof(TRGBQUAD));
end
else
if bmp.HasAlphaChannel then
begin
// 32bit RGBA
bmp.PixelFormat := ie32RGB;
bmp.SynchronizeRGBA(false); // alpha to RGBA
he.biClrUsed := 0;
he.biBitCount := 32;
//he.biCompression := IEBI_RGBA; // <- don't work with it!
he.biSizeImage := bmp.RowLen * bmp.Height;
if fAVI_idx = 0 then
AVIStreamSetFormat(fAVI_avs, 0, @he, sizeof(TBITMAPINFOHEADER));
end
else
begin
// 24 bit
he.biClrUsed := 0;
he.biBitCount := 24;
he.biSizeImage := bmp.RowLen * bmp.Height;
if fAVI_idx = 0 then
AVIStreamSetFormat(fAVI_avs, 0, @he, sizeof(TBITMAPINFOHEADER));
end;
sw := 0;
sx := 0;
AVIStreamWrite(fAVI_avs, fAVI_idx, 1, bmp.Scanline[bmp.Height - 1], he.biSizeImage, AVIIF_KEYFRAME, @sx, @sw);
finally
FreeAndNil(bmp);
end;
inc(fAVI_idx);
end;
{!!
<FS>TImageEnIO.MergeMetaFile
<FM>Declaration<FC>
procedure MergeMetafile(const FileName: WideString; x, y, Width, Height: Integer);
<FM>Description<FN>
Loads a metafile and draws it at the x, y position using sizes of Width and Height.
If Width or Height is -1 the other is auto-calculated to maintain the aspect ratio.
<FM>Example<FC>
ImageEnView1.io.LoadFromFile('C:\backgroundimage.jpg');
ImageEnView1.io.MergeMetaFile('C:\overimage.wmf', 100, 100, 120, -1);
!!}
// If Width or Height is -1 then it is auto-calculated maintain aspect ratio
// Import... because this is a vectorial image
// Doesn't set IO params
// DON't USE INSIDE A THREAD
procedure TImageEnIO.MergeMetafile(const FileName: WideString; x, y, Width, Height: integer);
const
MAXDIMS = 16000;
var
meta: TMetafile;
dib: TIEDibBitmap;
dibcanvas: TCanvas;
begin
try
fAborting := false;
if (Width = 0) or (Height = 0) then
exit;
if not MakeConsistentBitmap([]) then
exit;
meta := tmetafile.create;
try
meta.LoadFromFile(FileName);
if (Width >= 0) or (Height >= 0) then
begin
if (Width >= 0) and (Height >= 0) then
begin
meta.Width := Width;
meta.Height := Height;
end
else
begin
if Width < 0 then
begin
meta.Width := (meta.Width * Height) div meta.Height;
meta.Height := Height;
end
else
if Height < 0 then
begin
meta.Height := (meta.Height * Width) div meta.Width;
meta.Width := Width;
end;
end;
end;
if (meta.width = 0) or (meta.height = 0) then
begin
fAborting := true;
exit; // finally will be executed (meta.free)
end;
if (meta.width > MAXDIMS) or (meta.height > MAXDIMS) then
begin
if meta.Height > meta.Width then
begin
meta.Width := (meta.Width * MAXDIMS) div meta.Height;
meta.Height := MAXDIMS;
end
else
begin
meta.Height := (meta.Height * MAXDIMS) div meta.Width;
meta.Width := MAXDIMS;
end;
end;
meta.transparent := true;
dib := TIEDibBitmap.Create;
dibcanvas := TCanvas.Create;
dib.AllocateBits(meta.Width - 1, meta.Height - 1, 24);
fIEBitmap.CopyToTDibBitmap(dib, x, y, dib.Width, dib.Height);
dibcanvas.Handle := dib.HDC;
dibCanvas.Draw(0, 0, meta);
fIEBitmap.MergeFromTDibBitmap(dib, x, y);
FreeAndNil(dibcanvas);
FreeAndNil(dib);
finally
FreeAndNil(meta);
end;
Update();
finally
DoFinishWork;
end;
end;
// doesn't set fParams.FileType
{$IFDEF IEINCLUDEJPEG2000}
function TImageEnIO.LoadFromStreamJ2000(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
CheckHaveValidBitmap();
Result := False;
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
J2KReadStream(Stream, fIEBitmap, fParams, Progress, False);
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
Result := Not fAborting;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.LoadFromStreamJP2
<FM>Declaration<FC>
function LoadFromStreamJP2(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a Jpeg2000 (JP2) file. The result will be false if an error is encountered, e.g. the file in the stream is not JPEG2000 format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamJP2(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamJP2, Stream);
Result := True;
exit;
end;
try
Result := LoadFromStreamJ2000(Stream);
fParams.FileType := ioJP2;
Update();
ResetModified();
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.LoadFromStreamJ2K
<FM>Declaration<FC>
function LoadFromStreamJ2K(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a Jpeg2000 (J2K code stream) file. The result will be false if an error is encountered, e.g. the file in the stream is not JPEG2000 format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamJ2K(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamJ2K, Stream);
Result := True;
exit;
end;
try
Result := LoadFromStreamJ2000(Stream);
fParams.FileType := ioJ2K;
Update();
ResetModified();
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.LoadFromFileJ2K
<FM>Declaration<FC>
function LoadFromFileJ2K(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a Jpeg2000 (J2K code stream) file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not a JPEG2000 (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
!!}
function TImageEnIO.LoadFromFileJ2K(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileJ2K, FileName);
Result := True;
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
fAborting := false;
try
Result := LoadFromStreamJ2000(fs);
fParams.FileName := FileName;
fParams.FileType := ioJ2K;
finally
FreeAndNil(fs);
end;
Update();
ResetModified();
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.LoadFromFileJP2
<FM>Declaration<FC>
function LoadFromFileJP2(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a Jpeg2000 (JP2) file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not JPEG2000 format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
!!}
function TImageEnIO.LoadFromFileJP2(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileJP2, FileName);
Result := True;
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
fAborting := false;
try
Result := LoadFromStreamJ2000(fs);
fParams.FileName := FileName;
fParams.FileType := ioJP2;
finally
FreeAndNil(fs);
end;
Update();
ResetModified();
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
procedure TImageEnIO.SaveToStreamJ2000(Stream: TStream; format: integer);
var
Progress: TProgressRec;
begin
CheckHaveValidBitmap();
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([ie1g, ie8g, ie16g, ie24RGB]) then
exit;
J2KWriteStream(Stream, fIEBitmap, fParams, Progress, format);
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.SaveToStreamJP2
<FM>Declaration<FC>
procedure SaveToStreamJP2(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in Jpeg2000 (JP2) format.
!!}
procedure TImageEnIO.SaveToStreamJP2(Stream: TStream);
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamJP2, Stream);
exit;
end;
try
SaveToStreamJ2000(Stream, 0);
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.SaveToStreamJ2K
<FM>Declaration<FC>
procedure SaveToStreamJ2K(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in Jpeg2000 (J2K code stream) format.
!!}
procedure TImageEnIO.SaveToStreamJ2K(stream: TStream);
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamJ2K, Stream);
exit;
end;
try
SaveToStreamJ2000(Stream, 1);
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.SaveToFileJP2
<FM>Declaration<FC>
procedure SaveToFileJP2(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in Jpeg2000 (JP2) format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnIO.SaveToFileJP2(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileJP2, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
SaveToStreamJ2000(fs, 0);
fParams.FileName := FileName;
fParams.FileType := ioJP2;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{$ENDIF}
{$IFDEF IEINCLUDEJPEG2000}
{!!
<FS>TImageEnIO.SaveToFileJ2K
<FM>Declaration<FC>
procedure SaveToFileJ2K(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in Jpeg2000 (J2K code stream) format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnIO.SaveToFileJ2K(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileJ2K, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
SaveToStreamJ2000(fs, 1);
fParams.FileName := FileName;
fParams.FileType := ioJ2K;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{$ENDIF}
{!!
<FS>TImageEnIO.IEBitmap
<FM>Declaration<FC>
property IEBitmap: <A TIEBitmap>
<FM>Description<FN>
Contains the attached <A TIEBitmap> object (same value as the <A TImageEnIO.AttachedIEBitmap> property).
!!}
procedure TImageEnIO.SetIEBitmap(bmp: TIEBitmap);
begin
fBitmap := nil;
if fIEBitmapCreated then
FreeAndNil(fIEBitmap);
fIEBitmapCreated := false;
fIEBitmap := bmp;
end;
{!!
<FS>TImageEnIO.AttachedIEBitmap
<FM>Declaration<FC>
property AttachedIEBitmap: <A TIEBitmap>
<FM>Description<FN>
Contains the attached <A TIEBitmap> object (same value as the <A TImageEnIO.IEBitmap> property).
<FM>Example<FC>
// multithread saving
Var
Bmp: TIEBitmap;
Io: TImageEnIO;
Begin
Bmp := TIEBitmap.Create;
Io := TImageEnIO.CreateFromBitmap(bmp);
Io.LoadFromFile('C:\input.bmp');
Io.AsyncMode := True; // this makes a thread foreach input/output task
Io.SaveToFile('D:\i1.jpg'); // thread 1
Io.SaveToFile('D:\i2.jpg'); // thread 2
Io.SaveToFile('D:\i3.jpg'); // thread 3
Io.Free; // free method waits for all tasks end!
Bmp.Free;
End;
!!}
procedure TImageEnIO.SetAttachedIEBitmap(bmp: TIEBitmap);
begin
if assigned(fImageEnView) then
fImageEnView.RemoveBitmapChangeEvent(fImageEnViewBitmapChangeHandle); // remove previous if exists
if (not assigned(bmp)) and (assigned(fImageEnView) or assigned(fTImage)) then
exit; // error
SetIEBitmap(bmp);
if assigned(bmp) then
begin
fImageEnView := nil;
fTImage := nil;
end;
end;
procedure TImageEnIO.SetBitmap(bmp: TBitmap);
begin
fBitmap := bmp;
fIEBitmap.EncapsulateTBitmap(fBitmap, true);
end;
{!!
<FS>TImageEnIO.AttachedBitmap
<FM>Declaration<FC>
property AttachedBitmap: TBitmap;
<FM>Description<FN>
Use this property to attach a TImageEnIO to a normal TBitmap object to provide wider format support and functionality.
This property is mutually exclusive with <A TImageEnIO.AttachedTImage> and <A TImageEnIO.AttachedImageEn>.
<FM>Example<FC>
var
bmp: TBitmap;
Begin
bmp := TBitmap.Create;
ImageEnIO1.AttachedBitmap := bmp;
ImageEnIO1.LoadFromFile('C:\alfa.tif');
...
End;
!!}
procedure TImageEnIO.SetAttachedBitmap(atBitmap: TBitmap);
begin
if assigned(fImageEnView) then
fImageEnView.RemoveBitmapChangeEvent(fImageEnViewBitmapChangeHandle); // remove previous if exists
if (not assigned(atBitmap)) and (assigned(fImageEnView) or assigned(fTImage)) then
exit; // error
fBitmap := atBitmap;
if assigned(fBitmap) then
fIEBitmap.EncapsulateTBitmap(fBitmap, true);
if assigned(fBitmap) then
begin
fImageEnView := nil;
fTImage := nil;
end;
end;
{!!
<FS>TImageEnIO.AttachedImageEn
<FM>Declaration<FC>
property AttachedImageEn: <A TIEView>;
<FM>Description<FN>
Use this property to attach a TImageEnIO to a <A TImageEnView>, <A TImageEnDBView>, <A TImageEnVect> or any other inherited component.
This property is mutually exclusive with <A TImageEnIO.AttachedTImage> and <A TImageEnIO.AttachedBitmap>.
Note: TIEView is the base class of <A TImageEnView> and <A TImageEnMView>.
<FM>Example<FC>
ImageEnIO1.AttachedImageEn := ImageEnView1;
!!}
procedure TImageEnIO.SetAttachedImageEn(atImageEn: TIEView);
begin
if assigned(fImageEnView) then
fImageEnView.RemoveBitmapChangeEvent(fImageEnViewBitmapChangeHandle); // remove previous if exists
fImageEnView := atImageEn;
if assigned(fImageEnView) then
begin // fImageEnView now could be nil
if fIEBitmapCreated then
begin
fIEBitmapCreated := false;
FreeAndNil(fIEBitmap);
end;
fBitmap := fImageEnView.Bitmap;
fIEBitmap := fImageEnView.IEBitmap;
if assigned(fIEBitmap) then
// use TIEBitmap
fBitmap := nil // both fBitmap and fIEBitmap not allowed
else
begin
// use TBitmap
fIEBitmapCreated := true;
fIEBitmap := TIEBitmap.Create;
fIEBitmap.EncapsulateTBitmap(fBitmap, true);
end;
fImageEnView.FreeNotification(self);
fTImage := nil;
fImageEnViewBitmapChangeHandle := fImageEnView.RegisterBitmapChangeEvent(OnBitmapChange);
end
else
begin
fIEBitmap := TIEBitmap.Create;
fIEBitmapCreated := true; // we create fIEBitmap
end;
end;
{!!
<FS>TImageEnIO.AttachedTImage
<FM>Declaration<FC>
property AttachedTImage: TImage;
<FM>Description<FN>
Use this property to attach a TImageEnIO to a TImage (to widen its format support and functionality).
This property is mutually exclusive with <A TImageEnIO.AttachedImageEn> and <A TImageEnIO.AttachedBitmap>.
<FM>Example<FC>
ImageEnIO1.AttachedTImage := Image1;
!!}
procedure TImageEnIO.SetTImage(v: TImage);
begin
if assigned(fImageEnView) then
fImageEnView.RemoveBitmapChangeEvent(fImageEnViewBitmapChangeHandle); // remove previous if exists
fTImage := v;
if assigned(fTImage) then
begin
fBitmap := fTImage.Picture.Bitmap;
fIEBitmap.EncapsulateTBitmap(fBitmap, true);
fTImage.FreeNotification(self);
fImageEnView := nil;
end
else
fIEBitmap.FreeImage(true);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TIEIOThread
{!!
<FS>TImageEnIO.AsyncRunning
<FM>Declaration<FC>
property AsyncRunning: Integer;
<FM>Description<FN>
Returns the number of threads that are running.
See also: <A TImageEnIO.AsyncMode>
<FM>Example<FC>
// multithread saving
Var
Bmp: TIEBitmap;
Io: TImageEnIO;
Begin
Bmp := TIEBitmap.Create;
Io := TImageEnIO.CreateFromBitmap(bmp);
Io.LoadFromFile('C:\input.bmp');
Io.AsyncMode := True; // this makes a thread foreach input/output task
Io.SaveToFile('D:\i1.jpg'); // thread-1
Io.SaveToFile('D:\i2.jpg'); // thread-2
Io.SaveToFile('D:\i3.jpg'); // thread-3
// waits all threads finish
Io.WaitThreads();
...
End;
!!}
function TImageEnIO.GetAsyncRunning: integer;
begin
fAsyncThreadsCS.Enter();
result := fAsyncThreads.Count;
fAsyncThreadsCS.Leave();
end;
procedure TIEIOThread.Init;
begin
fThreadList := fOwner.fAsyncThreads;
fOwner.fAsyncThreadsCS.Enter();
fThreadList.Add(self);
Windows.ResetEvent(fOwner.fAsyncThreadsFinishEvent);
fOwner.fAsyncThreadsCS.Leave();
{$ifndef IEHASAFTERCONSTRUCTION}
// this Delphi version hasn't AfterConstruction. We create threads in suspended mode, then resume
Resume;
{$endif}
end;
{$ifdef IEHASAFTERCONSTRUCTION}
const TIEIOTHREAD_STARTMODE = false; // start in AfterConstruction (don't need Resume)
{$else}
const TIEIOTHREAD_STARTMODE = true; // start suspended (need Resume)
{$endif}
constructor TIEIOThread.CreateLoadSaveFile(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFile; const in_nf: WideString);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveFile;
fMethod_LoadSaveFile := InMethod;
p_nf := in_nf;
Init;
end;
constructor TIEIOThread.CreateLoadSaveFileIF(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileIF; const in_nf: WideString; ImageFormat: TIOFileType);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveFileIF;
fMethod_LoadSaveFileIF := InMethod;
p_nf := in_nf;
p_ImageFormat := ImageFormat;
Init;
end;
constructor TIEIOThread.CreateLoadSaveStream(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStream; in_Stream: TStream);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveStream;
fMethod_LoadSaveStream := InMethod;
p_stream := in_Stream;
Init;
end;
constructor TIEIOThread.CreateLoadSaveStreamRetInt(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamRetInt; in_Stream: TStream);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveStreamRetInt;
fMethod_LoadSaveStreamRetInt := InMethod;
p_stream := in_Stream;
Init;
end;
constructor TIEIOThread.CreateLoadSaveStreamRetBool(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamRetBool; in_Stream: TStream);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveStreamRetBool;
fMethod_LoadSaveStreamRetBool := InMethod;
p_stream := in_Stream;
Init;
end;
constructor TIEIOThread.CreateLoadSaveFileRetInt(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileRetInt; const in_nf: WideString);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveFileRetInt;
fMethod_LoadSaveFileRetInt := InMethod;
p_nf := in_nf;
Init;
end;
constructor TIEIOThread.CreateLoadSaveFileRetBool(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileRetBool; const in_nf: WideString);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveFileRetBool;
fMethod_LoadSaveFileRetBool := InMethod;
p_nf := in_nf;
Init;
end;
constructor TIEIOThread.CreateLoadSaveFileIFRetBool(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileIFRetBool; const in_nf: WideString; ImageFormat: TIOFileType);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveFileIFRetBool;
fMethod_LoadSaveFileIFRetBool := InMethod;
p_nf := in_nf;
p_ImageFormat := ImageFormat;
Init;
end;
constructor TIEIOThread.CreateLoadSaveFileFFRetBool(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveFileFFRetBool; const in_nf: WideString; in_fileformat: TIOFileType);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveFileFFRetBool;
fMethod_LoadSaveFileFFRetBool := InMethod;
p_nf := in_nf;
p_fileformat := in_fileformat;
Init;
end;
constructor TIEIOThread.CreateLoadSaveStreamFF(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamFF; in_Stream: TStream; in_fileformat: TIOFileType);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveStreamFF;
fMethod_LoadSaveStreamFF := InMethod;
p_stream := in_stream;
p_fileformat := in_fileformat;
Init;
end;
constructor TIEIOThread.CreateLoadSaveStreamFTRetBool(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveStreamFTRetBool; in_Stream: TStream; in_fileformat: TIOFileType);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveStreamFTRetBool;
fMethod_LoadSaveStreamFTRetBool := InMethod;
p_stream := in_stream;
p_fileformat := in_fileformat;
Init;
end;
constructor TIEIOThread.CreateCaptureFromScreen(Owner: TImageEnIO; InMethod: TIEIOMethodType_CaptureFromScreen; in_source: TIECSSource; in_mouseCursor: TCursor);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieCaptureFromScreen;
fMethod_CaptureFromScreen := InMethod;
p_source := in_source;
p_mouseCursor := in_mouseCursor;
Init;
end;
constructor TIEIOThread.CreateLoadSaveIndexRetBool(Owner: TImageEnIO; InMethod: TIEIOMethodType_LoadSaveIndexRetBool; in_index: integer);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadSaveIndexRetBool;
fMethod_LoadSaveIndexRetBool := InMethod;
p_index := in_index;
Init;
end;
constructor TIEIOThread.CreateImportMetaFileRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_ImportMetaFileRetBool; const in_nf: WideString; in_width, in_height: integer; in_withalpha: boolean);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieImportMetaFileRetBool;
fMethod_ImportMetaFileRetBool := InMethod;
p_nf := in_nf;
p_width := in_width;
p_height := in_height;
p_withalpha := in_withalpha;
Init;
end;
constructor TIEIOThread.CreateLoadFromURLRetBool(owner: TImageEnIO; InMethod: TIEIOMethodType_LoadFromURLRetBool; const in_URL: WideString; dummy: Double);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieLoadFromURLRetBool;
fMethod_LoadFromURLRetBool := InMethod;
p_URL := in_URL;
Init;
end;
constructor TIEIOThread.CreateAcquire(owner: TImageEnIO; InMethod: TIEIOMethodType_Acquire; bResetParams: Boolean);
begin
inherited Create(TIEIOTHREAD_STARTMODE);
fOwner := Owner;
fMethodType := ieAcquire;
fMethod_Acquire := InMethod;
p_ResetParams := bResetParams;
Init;
end;
procedure TIEIOThread.Execute;
begin
fThreadID := GetCurrentThreadID;
try
case fMethodType of
ieLoadSaveFile : fMethod_LoadSaveFile(p_nf);
ieLoadSaveFileIF : fMethod_LoadSaveFileIF(p_nf, p_ImageFormat);
ieLoadSaveStream : fMethod_LoadSaveStream(p_stream);
ieLoadSaveFileRetInt : fMethod_LoadSaveFileRetInt(p_nf);
ieLoadSaveFileRetBool : fMethod_LoadSaveFileRetBool(p_nf);
ieLoadSaveFileIFRetBool : fMethod_LoadSaveFileIFRetBool(p_nf, p_ImageFormat);
ieLoadSaveStreamRetInt : fMethod_LoadSaveStreamRetInt(p_stream);
ieLoadSaveStreamRetBool : fMethod_LoadSaveStreamRetBool(p_stream);
ieLoadSaveFileFFRetBool : fMethod_LoadSaveFileFFRetBool(p_nf, p_fileformat);
ieLoadSaveStreamFF : fMethod_LoadSaveStreamFF(p_stream, p_FileFormat);
ieLoadSaveStreamFTRetBool : fMethod_LoadSaveStreamFTRetBool(p_stream, p_FileFormat);
ieCaptureFromScreen : fMethod_CaptureFromScreen(p_Source, p_mouseCursor);
ieLoadSaveIndexRetBool : fMethod_LoadSaveIndexRetBool(p_index);
ieImportMetaFileRetBool : fMethod_ImportMetaFileRetBool(p_nf, p_width, p_height, p_withalpha);
ieLoadFromURLRetBool : fMethod_LoadFromURLRetBool(p_URL);
ieAcquire : fMethod_Acquire(p_ResetParams);
end;
except
fOwner.Aborting := true;
end;
FreeOnTerminate := true;
fOwner.fAsyncThreadsCS.Enter();
fThreadList.Remove(self);
if fThreadList.Count = 0 then
Windows.SetEvent(fOwner.fAsyncThreadsFinishEvent);
fOwner.fAsyncThreadsCS.Leave();
end;
// end of TIEIOThread
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnIO.LoadFromURL
<FM>Declaration<FC>
function LoadFromURL(const URL: WideString): Boolean;
<FM>Description<FN>
Loads the image from the internet using the HTTP or FTP protocol.
Password authentication for HTTP is NOT supported, while it is necessary for FTP (even if connecting to an anonymous server).
<FC>URL<FN> must be in the format:
'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.
<FM>Example<FC>
// load from standard port 80
ImageEnView.IO.LoadFromURL('http://www.imageen.com/image.jpg');
// load from port 8080
ImageEnView.IO.LoadFromURL('http://www.imageen.com:8080/image.jpg');
// load from FTP
ImageEnView.IO.LoadFromURL('ftp://space:shuttle@ftp.imageen.com/Pictures/test.jpg')
!!}
function TImageEnIO.LoadFromURL(const URL: WideString): Boolean;
var
ms: TMemoryStream;
FileExt: string;
FileFormat: TIOFileType;
begin
Result := False;
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadFromURLRetBool(self, LoadFromURL, URL, 0);
Result := True;
exit;
end;
fAborting := false;
ms := TMemoryStream.Create;
try
if not IEGetFromURL(URL, ms, IEGlobalSettings().ProxyAddress, IEGlobalSettings().ProxyUser, IEGlobalSettings().ProxyPassword, fOnIntProgress, self, @fAborting, FileExt) then
begin
fAborting := true;
DoFinishWork;
end
else
begin
ms.Position := 0;
FileFormat := FindStreamFormat( ms );
if FileFormat = ioUnknown then
FileFormat := IEFilenameToFileFormat( URL );
Result := LoadFromStream( ms, FileFormat ); // this handles other tasks, such as IEBitmap sync, OnFinishWork, Update
end;
finally
FreeAndNil(ms);
end;
end;
// load from url
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TImageEnIO.DoAcquireBitmap(ABitmap: TIEBitmap; ImDpiX, ImDpiY: integer; var Handled: boolean);
begin
if assigned(fOnAcquireBitmap) then
fOnAcquireBitmap(self, ABitmap, ImDpiX, ImDpiY, Handled);
end;
procedure TImageEnIO.TWMultiCallBack(Bitmap: TIEBitmap; var IOParams: TObject; ImDpiX, ImDpiY: integer);
var
bHandled: boolean; // Flag indicating whether the user has handled the acquired bitmap themselves
begin
if not MakeConsistentBitmap([]) then
exit;
bHandled := false;
DoAcquireBitmap(Bitmap, ImDpiX, ImDpiY, bHandled);
if not bHandled then
begin
IOParams := Params;
fIEBitmap.Assign(Bitmap);
if fAutoAdjustDPI then
AdjustDPI;
Update();
end;
end;
procedure TImageEnIO.TWCloseCallBack;
begin
fgrec := nil;
if assigned(fOnAcquireClose) then
fOnAcquireClose(self);
end;
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnIO.TwainAcquireOpen
<FM>Declaration<FC>
function TwainAcquireOpen : boolean;
<FM>Description<FN>
Opens a connection to the selected scanner. It commonly used to perform a modeless acquisition from a Twain device. The result is false if it fails.
Whenever ImageEn gets an image, the <A TImageEnIO.OnAcquireBitmap> event occurs.
See also: <A TImageEnIO.TwainAcquireClose>
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\Twain\TwainDemo.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnIO.TwainAcquireOpen;
...
ImageEnIO.TwainAcquireClose;
!!}
function TImageEnIO.TwainAcquireOpen: boolean;
begin
if (not assigned(fgrec)) and assigned(fImageEnView) then
begin
fAborting := false;
fTwainParams.FreeResources;
fTwainParams.LastError := 0;
fTwainParams.LastErrorStr := '';
fgrec := IETWAINAcquireOpen(TWCloseCallBack, TWMultiCallBack, fTwainParams, @fTwainParams.TwainShared, fParams, fImageEnView, NativePixelFormat);
result := fgrec <> nil;
end
else
result := false;
end;
// Legacy interface to TwainAcquireOpen
function TImageEnIO.AcquireOpen: boolean;
begin
result := TwainAcquireOpen;
end;
{$ENDIF}
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnIO.TwainAcquireClose
<FM>Declaration<FC>
procedure TwainAcquireClose;
<FM>Description<FN>
Closes a connection to a Twain device, which was opened with <A TImageEnIO.TwainAcquireOpen>.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\Twain\TwainDemo.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnIO.TwainAcquireOpen;
...
ImageEnIO.TwainAcquireClose;
!!}
procedure TImageEnIO.TwainAcquireClose;
begin
if fgrec <> nil then
begin
IETWAINAcquireClose(fgrec);
fgrec := nil;
end;
end;
// Legacy interface to TwainAcquireClose
procedure TImageEnIO.AcquireClose;
begin
TwainAcquireClose;
end;
{$ENDIF}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
{!!
<FS>TImageEnIO.ThreadsCount
<FM>Declaration<FC>
property ThreadsCount: Integer;
<FM>Description<FN>
Returns the count of currently active threads. Valid only if <A TImageEnIO.AsyncMode> is True.
!!}
function TImageEnIO.GetThreadsCount: integer;
begin
fAsyncThreadsCS.Enter();
result := fAsyncThreads.Count;
fAsyncThreadsCS.Leave();
end;
{!!
<FS>TImageEnIO.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: <FC>ieThreshold<FN>
!!}
procedure TImageEnIO.SetDefaultDitherMethod(Value: TIEDitherMethod);
begin
if assigned(fIEBitmap) then
fIEBitmap.DefaultDitherMethod := Value;
fDefaultDitherMethod := Value;
end;
{!!
<FS>TImageEnIO.Bitmap
<FM>Declaration<FC>
property Bitmap: TBitmap; (Read-only)
<FM>Description<FN>
References the bitmap contained in TImageEnIO, <A TImageEnView> or <A TImageEnMView>.
<FM>Example<FC>
// Use the standard LoadFromFile method of TBitmap
ImageEnView1.IO.Bitmap.LoadFromFile('C:\my.bmp');
ImageEnView1.IO.Bitmap.PixelFormat := pf24bit;
ImageEnView1.Update;
!!}
function TImageEnIO.GetBitmap: TBitmap;
begin
if assigned(fIEBitmap) and (fIEBitmap.Location = ieTBitmap) then
result := fIEBitmap.VclBitmap
else
result := fBitmap;
end;
{!!
<FS>TImageEnIO.SaveToStreamICO
<FM>Declaration<FC>
procedure SaveToStreamICO(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in ICO format. ICO format allows storing multiple images with several resolutions and sizes.
ImageEn creates for you the sub-images to save; you have only to set the <A TImageEnIO.Params>.<A TIOParams.ICO_BitCount> and Params.<A TIOParams.ICO_Sizes> arrays.
To control each image separately, use the <A IEWriteICOImages> function.
<FM>Example<FC>
// save the current image in 'output.ico', It will contain three images with 64x64 32bit (24bit +alphachannel), 32x32 256 colors and 32x32 16 colors
// 64x64 x32bit
ImageEnView.IO.Params.ICO.BitCount[0] := 32;
ImageEnView.IO.Params.ICO.Sizes[0].cx := 64;
ImageEnView.IO.Params.ICO.Sizes[0].cy := 64;
// 32x32 x8bit
ImageEnView.IO.Params.ICO.BitCount[1] := 8;
ImageEnView.IO.Params.ICO.Sizes[1].cx := 32;
ImageEnView.IO.Params.ICO.Sizes[1].cy := 32;
// 32x32 x4bit
ImageEnView.IO.Params.ICO.BitCount[2] := 4;
ImageEnView.IO.Params.ICO.Sizes[2].cx := 32;
ImageEnView.IO.Params.ICO.Sizes[2].cy := 32;
// I don't want other images
ImageEnView.IO.Params.ICO.BitCount[3] := 0;
ImageEnView.IO.Params.ICO.Sizes[3].cx := 0;
ImageEnView.IO.Params.ICO.Sizes[3].cy := 0;
// save
ImageEnView.IO.SaveToFile('D:\output.ico');
!!}
procedure TImageEnIO.SaveToStreamICO(Stream: TStream);
var
Progress: TProgressRec;
icount: integer;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamICO, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
icount := 0;
while (icount <= high(Params.ICO_Sizes)) and (Params.ICO_Sizes[icount].cx > 0) do
inc(icount);
ICOWriteStream(Stream, fIEBitmap, fParams, Progress, slice(Params.ICO_Sizes, icount), slice(Params.ICO_BitCount, icount));
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToFileICO
<FM>Declaration<FC>
procedure SaveToFileICO(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in ICO format. ICO format allows storing multiple images with different resolutions and sizes.
<FC>FileName<FN> is the file name including extension.
ImageEn creates for you the sub-images to save, you have only to set the <A TImageEnIO.Params>.<A TIOParams.ICO_BitCount> and Params.<A TIOParams.ICO_Sizes> arrays.
To control each image separately, use the <A IEWriteICOImages> function.
Note: If an internal save error is encountered <A TImageEnIO.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\FullApps\PlainIconEditor\PlainIconEditor.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// save the current image in 'output.ico', It will contain three images with 64x64 32bit (24bit +alphachannel), 32x32 256 colors and 32x32 16 colors
// 64x64 x32bit
ImageEnView.IO.Params.ICO.BitCount[0] := 32;
ImageEnView.IO.Params.ICO.Sizes[0].cx := 64;
ImageEnView.IO.Params.ICO.Sizes[0].cy := 64;
// 32x32 x8bit
ImageEnView.IO.Params.ICO.BitCount[1] := 8;
ImageEnView.IO.Params.ICO.Sizes[1].cx := 32;
ImageEnView.IO.Params.ICO.Sizes[1].cy := 32;
// 32x32 x4bit
ImageEnView.IO.Params.ICO.BitCount[2] := 4;
ImageEnView.IO.Params.ICO.Sizes[2].cx := 32;
ImageEnView.IO.Params.ICO.Sizes[2].cy := 32;
// I don't want other images
ImageEnView.IO.Params.ICO.BitCount[3] := 0;
ImageEnView.IO.Params.ICO.Sizes[3].cx := 0;
ImageEnView.IO.Params.ICO.Sizes[3].cy := 0;
// save
ImageEnView.IO.SaveToFile('D:\output.ico');
!!}
procedure TImageEnIO.SaveToFileICO(const FileName: WideString);
var
Progress: TProgressRec;
fs: TIEWideFileStream;
icount: integer;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileICO, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
icount := 0;
while (icount <= high(Params.ICO_Sizes)) and (Params.ICO_Sizes[icount].cx > 0) do
inc(icount);
ICOWriteStream(fs, fIEBitmap, fParams, Progress, slice(Params.ICO_Sizes, icount), slice(Params.ICO_BitCount, icount));
fParams.FileName := FileName;
fParams.FileType := ioICO;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{$IFDEF IEINCLUDEIEXACQUIRE}
{!!
<FS>TImageEnIO.WIAParams
<FM>Declaration<FC>
property WIAParams: <A TIEWia>;
<FM>Description<FN>
Provides access to WIA parameters and allows you to show dialogs and control WIA devices.
Note: Use WIAParams only when you need access to WIA specific functionality (when <A TImageEnIO.SelectedAcquireSource>.Api is ieaWIA). For generic access to all image acquisitions sources (Twain, WIA, etc.) use <A TImageEnIO.AcquireParams> instead.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageAcquisition\WIAScanner\WIAScanner.dpr </C> </R>
</TABLE>
<FM>Examples<FC>
// select first device, set black/white (with threshold) and capture
ImageEnView.IO.WIAParams.SetItemProperty(WIA_IPA_DATATYPE, WIA_DATA_THRESHOLD, nil);
if ImageEnView1.IO.SetSource(ieaWIA, Default_Device) then
ImageEnView1.IO.Acquire;
// set dpi = 150 then capture
ImageEnView.IO.WIAParams.SetItemProperty(WIA_IPS_XRES, 150, nil);
ImageEnView.IO.WIAParams.SetItemProperty(WIA_IPS_YRES, 150, nil);
if ImageEnView1.IO.SetSource(ieaWIA, Default_Device) then
ImageEnView1.IO.Acquire;
<FM>See Also<FN>
- <A TIEWia>
- <A TImageEnIO.AcquireParams>
- <A TImageEnIO.SelectedAcquireSource>
!!}
function TImageEnIO.GetWIAParams: TIEWia;
begin
if not assigned(fWIA) then
begin
fWIA := TIEWia.Create(self);
fWIA.OnProgress := WiaOnProgress;
end;
result := fWIA;
end;
function TImageEnIO.WiaOnProgress(Percentage: integer): boolean;
begin
fOnIntProgress(self, Percentage); // fOnIntProgress is always assigned
result := not fAborting;
end;
{$ENDIF}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TImageEnIO.SyncLoadFromStreamWBMP(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
WBMPReadStream(Stream, fIEBitmap, fParams, Progress, false);
CheckDPI;
fParams.FileName := '';
fParams.FileType := ioWBMP;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileWBMP
<FM>Declaration<FC>
function LoadFromFileWBMP(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a WBMP (Wireless bitmap) file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not WBMP format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
!!}
function TImageEnIO.LoadFromFileWBMP(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileWBMP, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamWBMP( fs );
fParams.FileName := Filename;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamWBMP
<FM>Declaration<FC>
function LoadFromStreamWBMP(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a WBMP (Wireless bitmap) file. The result will be false if an error is encountered, e.g. the file in the stream is not WBMP format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamWBMP(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamWBMP, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamWBMP( Stream );
end;
end;
{!!
<FS>TImageEnIO.SaveToFileWBMP
<FM>Declaration<FC>
procedure SaveToFileWBMP(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in WBMP (Wireless bitmap) format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
!!}
procedure TImageEnIO.SaveToFileWBMP(const FileName: WideString);
var
Progress: TProgressRec;
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileWBMP, FileName);
exit;
end;
try
fAborting := true; // So that fAborting is True if the file is not found
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fs := TIEWideFileStream.Create(FileName, fmCreate);
fAborting := false;
try
WBMPWriteStream(fs, fIEBitmap, fParams, Progress);
fParams.FileName := FileName;
fParams.FileType := ioWBMP;
finally
FreeAndNil(fs);
end;
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamWBMP
<FM>Declaration<FC>
procedure SaveToStreamWBMP(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in WBMP (Wireless bitmap) format.
!!}
procedure TImageEnIO.SaveToStreamWBMP(Stream: TStream);
var
Progress: TProgressRec;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamWBMP, Stream);
exit;
end;
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
WBMPWriteStream(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.CreatePSFile
<FM>Declaration<FC>
procedure CreatePSFile(const FileName: WideString);
<FM>Description<FN>
Creates a new, empty PostScript file of the specified filename. You can add pages using <A TImageEnIO.SaveToPS> and when complete, close the file using <A TImageEnIO.ClosePSFile>.
Note: All images in the resulting PostScript file will be aligned to the upper-left corner of the paper.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\PDFBuilder\PdfBuilder.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.CreatePSFile( 'D:\output.ps' );
// load and save page 1
ImageEnView1.IO.LoadFromFile('C:\page1.tiff');
ImageEnView1.IO.Params.PS_Compression := ioPS_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPS;
// load and save page 2
ImageEnView1.IO.LoadFromFile('C:\page2.tiff');
ImageEnView1.IO.Params.PS_Compression := ioPS_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPS;
...Other pages...
// close PS file
ImageEnView1.IO.ClosePSFile;
!!}
procedure TImageEnIO.CreatePSFile(const FileName: WideString);
begin
fAborting := False;
fPS_stream := TIEWideFileStream.Create(FileName, fmCreate);
fPS_handle := IEPostScriptCreate(fPS_stream, fParams);
end;
{!!
<FS>TImageEnIO.SaveToPS
<FM>Declaration<FC>
procedure SaveToPS;
<FM>Description<FN>
Saves the current image to a PostScript file opened using <A TImageEnIO.CreatePSFile>.
Note: All images in the resulting PostScript file will be aligned to the upper-left corner of the paper.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\PDFBuilder\PdfBuilder.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.CreatePSFile( 'D:\output.ps' );
// load and save page 1
ImageEnView1.IO.LoadFromFile('C:\page1.tiff');
ImageEnView1.IO.Params.PS_Compression := ioPS_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPS;
// load and save page 2
ImageEnView1.IO.LoadFromFile('C:\page2.tiff');
ImageEnView1.IO.Params.PS_Compression := ioPS_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPS;
...Other pages...
// close PS file
ImageEnView1.IO.ClosePSFile;
!!}
procedure TImageEnIO.SaveToPS;
var
Progress: TProgressRec;
begin
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
IEPostScriptSave(fPS_handle, fPS_stream, fIEBitmap, fParams, Progress);
end;
{!!
<FS>TImageEnIO.ClosePSFile
<FM>Declaration<FC>
procedure ClosePSFile;
<FM>Description<FN>
Closes a PostScript file opened using <A TImageEnIO.CreatePSFile>.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\PDFBuilder\PdfBuilder.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.CreatePSFile( 'output.ps' );
// load and save page 1
ImageEnView1.IO.LoadFromFile('C:\page1.tiff');
ImageEnView1.IO.Params.PS_Compression := ioPS_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPS;
// load and save page 2
ImageEnView1.IO.LoadFromFile('C:\page2.tiff');
ImageEnView1.IO.Params.PS_Compression := ioPS_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPS;
...Other pages...
// close PS file
ImageEnView1.IO.ClosePSFile;
<FM>See Also<FN>
- <A TImageEnIO.CreatePSFile>
- <A TImageEnIO.SaveToPS>
!!}
procedure TImageEnIO.ClosePSFile;
begin
if fPS_handle <> nil then
IEPostScriptClose(fPS_handle, fPS_stream);
if assigned(fPS_stream) then
FreeAndNil(fPS_stream);
fPS_stream := nil;
fPS_handle := nil;
end;
procedure TImageEnIO.SyncSaveToStreamPS(Stream: TStream);
var
Progress: TProgressRec;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
IEPostScriptSaveOneStep(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamPS
<FM>Declaration<FC>
procedure SaveToStreamPS(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in PostScript format. The resulting file will have only one page.
!!}
procedure TImageEnIO.SaveToStreamPS(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamPS, Stream);
end
else
begin
SyncSaveToStreamPS(Stream);
end;
end;
{!!
<FS>TImageEnIO.SaveToFilePS
<FM>Declaration<FC>
procedure SaveToFilePS(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in PostScript format.
<FC>FileName<FN> is the file name including extension.
If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
Note: The created file will have only one page. See <A TImageEnIO.CreatePSFile> to create multi-page PS files.
<FM>Example<FC>
ImageEnView1.IO.LoadFromFile('D:\input.bmp');
ImageEnView1.IO.SaveToFilePS('D:\output.ps');
!!}
procedure TImageEnIO.SaveToFilePS(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFilePS, FileName);
exit;
end;
fs := TIEWideFileStream.Create(FileName, fmCreate);
try
SyncSaveToStreamPS(fs);
fParams.FileName := FileName;
fParams.FileType := ioPS;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.CreatePDFFile
<FM>Declaration<FC>
procedure CreatePDFFile(const FileName: WideString);
<FM>Description<FN>
Creates a new, empty Adobe PDF file of the specified filename. You can add pages using <A TImageEnIO.SaveToPDF> and when complete, close the file using <A TImageEnIO.ClosePDFFile>.
Note: All images in the resulting PDF file will be aligned to the upper-left corner of the paper.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\PDFBuilder\PdfBuilder.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.CreatePDFFile( 'D:\output.pdf' );
// load and save page 1
ImageEnView1.IO.LoadFromFile('C:\page1.tiff');
ImageEnView1.IO.Params.PDF_Compression := ioPDF_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPDF;
// load and save page 2
ImageEnView1.IO.LoadFromFile('C:\page2.tiff');
ImageEnView1.IO.Params.PDF_Compression := ioPDF_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPDF;
...Other pages...
// close PDF file
ImageEnView1.IO.ClosePDFFile;
!!}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnIO.CreatePDFFile(const FileName: WideString);
begin
fAborting := False;
fPDF_stream := TIEWideFileStream.Create(FileName, fmCreate);
fPDF_handle := IEPDFCreate(fParams);
end;
{$endif}
{!!
<FS>TImageEnIO.SaveToPDF
<FM>Declaration<FC>
procedure SaveToPDF;
<FM>Description<FN>
Saves the current image to the active Adobe PDF file, opened using <A TImageEnIO.CreatePDFFile>.
Note: All images in the resulting PDF file will be aligned to the upper-left corner of the paper.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\PDFBuilder\PdfBuilder.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.CreatePDFFile( 'D:\output.pdf' );
// load and save page 1
ImageEnView1.IO.LoadFromFile('C:\page1.tiff');
ImageEnView1.IO.Params.PDF_Compression := ioPDF_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPDF;
// load and save page 2
ImageEnView1.IO.LoadFromFile('C:\page2.tiff');
ImageEnView1.IO.Params.PDF_Compression := ioPDF_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPDF;
...Other pages...
// close PDF file
ImageEnView1.IO.ClosePDFFile;
!!}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnIO.SaveToPDF;
var
Progress: TProgressRec;
begin
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
IEPDFSave(fPDF_handle, fIEBitmap, fParams, Progress);
end;
{$endif}
{!!
<FS>TImageEnIO.ClosePDFFile
<FM>Declaration<FC>
procedure ClosePDFFile;
<FM>Description<FN>
Closes the active Adobe PDF file, opened using <A TImageEnIO.CreatePDFFile>.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\PDFBuilder\PdfBuilder.dpr </C> </R>
</TABLE>
<FM>Example<FC>
ImageEnView1.IO.CreatePDFFile( 'D:\output.pdf' );
// load and save page 1
ImageEnView1.IO.LoadFromFile('C:\page1.tiff');
ImageEnView1.IO.Params.PDF_Compression := ioPDF_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPDF;
// load and save page 2
ImageEnView1.IO.LoadFromFile('C:\page2.tiff');
ImageEnView1.IO.Params.PDF_Compression := ioPDF_G4FAX; // G4Fax compression
ImageEnView1.IO.SaveToPDF;
...Other pages...
// close PDF file
ImageEnView1.IO.ClosePDFFile;
<FM>See Also<FN>
- <A TImageEnIO.CreatePDFFile>
- <A TImageEnIO.SaveToPDF>
!!}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnIO.ClosePDFFile;
begin
if fPDF_handle <> nil then
IEPDFClose(fPDF_handle, fPDF_stream, fParams);
if assigned(fPDF_stream) then
FreeAndNil(fPDF_stream);
fPDF_stream := nil;
fPDF_handle := nil;
end;
{$endif}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnIO.SyncSaveToStreamPDF(Stream: TStream);
var
Progress: TProgressRec;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if (fIEBitmap.pixelformat <> ie24RGB) and (fIEBitmap.PixelFormat <> ie1g) then
fIEBitmap.PixelFormat := ie24RGB;
IEPDFSaveOneStep(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{$endif}
{!!
<FS>TImageEnIO.SaveToStreamPDF
<FM>Declaration<FC>
procedure SaveToStreamPDF(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in Adobe PDF format. The resulting file will have only one page.
!!}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnIO.SaveToStreamPDF(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamPDF, Stream);
end
else
begin
SyncSaveToStreamPDF(Stream);
end;
end;
{$endif}
{!!
<FS>TImageEnIO.SaveToFilePDF
<FM>Declaration<FC>
procedure SaveToFilePDF(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in Adobe PDF format.
<FC>FileName<FN> is the file name including extension.
If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
Note: The created file will have only one page. See <A TImageEnIO.CreatePDFFile> to create multi-page PDF files.
<FM>Example<FC>
ImageEnView1.IO.LoadFromFile('C:\input.bmp');
ImageEnView1.IO.SaveToFilePDF('D:\output.pdf');
!!}
{$ifdef IEINCLUDEPDFWRITING}
procedure TImageEnIO.SaveToFilePDF(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFilePDF, FileName);
exit;
end;
fs := TIEWideFileStream.Create(FileName, fmCreate);
try
SyncSaveToStreamPDF(fs);
fParams.FileName := FileName;
fParams.FileType := ioPDF;
finally
FreeAndNil(fs);
end;
end;
{$endif}
{$IFDEF IEINCLUDEDIRECTSHOW}
{!!
<FS>TImageEnIO.DShowParams
<FM>Declaration<FC>
property DShowParams: <A TIEDirectShow>;
<FM>Description<FN>
DShowParams is a TIEDirectShow instance which allows control of some Direct Show features, such as video capture, audio capture, multimedia files capture as well video rendering, and multimedia file writing.
<FM>Demos<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\VideoCapture\DirectShow1\DShow.dpr </C> </R>
<R> <C_IMG_DEMO> <C>Demos\VideoCapture\DirectShow2\DShowCap.dpr </C> </R>
<R> <C_IMG_DEMO> <C>Demos\VideoCapture\VideoEffects\VideoEffects.dpr </C> </R>
<R> <C_IMG_DEMO> <C>Demos\Display\VideoPlayer\VideoPlayer.dpr </C> </R>
</TABLE>
<FM>Examples<FC>
Capture Skeleton
// Fills ComboBox1 with the names of all video capture inputs
ComboBox1.Items.Assign( ImageEnView1.IO.DShowParams.VideoInputs );
// Select the first video input available
ImageEnView1.IO.DShowParams.SetVideoInput( 0 );
// Enables frame grabbing
// ImageEnView1.OnDShowNewFrame event occurs for each frame acquired
ImageEnView1.IO.DShowParams.EnableSampleGrabber := True;
// connect to the video input: this begins video capture
ImageEnView1.IO.DShowParams.Connect;
...
// Disconnect the video input
ImageEnView1.IO.DShowParams.Disconnect;
Capture a frame
// We are inside the OnDShowNewFrame event:
procedure Tfmain.ImageEnView1DShowNewFrame(Sender: TObject);
begin
// copy current sample to ImageEnView bitmap
ImageEnView1.IO.DShowParams.GetSample(ImageEnView1.IEBitmap);
// refresh ImageEnView1
ImageEnView1.Update;
end;
Setting video capture size
// We'd like to acquire 640x480 frames
ImageEnView1.IO.DShowParams.SetCurrentVideoFormat( 640, 480, '' );
Select a TV Tuner channel
// We want channel 15
ImageEnView1.IO.DShowParams.TunerChannel := 15;
Showing capture card dialogs
// Show video dialog
ImageEnView1.IO.DShowParams.ShowPropertyPages(iepVideoInput, ietFilter);
// Show video source dialog
ImageEnView1.IO.DShowParams.ShowPropertyPages(iepVideoInputSource, ietFilter);
// Show tuner dialog
ImageEnView1.IO.DShowParams.ShowPropertyPages(iepTuner, ietFilter);
// Show format dialog
ImageEnView1.IO.DShowParams.ShowPropertyPages(iepVideoInput, ietOutput);
Read from a multimedia file, and save with another compression
ImageEnView1.IO.DShowParams.FileInput := 'input.avi';
ImageEnView1.IO.DShowParams.FileOutput := 'output.avi';
ImageEnView1.IO.DShowParams.SetVideoCodec( ... );
ImageEnView1.IO.DShowParams.SetAudioCodec( ... );
ImageEnView1.IO.DShowParams.EnableSampleGrabber := True;
ImageEnView1.IO.DShowParams.Connect;
See the \VideoCapture\DirectShow1\ and \VideoCapture\DirectShow2\ demos for more info.
!!}
function TImageEnIO.GetDShowParams: TIEDirectShow;
begin
if not assigned(fDShow) then
begin
fDShow := TIEDirectShow.Create;
if assigned(fImageEnView) then
begin
fDShow.SetNotifyWindow(fImageEnView.Handle, IEM_NEWFRAME, IEM_EVENT)
end;
end;
result := fDShow;
end;
{$ENDIF}
{$IFDEF IEINCLUDEMEDIAFOUNDATION}
{!!
<FS>TImageEnIO.MediaFoundationSourceReader
<FM>Declaration<FC>
property MediaFoundationSourceReader: <A TIEMediaFoundationSourceReader>;
<FM>Description<FN>
MediaFoundationSourceReader is a TIEMediaFoundationSourceReader instance which allows capture samples from webcams, multimedia files and URLs.
This is a minimal setup to capture from a webcam (the first webcam, using first proposed media type):
<FC>
ImageEnView1.IO.MediaFoundationSourceReader.SetVideoInput(0); // select first video input (first webcam)
ImageEnView1.IO.MediaFoundationSourceReader.SetSelectedStreams('Video', true); // enable first video stream
ImageEnView1.IO.MediaFoundationSourceReader.SelectMediaType('Video', 0); // select first media type of the first video stream
ImageEnView1.IO.MediaFoundationSourceReader.StartCapture(); // start capture
// handler for TImageEnView.OnMediaFoundatioNotify event
procedure TForm1.ImageEnVect1MediaFoundationNotify(Sender, MediaFoundationObject: TObject; NotifyType: TIEMediaFountationNotifyType);
var
sample: TIEMFReceivedSample;
begin
if NotifyType = iemfnFRAME then // is this a frame?
begin
sample := ImageEnView1.IO.MediaFoundationSourceReader.GetNextSample(); // retrieve frame sample
try
sample.DecodeSample(ImageEnView1.IEBitmap); // convert frame sample to bitmap
ImageEnView1.Update(); // update TImageEnView to show the new bitmap
finally
sample.Free(); // free the sample
end;
end;
end;
<FN>
Look at VideoCapture\MediaFoundation demos for usage samples.
!!}
function TImageEnIO.GetMediaFoundationSourceReader(): TIEMediaFoundationSourceReader;
begin
if not assigned(fMediaFoundationSourceReader) then
begin
fMediaFoundationSourceReader := TIEMediaFoundationSourceReader.Create();
if assigned(fImageEnView) then
fMediaFoundationSourceReader.PushNotifyReceiver( TIEMediaFoundationReaderWindowNotifyReceiver.Create(fImageEnView.Handle, IEM_MEDIAFOUNDATION) );
end;
result := fMediaFoundationSourceReader;
end;
{$ENDIF}
procedure TImageEnIO.CheckDPI;
begin
if fParams.DpiX < 2 then
fParams.DpiX := IEGlobalSettings().DefaultDPIX;
if fParams.DpiY < 2 then
fParams.DpiY := IEGlobalSettings().DefaultDPIY;
end;
{$ifdef IEINCLUDERAWFORMATS}
function TImageEnIO.SyncLoadFromStreamRAW(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
IEReadCameraRAWStream(Stream, fIEBitmap, fParams, Progress, false);
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioRAW;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{$endif}
{$ifdef IEINCLUDERAWFORMATS}
{!!
<FS>TImageEnIO.LoadFromStreamRAW
<FM>Declaration<FC>
function LoadFromStreamRAW(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a digital camera Raw file. The result will be false if an error is encountered, e.g. the file in the stream is not a RAW format (<A TImageEnIO.Aborting> will be true).
!!}
function TImageEnIO.LoadFromStreamRAW(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamRAW, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamRAW(Stream);
end;
end;
{$endif}
{$ifdef IEINCLUDERAWFORMATS}
{!!
<FS>TImageEnIO.LoadFromFileRAW
<FM>Declaration<FC>
function LoadFromFileRAW(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a Digital Camera Raw file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not a camera RAW format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\CameraRaw\CameraRaw.dpr </C> </R>
</TABLE>
!!}
function TImageEnIO.LoadFromFileRAW(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileRAW, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamRAW(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{$endif}
{$ifdef IEINCLUDEDIRECTSHOW}
{!!
<FS>TImageEnIO.OpenMediaFile
<FM>Declaration<FC>
function OpenMediaFile(const FileName: WideString): Integer;
<FM>Description<FN>
Opens a video file using DirectShow. Supported file types are AVI, MPEG, WMV and other DirectX supported formats.
This method will open the file, but doesn't actually get an image. To get a frame use the <A TImageEnIO.LoadFromMediaFile> method.
To close the media file use <A TImageEnIO.CloseMediaFile>.
<FM>Example<FC>
// Save frame 10 as 'frame10.jpg'
ImageEnView1.IO.OpenMediaFile('C:\film.mpeg');
ImageEnView1.IO.LoadFromMediaFile(10);
ImageEnView1.IO.SaveToFile('D:\frame10.jpg');
ImageEnView1.IO.CloseMediaFile;
!!}
function TImageEnIO.OpenMediaFile(const FileName: WideString): Integer;
var
l: int64;
ww, hh: Integer;
fmt: AnsiString;
avgtime, ltime: int64;
begin
result := 0;
if assigned(fOpenMediaFile) then
CloseMediaFile;
fAborting := True;
fOpenMediaFile := TIEDirectShow.Create;
fOpenMediaFile.FileInput := AnsiString(FileName);
fOpenMediaFile.EnableSampleGrabber := True;
fOpenMediaFile.Connect;
fOpenMediaFile.Pause;
fOpenMediaFile.TimeFormat := TfTime;
ltime := fOpenMediaFile.Duration;
if (ltime = 0) then
exit;
fOpenMediaFile.TimeFormat := TfFrame;
l := fOpenMediaFile.Duration;
avgtime := fOpenMediaFile.GetAverageTimePerFrame;
if (l=ltime) and (avgtime <> 0) then
begin
l := l div avgtime;
fOpenMediaFileMul := avgtime;
end
else
fOpenMediaFileMul := 1;
fOpenMediaFileRate := (ltime/10000000) / l*1000;
fAborting := False;
fParams.MEDIAFILE_FrameCount := l;
fParams.FileType := ioUnknown;
ResetModified();
fParams.FileName := FileName; // this is important for TImageEnMView
fOpenMediaFile.GetCurrentVideoFormat(ww, hh, fmt);
fParams.Width := ww;
fParams.Height := hh;
fParams.OriginalWidth := ww;
fParams.OriginalHeight := hh;
result := l;
end;
{!!
<FS>TImageEnIO.CloseMediaFile
<FM>Declaration<FC>
procedure CloseMediaFile;
<FM>Description<FN>
Close a video file that was opened with <A TImageEnIO.OpenMediaFile>.
<FM>Example<FC>
// Save frame 10 as 'frame10.jpg'
ImageEnView1.IO.OpenMediaFile('C:\film.mpeg');
ImageEnView1.IO.LoadFromMediaFile(10);
ImageEnView1.IO.SaveToFile('D:\frame10.jpg');
ImageEnView1.IO.CloseMediaFile;
!!}
procedure TImageEnIO.CloseMediaFile;
begin
if assigned(fOpenMediaFile) then
begin
fOpenMediaFile.Disconnect;
FreeAndNil(fOpenMediaFile);
end;
end;
{!!
<FS>TImageEnIO.LoadFromMediaFile
<FM>Declaration<FC>
procedure LoadFromMediaFile(FrameIndex: Integer);
<FM>Description<FN>
Loads the specified frame from a media file that was opened using <A TImageEnIO.OpenMediaFile>.
The first frame has index 0.
<FM>Example<FC>
// Save frame 10 as 'frame10.jpg'
ImageEnView1.IO.OpenMediaFile('C:\film.mpeg');
ImageEnView1.IO.LoadFromMediaFile(10);
ImageEnView1.IO.SaveToFile('D:\frame10.jpg');
ImageEnView1.IO.CloseMediaFile;
!!}
procedure TImageEnIO.LoadFromMediaFile(FrameIndex: Integer);
begin
CheckHaveValidBitmap();
if assigned(fOpenMediaFile) then
begin
fParams.TIFF_ImageIndex := FrameIndex;
fParams.GIF_ImageIndex := FrameIndex;
fParams.DCX_ImageIndex := FrameIndex;
fOpenMediaFile.position := int64(FrameIndex) * int64(fOpenMediaFileMul);
fOpenMediaFile.GetSample( fIEBitmap );
fParams.MEDIAFILE_FrameDelayTime := fOpenMediaFileRate;
Update();
ResetModified();
end;
end;
{!!
<FS>TImageEnIO.IsOpenMediaFile
<FM>Declaration<FC>
function IsOpenMediaFile: Boolean;
<FM>Description<FN>
Returns True if <A TImageEnIO.OpenMediaFile> has a currently open file.
!!}
function TImageEnIO.IsOpenMediaFile: Boolean;
begin
result := assigned(fOpenMediaFile);
end;
{$endif}
function TImageEnIO.SyncLoadFromStreamBMPRAW(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
IERealRAWReadStream(Stream, fIEBitmap, fParams, Progress);
fParams.FileName := '';
fParams.FileType := ioBMPRAW;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamBMPRAW
<FM>Declaration<FC>
function LoadFromStreamBMPRAW(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a BmpRaw file. The result will be false if an error is encountered, e.g. the file in the stream is not BmpRaw format (<A TImageEnIO.Aborting> will be true).
Note: This is not the same as a digital camera Raw file, but a true "raw" format (named "BmpRaw" in ImageEn) where you can specify the channel order, placement, alignment, size, etc.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\RealRAW\RealRaw.dpr </C> </R>
</TABLE>
<FM>Examples<FC>
// load a RAW image, RGB, interleaved, 8 bit aligned, 1024x768
ImageEnView1.LegacyBitmap := False;
ImageEnView1.IEBitmap.Allocate(1024, 768, ie24RGB);
ImageEnView1.IO.Params.BMPRAW_ChannelOrder := coRGB;
ImageEnView1.IO.Params.BMPRAW_Planes := plInterleaved;
ImageEnView1.IO.Params.BMPRAW_RowAlign := 8;
ImageEnView1.IO.Params.BMPRAW_HeaderSize := 0;
ImageEnView1.IO.LoadFromStreamBMPRAW( stream );
// load a RAW image, CMYK, interleaved, 8 bit aligned, 1024x768
ImageEnView1.LegacyBitmap := False;
ImageEnView1.IEBitmap.Allocate(1024, 768, ieCMYK);
ImageEnView1.IO.Params.BMPRAW_ChannelOrder := coRGB;
ImageEnView1.IO.Params.BMPRAW_Planes := plInterleaved;
ImageEnView1.IO.Params.BMPRAW_RowAlign := 8;
ImageEnView1.IO.Params.BMPRAW_HeaderSize := 0;
ImageEnView1.IO.LoadFromStreamBMPRAW( stream );
!!}
function TImageEnIO.LoadFromStreamBMPRAW(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamBMPRAW, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamBMPRAW(Stream);
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileBMPRAW
<FM>Declaration<FC>
function LoadFromFileBMPRAW(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a BmpRaw file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not BmpRaw (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
Note: This is not the same as a digital camera Raw file, but a true "raw" format (named "BmpRaw" in ImageEn) where you can specify the channel order, placement, alignment, size, etc.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\RealRAW\RealRaw.dpr </C> </R>
</TABLE>
<FM>Examples<FC>
// load a RAW image, RGB, interleaved, 8 bit aligned, 1024x768
ImageEnView1.LegacyBitmap := False;
ImageEnView1.IEBitmap.Allocate(1024, 768, ie24RGB);
ImageEnView1.IO.Params.BMPRAW_ChannelOrder := coRGB;
ImageEnView1.IO.Params.BMPRAW_Planes := plInterleaved;
ImageEnView1.IO.Params.BMPRAW_RowAlign := 8;
ImageEnView1.IO.Params.BMPRAW_HeaderSize := 0;
ImageEnView1.IO.LoadFromFileBMPRAW('C:\input.dat');
// load a RAW image, CMYK, interleaved, 8 bit aligned, 1024x768
ImageEnView1.LegacyBitmap := False;
ImageEnView1.IEBitmap.Allocate(1024, 768, ieCMYK);
ImageEnView1.IO.Params.BMPRAW_ChannelOrder := coRGB;
ImageEnView1.IO.Params.BMPRAW_Planes := plInterleaved;
ImageEnView1.IO.Params.BMPRAW_RowAlign := 8;
ImageEnView1.IO.Params.BMPRAW_HeaderSize := 0;
ImageEnView1.IO.LoadFromFileBMPRAW('C:\input.dat');
!!}
function TImageEnIO.LoadFromFileBMPRAW(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileBMPRAW, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamBMPRAW(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
procedure TImageEnIO.SyncSaveToStreamBMPRAW(Stream: TStream);
var
Progress: TProgressRec;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
IERealRAWWriteStream(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamBMPRAW
<FM>Declaration<FC>
procedure SaveToStreamBMPRAW(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in BmpRaw format.
Note: This is not the same as a digital camera Raw file, but a true "raw" format (named "BmpRaw" in ImageEn) where you can specify the channel order, placement, alignment, size, etc.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\RealRAW\RealRaw.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// saves current image as RAW image
ImageEnView1.IO.Params.BMPRAW_ChannelOrder := coRGB;
ImageEnView1.IO.Params.BMPRAW_Planes := plPlanar;
ImageEnView1.IO.Params.BMPRAW_RowAlign := 8;
ImageEnView1.IO.SaveToStreamBMPRAW(stream);
!!}
procedure TImageEnIO.SaveToStreamBMPRAW(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamBMPRAW, Stream);
end
else
begin
SyncSaveToStreamBMPRAW(Stream);
end;
end;
{!!
<FS>TImageEnIO.SaveToFileBMPRAW
<FM>Declaration<FC>
procedure SaveToFileBMPRAW(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in BmpRaw format.
<FC>FileName<FN> is the file name including extension.
If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
Note: This is not the same as a digital camera Raw file, but a true "raw" format (named "BmpRaw" in ImageEn) where you can specify the channel order, placement, alignment, size, etc.
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\InputOutput\RealRAW\RealRaw.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// saves current image as RAW image
ImageEnView1.IO.Params.BMPRAW_ChannelOrder := coRGB;
ImageEnView1.IO.Params.BMPRAW_Planes := plPlanar;
ImageEnView1.IO.Params.BMPRAW_RowAlign := 8;
ImageEnView1.IO.SaveToFileBMPRAW('C:\output.dat');
!!}
procedure TImageEnIO.SaveToFileBMPRAW(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
if FileName='' then
exit;
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileBMPRAW, FileName);
exit;
end;
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmCreate);
SyncSaveToStreamBMPRAW(fs);
fParams.FileName := FileName;
fParams.FileType := ioBMPRAW;
finally
FreeAndNil(fs);
end;
end;
{$ifdef IEINCLUDERAWFORMATS}
{!!
<FS>TImageEnIO.LoadJpegFromFileCRW
<FM>Declaration<FC>
function LoadJpegFromFileCRW(const FileName: WideString): Boolean;
<FM>Description<FN>
Extract and load the large Jpeg encapsulated inside a CRW (Canon RAW) file. Result will be false if the file is not a recognized file type (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
<FM>Example<FC>
ImageEnView1.IO.LoadJpegFromFileCRW('C:\input.crw');
!!}
function TImageEnIO.LoadJpegFromFileCRW(const FileName: WideString): Boolean;
var
Progress: TProgressRec;
fs: TIEWideFileStream;
begin
Result := False;
if FileName='' then
exit;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
IECRWGetJpeg(fIEBitmap, fs);
fParams.FileName := FileName;
fParams.FileType := ioRAW;
Update();
finally
FreeAndNil(fs);
DoFinishWork;
Result := Not fAborting;
end;
end;
{$endif}
procedure TImageEnIO.DoIntProgress(Sender: TObject; per: integer);
begin
if assigned(fOnProgress) then
begin
if assigned(fImageEnView) and (fImageEnView.Parent <> nil) and IsInsideAsyncThreads then
begin
// we are inside a thread, so send a message to the parent TImageEnView component, if exists
{$ifdef IEHASTTHREADSTATICSYNCHRONIZE}
if not fImageEnView.HandleAllocated then // 3.0.2, to avoid deadlocks
TThread.Synchronize(nil, SyncGetHandle); // 3.0.1, 15/7/2008 - 13:55
{$endif}
PostMessage( fImageEnView.Handle, IEM_PROGRESS, per, 0);
end
else
fOnProgress(Sender, per);
end;
end;
procedure TImageEnIO.DoFinishWork;
begin
fOnIntProgress(self, 100); // fOnIntProgress is always assigned
if assigned(fOnFinishWork) then
begin
if assigned(fImageEnView) and (fImageEnView.Parent <> nil) and IsInsideAsyncThreads then
begin
// we are inside a thread, so send a message to the parent TImageEnView component, if exists
{$ifdef IEHASTTHREADSTATICSYNCHRONIZE}
if not fImageEnView.HandleAllocated then // 3.0.2, to avoid deadlocks
TThread.Synchronize(nil, SyncGetHandle); // 3.0.1, 15/7/2008 - 13:55
{$endif}
PostMessage( fImageEnView.Handle, IEM_FINISHWORK, 0, 0);
end
else
fOnFinishWork(self);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamPSD
<FM>Declaration<FC>
function LoadFromStreamPSD(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing an Adobe PSD file. The result will be false if an error is encountered, e.g. the file in the stream is not PSD format (<A TImageEnIO.Aborting> will be true).
PSD files can contain multiple layers. To load separated layers:<FC>
ImageEnView1.IO.Params.PSD_LoadLayers := True;
ImageEnView1.IO.LoadFromStreamPSD(stream);<FN>
To load only the merged/flattened image (default method):<FC>
ImageEnView1.IO.Params.PSD_LoadLayers := False;
ImageEnView1.IO.LoadFromStreamPSD(stream);<FN>
!!}
{$ifdef IEINCLUDEPSD}
function TImageEnIO.LoadFromStreamPSD(Stream: TStream): Boolean;
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamPSD, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamPSD(Stream);
end;
end;
{$endif}
{!!
<FS>TImageEnIO.LoadFromFilePSD
<FM>Declaration<FC>
function LoadFromFilePSD(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from an Adobe PSD file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not PSD format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
PSD files can contain multiple layers. To load separated layers:<FC>
ImageEnView1.IO.Params.PSD_LoadLayers := True;
ImageEnView1.IO.LoadFromFilePSD(filename);<FN>
To load only the merged/flattened image (default method):<FC>
ImageEnView1.IO.Params.PSD_LoadLayers := False;
ImageEnView1.IO.LoadFromFilePSD(filename);<FN>
<FM>Example<FC>
ImageEnView1.IO.Params.PSD_LoadLayers := True;
ImageEnView1.IO.LoadFromFilePSD('C:\input.psd');
!!}
{$ifdef IEINCLUDEPSD}
function TImageEnIO.LoadFromFilePSD(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFilePSD, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamPSD(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{$endif}
{$ifdef IEINCLUDEPSD}
function TImageEnIO.SyncLoadFromStreamPSD(Stream: TStream): Boolean;
var
Progress: TProgressRec;
layers: TList;
i, l: Integer;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
if Params.PSD_LoadLayers and Params.PSD_ReplaceLayers and assigned(fImageEnView) and (fImageEnView is TImageEnView) then
// working with TImageEnView, remove all layers
(fImageEnView as TImageEnView).LayersClear;
fIEBitmap.RemoveAlphaChannel;
layers := TList.Create;
IEReadPSD(Stream, fIEBitmap, fParams, Progress, fParams.PSD_LoadLayers, layers);
if Params.PSD_LoadLayers and assigned(fImageEnView) and (fImageEnView is TImageEnView) then
begin
// working with TImageEnView
if layers.Count > 0 then
begin
if Params.PSD_ReplaceLayers then
l := 0
else
l := (fImageEnView as TImageEnView).LayersAddEx( ielkImage, 0, 0, -1, -1, TIEBitmap.Create(0, 0), False, False );
// create a transparent layer 0 when the first layer is moved
with TIELayer(layers[0]) do
if (PosX <> 0) or (PosY <> 0) then
begin
(fImageEnView as TImageEnView).Layers[l].SetDefaults;
(fImageEnView as TImageEnView).Layers[l].Locked := True;
(fImageEnView as TImageEnView).Layers[l].Bitmap.Allocate(fParams.Width, fParams.Height);
(fImageEnView as TImageEnView).Layers[l].Bitmap.AlphaChannel.Fill(0);
(fImageEnView as TImageEnView).LayersAddEx( ielkImage, 0, 0, -1, -1, TIEBitmap.Create(0, 0), False, False );
inc(l);
end;
for i := 0 to layers.Count - 1 do
begin
if i > 0 then
l := (fImageEnView as TImageEnView).LayersAddEx( ielkImage, 0, 0, -1, -1, TIEBitmap.Create(0, 0), False, False );
if (fImageEnView as TImageEnView).LegacyBitmap then
(fImageEnView as TImageEnView).Layers[l].Assign( TIELayer(layers[i]) ) // TIELayer.Swap is not possible when using LegacyBitmap (causes memory leak)
else
(fImageEnView as TImageEnView).Layers[l].Swap( TIELayer(layers[i]) );
end;
end;
end
else
if (layers.Count = 1) and not fParams.GetThumbnail then
begin
// One layer or TImageEnIO
fIEBitmap.AlphaChannel.Assign( TIELayer(layers[0]).Bitmap.AlphaChannel );
if (fIEBitmap.Width <> fIEBitmap.AlphaChannel.Width) or (fIEBitmap.Height <> fIEBitmap.AlphaChannel.Height) then
begin
// an alpha channel can be moved and of different size
fIEBitmap.AlphaChannel.Resize(fIEBitmap.AlphaChannel.Width+TIELayer(layers[0]).PosX,
fIEBitmap.AlphaChannel.Height+TIELayer(layers[0]).PosY, 0, 0, iehRight, ievBottom);
fIEBitmap.AlphaChannel.Resize(fIEBitmap.Width, fIEBitmap.Height, 0, 0, iehLeft, ievTop);
end;
end;
for i := 0 to layers.count - 1 do
TIELayer(layers[i]).Free();
layers.Free();
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioPSD;
Update();
ResetModified( Params.PSD_LoadLayers );
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
{$endif}
{$ifdef IEINCLUDEPSD}
procedure TImageEnIO.SyncSaveToStreamPSD(Stream: TStream);
var
Progress: TProgressRec;
merged, view: TImageEnView;
layers: TList;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
if assigned(fImageEnView) and (fImageEnView is TImageEnView) then
view := (fImageEnView as TImageEnView)
else
view := nil;
if (view <> nil) then
begin
merged := TImageEnView.Create(nil);
merged.LegacyBitmap := False;
view.LayersDrawTo(merged.IEBitmap);
merged.IEBitmap.Location := ieMemory;
merged.IEBitmap.PixelFormat := view.Layers[0].Bitmap.PixelFormat;
layers := view.LayersList;
IEWritePSD(Stream, fParams, Progress, merged.IEBitmap, layers);
merged.free;
end
else
begin
layers := TList.Create;
IEWritePSD(Stream, fParams, Progress, fIEBitmap, layers);
layers.free;
end;
finally
DoFinishWork;
end;
end;
{$endif}
{!!
<FS>TImageEnIO.SaveToStreamPSD
<FM>Declaration<FC>
procedure SaveToStreamPSD(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in PSD format. PSD supports multiple layers, so it can store position and other useful info (like layer name). PSD also has a merged representation of the image to fast preview the merged result.
Note: You can also save layers in <L TImageEnIO.SaveToStreamIEN>IEN</L> and <L TImageEnIO.SaveToStreamSVG>SVG</L> format
!!}
{$ifdef IEINCLUDEPSD}
procedure TImageEnIO.SaveToStreamPSD(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamPSD, Stream);
end
else
begin
SyncSaveToStreamPSD(Stream);
end;
end;
{$endif}
{!!
<FS>TImageEnIO.SaveToFilePSD
<FM>Declaration<FC>
procedure SaveToFilePSD(const FileName: WideString);
<FM>Description<FN>
Saves the current image or all layers to a file in PSD format. PSD supports multiple layers, so it can store position and other useful info (like layer name).
PSD files also have a merged representation of the image to fast preview the merged result.
<FC>FileName<FN> is the file name including extension.
Notes:
- If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
- You can also save layers in <L TImageEnIO.SaveToFileIEN>IEN</L> and <L TImageEnIO.SaveToFileSVG>SVG</L> format
!!}
{$ifdef IEINCLUDEPSD}
procedure TImageEnIO.SaveToFilePSD(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFilePSD, FileName);
exit;
end;
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fParams.PSD_LargeDocumentFormat := IEFilenameInExtensions(string(FileName), '*.psb'); // automatically selec large document format for PSB
fs := TIEWideFileStream.Create(FileName, fmCreate);
SyncSaveToStreamPSD(fs);
fParams.FileName := FileName;
fParams.FileType := ioPSD;
finally
FreeAndNil(fs);
end;
end;
{$endif}
procedure TImageEnIO.SetPrintLogFile(v: String);
begin
if iegPrintLogFileName <> '' then
CloseFile(iegPrintLogFile);
iegPrintLogFileName := v;
if v <> '' then
begin
AssignFile(iegPrintLogFile, iegPrintLogFileName);
Rewrite(iegPrintLogFile);
end;
end;
function TImageEnIO.GetParams: TIOParams;
begin
if assigned( fIEBitmap ) and fIEBitmap.ParamsEnabled then
Result := fIEBitmap.Params
else
Result := fParams;
end;
function TImageEnIO.GetPrintLogFile: String;
begin
result := iegPrintLogFileName;
end;
{!!
<FS>TImageEnIO.ReplaceStreamTIFF
<FM>Declaration<FC>
function ReplaceStreamTIFF(Stream: TStream): integer;
<FM>Description<FN>
Save the current image into the specified multi-page TIFF file, replacing the image at the index specified by <A TImageEnIO.Params>.<A TIOParams.TIFF_ImageIndex>.
Note: The Stream position must be at the beginning of the TIFF content.
!!}
function TImageEnIO.ReplaceStreamTIFF(Stream: TStream): integer;
var
lpos: int64;
begin
lpos := Stream.Position;
TIFFDeleteImStream(Stream, fParams.TIFF_ImageIndex);
Stream.Position := lpos;
result := InsertToStreamTIFF(Stream);
end;
{$ifdef IEINCLUDEWIC}
{!!
<FS>TImageEnIO.LoadFromStreamHDP
<FM>Declaration<FC>
function LoadFromStreamHDP(Stream: TStream): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a Microsoft HD Photo file. The result will be false if an error is encountered, e.g. the file in the stream is not HDP format (<A TImageEnIO.Aborting> will be true).
Requires: Windows XP (SP2) with .Net 3.0, Windows Vista or newer.
!!}
function TImageEnIO.LoadFromStreamHDP(Stream: TStream): Boolean;
begin
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC LOADING
TIEIOThread.CreateLoadSaveStreamRetBool(self, LoadFromStreamHDP, Stream);
Result := True;
end
else
begin
Result := SyncLoadFromStreamHDP(Stream);
end;
end;
{!!
<FS>TImageEnIO.LoadFromFileHDP
<FM>Declaration<FC>
function LoadFromFileHDP(const FileName: WideString): Boolean;
<FM>Description<FN>
Loads an image from a Microsoft HD Photo file.
<FC>FileName<FN> is the file name including extension.
Result will be false if the file is not HDP format (and <A TImageEnIO.Aborting> will be false). Loading errors due to a file not being available will raise an exception.
Requires: Windows XP (SP2) with .Net 3.0, Windows Vista or newer.
!!}
function TImageEnIO.LoadFromFileHDP(const FileName: WideString): Boolean;
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC LOADING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFileRetBool(self, LoadFromFileHDP, FileName);
Result := True;
exit;
end;
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := SyncLoadFromStreamHDP(fs);
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamHDP
<FM>Declaration<FC>
procedure SaveToStreamHDP(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in Microsoft HD Photo file format.
Requires: Windows XP (SP2) with .Net 3.0, Windows Vista or newer.
!!}
procedure TImageEnIO.SaveToStreamHDP(Stream: TStream);
begin
CheckHaveValidBitmap();
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
// ASYNC SAVING
TIEIOThread.CreateLoadSaveStream(self, SaveToStreamHDP, Stream);
end
else
begin
SyncSaveToStreamHDP(Stream);
end;
end;
{!!
<FS>TImageEnIO.SaveToFileHDP
<FM>Declaration<FC>
procedure SaveToFileHDP(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in Microsoft HD Photo format.
<FC>FileName<FN> is the file name including extension.
Note: If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
Requires: Windows XP (SP2) with .Net 3.0, Windows Vista or newer.
!!}
procedure TImageEnIO.SaveToFileHDP(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
CheckHaveValidBitmap();
// ASYNC SAVING
if (not fIEBitmapCreated) and fAsyncMode and (not IsInsideAsyncThreads) then
begin
TIEIOThread.CreateLoadSaveFile(self, SaveToFileHDP, FileName);
exit;
end;
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmCreate);
SyncSaveToStreamHDP(fs);
fParams.FileName := FileName;
fParams.FileType := ioHDP;
finally
FreeAndNil(fs);
end;
end;
function TImageEnIO.SyncLoadFromStreamHDP(Stream: TStream): Boolean;
var
Progress: TProgressRec;
begin
{$IFDEF IEForceVarInitialization}
Result := False;
{$ENDIF}
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
fParams.ResetInfo;
fIEBitmap.RemoveAlphaChannel;
IEHDPRead(Stream, fIEBitmap, fParams, Progress, false);
CheckDPI;
if fAutoAdjustDPI then
AdjustDPI;
fParams.FileName := '';
fParams.FileType := ioHDP;
Update();
ResetModified();
finally
DoFinishWork;
Result := Not fAborting;
end;
end;
procedure TImageEnIO.SyncSaveToStreamHDP(Stream: TStream);
var
Progress: TProgressRec;
begin
try
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
if not MakeConsistentBitmap([]) then
exit;
IEHDPWrite(Stream, fIEBitmap, fParams, Progress);
finally
DoFinishWork;
end;
end;
{$endif} // HDP
{$ifdef IEINCLUDERESOURCEEXTRACTOR}
{!!
<FS>TImageEnIO.LoadFromResource
<FM>Declaration<FC>
procedure LoadFromResource(const ModulePath: WideString; const ResourceType: String; const ResourceName: String; Format: TIOFileType);
<FM>Description<FN>
Loads the specified image resource from PE files like EXE, DLL, OCX, ICL, BPL, etc.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>ModulePath<FN></C> <C>Specifies the path and filename of PE module.</C> </R>
<R> <C><FC>ResourceType<FN></C> <C>Resource type as string (ie 'Bitmap', 'Cursor').</C> </R>
<R> <C><FC>ResourceName<FN></C> <C>Resource name as string (ie 'INTRESOURCE:100', 'Hand').</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. ioUnknown should fail for BMP, ICO and CUR resources.</C> </R>
</TABLE>
See also: <A TIEResourceExtractor>
<FM>Example<FC>
// Load resource 143, in "Bitmap"s, from "explorer.exe" (should be a small Windows logo)
ImageEnView1.IO.LoadFromResource('explorer.exe', 'Bitmap', 'INTRESOURCE:143', ioBMP);
!!}
procedure TImageEnIO.LoadFromResource(const ModulePath: WideString; const ResourceType: String; const ResourceName: String; Format: TIOFileType);
var
re: TIEResourceExtractor;
buffer: Pointer;
bufferLen: Integer;
begin
re := TIEResourceExtractor.Create(ModulePath);
try
buffer := re.GetBuffer(AnsiString(ResourceType), AnsiString(ResourceName), bufferLen);
fParams.IsResource := true;
LoadFromBuffer(buffer, bufferLen, format);
finally
fParams.IsResource := false;
re.Free;
end;
end;
{$endif} // IEINCLUDERESOURCEEXTRACTOR
{!!
<FS>TImageEnIO.LoadFromFileIEN
<FM>Declaration<FC>
function LoadFromFileIEN(const FileName: WideString; Append: Boolean = False): Boolean;
<FM>Description<FN>
Loads an image from an ImageEn's native image format, which preserves the image and any layers.
<FC>FileName<FN> is the file name including extension. Result will be false if the file is not ImageEn format (and <A TImageEnIO.Aborting> will be true). Loading errors due to a file not being available will raise an exception.
If <FC>Append<FN> is True, the existing content is not cleared, i.e. layers in this file will be added to existing layers.
Notes:
- If the TImageEnIO is <L TImageEnIO.AttachedImageEn>attached to a TImageEnView</L> then layers in the file will be loaded, if it is attached to a TIEBitmap or TBitmap then the file will be loaded as a merged image.
- You can also load layers with the <L TImageEnIO.LoadFromFilePSD>PSD format</L>
<FM>Example<FC>
// Save current layer configuration (compress images as jpeg)
ImageEnView1.IO.Params.IEN_Compression := ioJPEG;
ImageEnView1.IO.SaveToFileIEN( 'D:\layers.ien' );
// Load saved layers
ImageEnView1.IO.LoadFromFileIEN( 'D:\layers.ien' );
<FM>Example<FC>
ImageEnView1.IO.LoadFromFileIEN('C:\input.dat');
<FM>See Also<FN>
- <A TIOParams.IEN_Description>
- <A TIOParams.GetThumbnail>
- <A TImageEnIO.LoadFromStreamIEN>
- <A TImageEnIO.SaveToFileIEN>
- <A TImageEnView.LayersImport>
!!}
function TImageEnIO.LoadFromFileIEN(const FileName: WideString; Append: Boolean = False): Boolean;
var
fs: TIEWideFileStream;
begin
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.create(FileName, fmOpenRead or fmShareDenyWrite);
try
Result := LoadFromStreamIEN( fs, Append );
if ( fParams.FileName = '' ) or ( Append = False ) then
fParams.FileName := FileName;
finally
FreeAndNil(fs);
end;
end;
{!!
<FS>TImageEnIO.LoadFromStreamIEN
<FM>Declaration<FC>
function LoadFromStreamIEN(Stream: TStream; Append: Boolean = False): Boolean;
<FM>Description<FN>
Loads an image from a stream containing a file in ImageEn's native format, which preserves the image and any layers.
The result will be false if an error is encountered, e.g. the file in the stream is not IEN format (<A TImageEnIO.Aborting> will be true).
If <FC>Append<FN> is True, the existing content is not cleared, i.e. layers in this file will be added to existing layers.
Note: If the TImageEnIO is <L TImageEnIO.AttachedImageEn>attached to a TImageEnView</L> then layers in the file will be loaded, if it is attached to a TIEBitmap or TBitmap then the file will be loaded as a merged image.
<FM>Example<FC>
// Save current layer configuration (compress images as jpeg)
ImageEnView1.IO.Params.IEN_Compression := ioJPEG;
ImageEnView1.IO.SaveToStreamIEN( Stream );
// Load saved layers
ImageEnView1.IO.LoadFromStreamIEN( Stream );
<FM>See Also<FN>
- <A TIOParams.IEN_Description>
- <A TIOParams.GetThumbnail>
- <A TImageEnIO.LoadFromFileIEN>
- <A TImageEnIO.SaveToStreamIEN>
- <A TImageEnView.LayersImport>
!!}
function TImageEnIO.LoadFromStreamIEN(Stream: TStream; Append: Boolean = False): Boolean;
var
basePos: Integer;
getThumbnail: Boolean;
tempIE : TImageEnView;
begin
fAborting := false;
try
basePos := Stream.Position;
fParams.ResetInfo;
getThumbnail := fParams.IEN_GetThumbnail;
if getThumbnail then
begin
ParamsFromStreamIEN( Stream, True );
Result := ( fAborting = False ) and ( fIEBitmap.Width > 1 );
if result then
begin
fParams.FileName := '';
fParams.FileType := ioIEN;
Update();
exit;
end;
Stream.Position := basePos;
end;
if ( getThumbnail = False ) and assigned( fImageEnView ) and ( fImageEnView is TImageEnView ) then
fAborting := not (fImageEnView as TImageEnView).LayersLoadFromStream( Stream, Append, fOnIntProgress )
else
begin
// Get params
ParamsFromStreamIEN( Stream, False );
Stream.Position := basePos;
// TImageEnView not associated, render image to IEBitmap
tempIE := TImageEnView.Create(nil);
try
tempIE.LegacyBitmap := False;
fAborting := not tempIE.LayersLoadFromStream( Stream, False, fOnIntProgress );
tempIE.LayersMergeAll( True );
fIEBitmap.Assign( tempIE.IEBitmap );
Update();
finally
tempIE.Free;
end;
end;
fParams.FileName := '';
fParams.FileType := ioIEN;
finally
DoFinishWork;
Result := not fAborting;
if result then
ResetModified( True );
end;
end;
{!!
<FS>TImageEnIO.SaveToStreamIEN
<FM>Declaration<FC>
procedure SaveToStreamIEN(Stream: TStream);
<FM>Description<FN>
Saves the current image in the <L TImageEnIO.AttachedImageEn>connected TImageEnView</L> to a stream in ImageEn's native format, which preserves the image and any layers.
Notes:
- An exception will be raised if the TImageEnIO is not attached to a TImageEnView
- If an internal save error is encountered <A TImageEnIO.Aborting> will return true
- <A TIOParams.IEN_Compression> cannot be <FC>ioTIFF<FN>.
- You can also save layers in <L TImageEnIO.SaveToStreamPSD>PSD</L> and <L TImageEnIO.SaveToStreamSVG>SVG</L> format
<FM>Example<FC>
// Save current layer configuration (compress images as jpeg)
ImageEnView1.IO.Params.IEN_Compression := ioJPEG;
ImageEnView1.IO.SaveToStreamIEN( Stream );
// Load saved layers
ImageEnView1.IO.LoadFromStreamIEN( Stream );
<FM>See Also<FN>
- <A TIOParams.IEN_Compression>
- <A TIOParams.IEN_Description>
- <A TImageEnIO.LoadFromStreamIEN>
- <A TImageEnIO.SaveToFileIEN>
- <A TImageEnView.LayersSaveMergedTo>
!!}
procedure TImageEnIO.SaveToStreamIEN(Stream: TStream);
begin
if assigned( fImageEnView ) = false then
raise EIEException.create( 'Must be attached to a TImageEnView to save in IEN format' );
try
(fImageEnView as TImageEnView).LayersSaveToStream( Stream, fParams.IEN_Compression, False, False, True, fOnIntProgress );
fAborting := False;
except
fAborting := True;
end;
DoFinishWork();
end;
{!!
<FS>TImageEnIO.SaveToFileIEN
<FM>Declaration<FC>
procedure SaveToFileIEN(const FileName: WideString);
<FM>Description<FN>
Saves the current image in the <L TImageEnIO.AttachedImageEn>connected TImageEnView</L> to a file in ImageEn's native format, which preserves the image and any layers.
<FC>FileName<FN> is the file name including extension.
Notes:
- An exception will be raised if the TImageEnIO is not attached to a TImageEnView
- If an internal save error is encountered <A TImageEnIO.Aborting> will return true. Saving issues due to insufficient write permissions and disk write failures will raise an exception.
- <A TIOParams.IEN_Compression> cannot be <FC>ioTIFF<FN>.
- You can also save layers in <L TImageEnIO.SaveToFilePSD>PSD</L> and <L TImageEnIO.SaveToFileSVG>SVG</L> format
<FM>Example<FC>
// Save current layer configuration (compress images as jpeg)
ImageEnView1.IO.Params.IEN_Compression := ioJPEG;
ImageEnView1.IO.SaveToFileIEN( 'D:\layers.ien' );
// Load saved layers
ImageEnView1.IO.LoadFromFileIEN( 'D:\layers.ien' );
<FM>See Also<FN>
- <A TIOParams.IEN_Compression>
- <A TIOParams.IEN_Description>
- <A TImageEnIO.LoadFromFileIEN>
- <A TImageEnIO.SaveToStreamIEN>
- <A TImageEnView.LayersSaveMergedTo>
!!}
procedure TImageEnIO.SaveToFileIEN(const FileName: WideString);
var
fs: TIEWideFileStream;
begin
if assigned( fImageEnView ) = false then
raise EIEException.create( 'Must be attached to a TImageEnView to save in IEN format' );
fs := nil;
try
fAborting := true; // So that fAborting is True if the file is not found
fs := TIEWideFileStream.Create(FileName, fmCreate);
SaveToStreamIEN( fs );
fParams.FileName := FileName;
fParams.FileType := ioIEN;
finally
FreeAndNil(fs);
end;
end;
// Sets just IEN params
// LoadThumbnail must be true at all times, except when we ONLY need to get the IO Params
procedure TImageEnIO.ParamsFromStreamIEN(Stream: TStream; LoadThumbnail: Boolean = False);
var
recHead: TLayerHeader;
headWidth, headHeight: Integer;
headDesc: Widestring;
begin
fAborting := True;
if IELayersLoadHeaderFromStream( Stream, recHead, headWidth, headHeight, headDesc, fIEBitmap, LoadThumbnail ) = False then
exit;
fParams.IEN_Compression := recHead.FileFormat;
fParams.fIEN_LayerCount := recHead.LayersCount;
fParams.fIEN_Version := recHead.Version;
fParams.IEN_Description := '';
if recHead.Version >= 7000 then
begin
fParams.IEN_Description := headDesc;
fParams.Width := headWidth;
fParams.Height := headHeight;
fParams.OriginalWidth := headWidth;
fParams.OriginalHeight := headHeight;
end;
fParams.FileType := ioIEN;
fAborting := False;
end;
{!!
<FS>TImageEnIO.SaveToStreamSVG
<FM>Declaration<FC>
procedure SaveToStreamSVG(Stream: TStream);
<FM>Description<FN>
Saves the current image to a stream in Scalable Vector Graphics format. SVG is a vector format that can be displayed be web browsers.
If the TImageEnIO is <L TImageEnIO.AttachedImageEn>connected to an TImageEnView</L>, then each of the <A TImageEnView.Layers> will be output as a scalable object. If connected to a TImageEnVect, the objects will be <L TImageEnVect.CopyAllObjectsTo>converted to layers</L> and then output. Otherwise the <A TImageEnIO.IEBitmap> is output as SVG with an embedded raster image.
SVG Exporting Limitations:
- Gradient fills are not supported at this time
- <L TIEImageLayer.IsMask>Mask layers</L> are not supported
- Some shapes of a TIEShapeLayer (those not listed in <A Supported_Generate_Points_Shapes>) will need to rasterized as an image (i.e. will no longer be vectors)
Notes:
- <A TIOParams.SVG_ImageCompression> sets the image format for embedded raster images. It should be a web-safe format such as ioPNG or ioJPEG
- If an internal save error is encountered <A TImageEnIO.Aborting> will return true (e.g. there are no valid layers)
- You can also save layers in <L TImageEnIO.SaveToStreamIEN>IEN</L> and <L TImageEnIO.SaveToStreamPSD>PSD</L> format
- SVG is an export only format. ImageEn does not support loading of SVG files
<FM>Example<FC>
// Save current layers (compress image layers as jpeg)
ImageEnView1.IO.Params.SVG_ImageCompression := ioJPEG;
ImageEnView1.IO.SaveToStreamSVG( Stream );
<FM>See Also<FN>
- <A TIOParams.SVG_ImageCompression>
- <A TImageEnIO.SaveToFileSVG>
!!}
procedure TImageEnIO.SaveToStreamSVG(Stream: TStream);
var
Progress: TProgressRec;
begin
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
WriteSVGFileOrStream( '', Stream, AttachedImageEn, IEBitmap, Params.SVG_ImageCompression, Progress );
DoFinishWork();
end;
{!!
<FS>TImageEnIO.SaveToFileSVG
<FM>Declaration<FC>
procedure SaveToFileSVG(const FileName: WideString);
<FM>Description<FN>
Saves the current image to a file in Scalable Vector Graphics format. SVG is a vector format that can be displayed be web browsers.
If the TImageEnIO is <L TImageEnIO.AttachedImageEn>connected to an TImageEnView</L>, then each of the <A TImageEnView.Layers> will be output as a scalable object. If connected to a TImageEnVect, the objects will be <L TImageEnVect.CopyAllObjectsTo>converted to layers</L> and then output. Otherwise the <A TImageEnIO.IEBitmap> is output as SVG with an embedded raster image.
<FC>FileName<FN> is the file name including extension.
SVG Exporting Limitations:
- Gradient fills are not supported at this time
- <L TIEImageLayer.IsMask>Mask layers</L> are not supported
- Some shapes of a TIEShapeLayer (those not listed in <A Supported_Generate_Points_Shapes>) will need to rasterized as an image (i.e. will no longer be vectors)
Notes:
- If an internal save error is encountered <A TImageEnIO.Aborting> will return true (e.g. there are no valid layers). Saving issues due to insufficient write permissions and disk write failures will raise an exception.
- Embedded images will be saved in the format specified by <A TIOParams.SVG_ImageCompression>.
- You can also save layers in <L TImageEnIO.SaveToFileIEN>IEN</L> and <L TImageEnIO.SaveToFilePSD>PSD</L> format
- SVG is an export only format. ImageEn does not support loading of SVG files
<FM>Demo<FN>
<TABLE2>
<R> <C_IMG_DEMO> <C>Demos\ImageEditing\Layers_AllTypes\Layers.dpr </C> </R>
</TABLE>
<FM>Example<FC>
// Save current layers (compress image layers as jpeg)
ImageEnView1.IO.Params.SVG_ImageCompression := ioJPEG;
ImageEnView1.IO.Params.JPEG_Quality := 80;
ImageEnView1.IO.SaveToFileSVG( 'D:\layers.SVG' );
<FM>See Also<FN>
- <A TIOParams.SVG_ImageCompression>
- <A TImageEnIO.SaveToStreamSVG>
!!}
procedure TImageEnIO.SaveToFileSVG(const FileName: WideString);
var
Progress: TProgressRec;
begin
fAborting := false;
Progress := ProgressRec( Self, fOnIntProgress, fAborting );
WriteSVGFileOrStream( FileName, nil, AttachedImageEn, IEBitmap, Params.SVG_ImageCompression, Progress );
fParams.FileName := FileName;
fParams.FileType := ioSVG;
DoFinishWork();
end;
{!!
<FS>TImageEnIO.Seek
<FM>Declaration<FC>
function Seek(Page : <A TImageEnIO.TIEIOSeekDestination>; FileName : WideString = ''): Integer;
<FM>Description<FN>
Load the specified page from the last loaded multipage file, including TIFF, GIF, AVI and other video types.
This method uses <A TImageEnIO.LoadFromFile> to load the file (hence the file name must be provided), unless it is part of <A TImageEnDBView> or <A TImageEnDBVect> where LoadPicture is called instead.
<TABLE>
<R> <H>Parameter</H> <H>Description</H> </R>
<R> <C><FC>Page<FN></C> <C>Page to load.</C> </R>
<R> <C><FC>FileName<FN></C> <C>Optional file name. If empty will use the last loaded file name.</C> </R>
</TABLE>
Returns the loaded page index.
<FM>Example<FC>
// load first page
ImageEnView1.IO.Seek(ieioSeekFirst, 'multipage.tiff');
// load next page
ImageEnView1.IO.Seek(ieioSeekNext);
!!}
function TImageEnIO.Seek(Destination: TIEIOSeekDestination; FileName: WideString = ''): Integer;
var
fn: WideString;
begin
result := 0;
case Destination of
ieioSeekFirst:
result := 0;
ieioSeekPrior:
result := imax(0, fParams.ImageIndex - 1);
ieioSeekNext:
result := imin(fParams.ImageCount - 1, fParams.ImageIndex + 1);
ieioSeekLast:
result := fParams.ImageCount - 1;
end;
if FileName = '' then
fn := fParams.FileName
else
fn := FileName;
{$ifdef IESUPPORTINTERFACESUPPORT}
if assigned(fImageEnView) and Supports(fImageEnView, IIELoadPicture) then
begin
fParams.ImageIndex := result;
(fImageEnView as IIELoadPicture).LoadPicture();
end
else
{$endif}
begin
if (FileName = '') and (result = fParams.ImageIndex) then
exit; // nothing to load
fParams.ImageIndex := result;
LoadFromFile(fn);
end;
end;
{$ifdef IEIncludeDeprecatedInV6}
// Deprecated in 6.2.0 (2015-06-08)
function TImageEnIO.GetProxyAddress: WideString;
begin
Result := IEGlobalSettings().ProxyAddress;
end;
function TImageEnIO.GetProxyUser: WideString;
begin
Result := IEGlobalSettings().ProxyUser;
end;
function TImageEnIO.GetProxyPassword: WideString;
begin
Result := IEGlobalSettings().ProxyPassword;
end;
procedure TImageEnIO.SetProxyAddress(Value: WideString);
begin
IEGlobalSettings().ProxyAddress := Value;
end;
procedure TImageEnIO.SetProxyUser(Value: WideString);
begin
IEGlobalSettings().ProxyUser := Value;
end;
procedure TImageEnIO.SetProxyPassword(Value: WideString);
begin
IEGlobalSettings().ProxyPassword := Value;
end;
{$ENDIF}
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
procedure IEInitialize_imageenio;
begin
//
end;
procedure IEFinalize_imageenio;
begin
//
end;
end.