3782 lines
139 KiB
Plaintext
3782 lines
139 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: iexHelperFunctions.pas
|
|
Description: ImageEn Helper functions
|
|
File version: 1010
|
|
Notes:
|
|
- Requires Delphi 2005 or newer
|
|
- Some additions by William Miller, Adirondack Software & Graphics
|
|
*)
|
|
|
|
|
|
unit iexHelperFunctions;
|
|
|
|
interface
|
|
|
|
{$I ie.inc}
|
|
|
|
|
|
// Enable to include TImageEnIO helpers for loading and saving to blob fields
|
|
{.$Define IE_DB_Helpers}
|
|
|
|
uses
|
|
Windows, Graphics, Classes,
|
|
{$ifdef IEHASTYPES} Types, {$endif}
|
|
{$ifdef IE_DB_Helpers} Db, {$endif}
|
|
ImageEnProc, hyiedefs, ImageEnIO, iexBitmaps, hyieutils;
|
|
|
|
|
|
|
|
type
|
|
{!!
|
|
<FS>TLightOrigin
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
TLightOrigin = (_loTopLeft, _loTopRight, _loBottomLeft, _loBottomRight);
|
|
{!!}
|
|
|
|
|
|
{!!
|
|
<FS>TIEQuality
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
TIEQuality = (ieLow, ieMedium, ieHigh);
|
|
{!!}
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
// TImageEnIO Helper Functions
|
|
TImageEnIOHelper = class helper for TImageEnIO
|
|
private
|
|
function ImageSize : TPoint;
|
|
function IsEmpty : Boolean;
|
|
function _LoadFromFileEx(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1;
|
|
bUseFileExt : Boolean = true): Boolean;
|
|
function _LoadFromStreamEx(Stream: TStream;
|
|
FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
function LoadFromStreamRawFast(Stream: TStream; iMaxX, iMaxY: integer): Boolean;
|
|
{$ENDIF}
|
|
public
|
|
function Reload : Boolean;
|
|
|
|
function LoadFromFileEx(const sFilename: string;
|
|
bAutoAdjustOrientation: Boolean;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
|
|
function LoadFromFileFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
function LoadFromFileJPEGFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
var iFastScaleUsed: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
function LoadFromStreamJPEGFast(Stream: TStream;
|
|
iMaxX, iMaxY: integer;
|
|
var iFastScaleUsed: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
function LoadFromFileAutoEx(const sFilename: string;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
function LoadFromFileRawFast(const sFilename: string; iMaxX, iMaxY: integer): Boolean;
|
|
{$ENDIF}
|
|
|
|
function LoadFromStreamEx(Stream: TStream;
|
|
FileType: integer = 0;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
|
|
function LoadFromStreamFast(Stream: TStream;
|
|
FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
function SaveToFileEx(const sFilename : string; iJpegQuality: integer = 0): Boolean;
|
|
function SaveToStreamEx(Stream: TStream; FileType: integer; iJpegQuality: integer = 0): Boolean;
|
|
|
|
{$IFDEF IEINCLUDEPDFWRITING}
|
|
function CreatePDFFromFileList(const sDestFilename : string;
|
|
ssFileList : TStrings;
|
|
const aPaperSize : TIOPDFPaperSize;
|
|
const aCompression : TIOPDFCompression;
|
|
const sTitle : string;
|
|
const sAuthor : string;
|
|
const bFailOnUnsupportedImage : Boolean = True;
|
|
const bRaiseExceptions : Boolean = False
|
|
) : Boolean;
|
|
{$ENDIF}
|
|
|
|
function CreatePSFromFileList(const sDestFilename : string;
|
|
ssFileList : TStrings;
|
|
const aPaperSize : TIOPDFPaperSize;
|
|
const aCompression : TIOPSCompression;
|
|
const sTitle : string = '';
|
|
const bFailOnUnsupportedImage : Boolean = True;
|
|
const bRaiseExceptions : Boolean = False
|
|
) : Boolean;
|
|
|
|
{$IFDEF IE_DB_Helpers}
|
|
function LoadFromBlob(aField: TBlobField;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1
|
|
): Boolean;
|
|
|
|
function LoadFromBlobFast(aField: TBlobField;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1
|
|
): Boolean;
|
|
|
|
function SaveToBlob(aField : TBlobField;
|
|
aFileType : TIOFileType;
|
|
iJpegQuality: integer = 0): Boolean;
|
|
{$ENDIF}
|
|
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
// TBitmap Helper Functions
|
|
TBitmapHelper = class helper for TBitmap
|
|
private
|
|
procedure ConvertTo24Bit;
|
|
public
|
|
procedure IEInitialize(iWidth, iHeight: Integer; ABackgroundColor : TColor = clNone);
|
|
procedure IERotate(Angle: double; AntiAliasMode: TIEAntialiasMode = ierFast; BackgroundColor: TColor = -1);
|
|
procedure IEFlip(Direction: TFlipDir);
|
|
procedure IEResample(iNewWidth, iNewHeight: integer; QualityFilter: TResampleFilter = rfNone; bMaintainAspectRatio : Boolean = False);
|
|
function IELoadFromFile(const sFilename : string): Boolean;
|
|
function IELoadFromFileFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
function IELoadFromStream(Stream: TStream; FileType: integer = 0): Boolean;
|
|
function IELoadFromStreamFast(Stream: TStream;
|
|
FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
function IESaveToFile(const sFilename : string; iJPEGQuality : Integer): Boolean;
|
|
function IESaveToStream(Stream: TStream; FileType: integer; iJPEGQuality : Integer): Boolean;
|
|
|
|
function LoadFromURL(const URL : WideString;
|
|
const sProxyAddress : WideString = '';
|
|
const sProxyUser : WideString = '';
|
|
const sProxyPassword : WideString = ''
|
|
): Boolean;
|
|
|
|
|
|
function IELoadAsThumbnail(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter : TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
) : Boolean;
|
|
|
|
procedure IEConvertToThumbnail(iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
QualityFilter : TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite);
|
|
|
|
procedure IEAddSoftShadow(iBlurRadius: integer;
|
|
iShadowOffset : Integer;
|
|
cBGColor: TColor;
|
|
LightOrigin: TLightOrigin = _loTopLeft;
|
|
cShadowColor: TColor = clblack);
|
|
|
|
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;
|
|
SubsampleFilter: TResampleFilter = rfFastLinear);
|
|
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
// TIEBitmap Helper Functions
|
|
TIEBitmapHelper = class helper for TIEBitmap
|
|
private
|
|
procedure ConvertTo24Bit;
|
|
function IELoadFromFileEx(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean;
|
|
IOParams: TIOParams;
|
|
iImageIndex: Integer
|
|
): Boolean;
|
|
function IELoadFromStreamEx(Stream: TStream; FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean;
|
|
IOParams: TIOParams;
|
|
iImageIndex: Integer
|
|
): Boolean;
|
|
public
|
|
procedure IEInitialize(iWidth, iHeight: Integer; ABackgroundColor: TColor = clNone); overload;
|
|
procedure IEInitialize(iWidth, iHeight: Integer; Transparent: Boolean); overload;
|
|
function IELoadFromFile(const sFilename: string; IOParams: TIOParams = nil; iImageIndex: Integer = 0): Boolean;
|
|
function IELoadFromFileFast(const sFilename: string; iMaxX, iMaxY: integer; bAutoAdjustOrientation: Boolean = False; IOParams: TIOParams = nil): Boolean;
|
|
function IELoadFromStream(Stream: TStream; FileType: integer = 0; IOParams: TIOParams = nil; iImageIndex: Integer = 0): Boolean;
|
|
function IELoadFromStreamFast(Stream: TStream; FileType: integer; iMaxX, iMaxY: integer; bAutoAdjustOrientation: Boolean = False; IOParams: TIOParams = nil): Boolean;
|
|
function IESaveToFile(const sFilename: string; iJPEGQuality: Integer; IOParams: TIOParams = nil): Boolean;
|
|
function IESaveToStream(Stream: TStream; FileType: integer; iJPEGQuality: Integer; IOParams: TIOParams = nil): Boolean;
|
|
function LoadFromURL(const URL : WideString;
|
|
const sProxyAddress : WideString = '';
|
|
const sProxyUser : WideString = '';
|
|
const sProxyPassword : WideString = ''
|
|
): Boolean;
|
|
|
|
function IELoadAsThumbnail(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter: TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius: Integer = 4;
|
|
iShadowOffset: Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
): Boolean;
|
|
|
|
procedure IEConvertToThumbnail(iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
QualityFilter: TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius: Integer = 4;
|
|
iShadowOffset: Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite);
|
|
|
|
procedure IEAddSoftShadow(iBlurRadius: integer;
|
|
iShadowOffset: Integer;
|
|
cBGColor: TColor;
|
|
LightOrigin: TLightOrigin = _loTopLeft;
|
|
cShadowColor: TColor = clblack);
|
|
|
|
|
|
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;
|
|
SubsampleFilter: TResampleFilter = rfFastLinear);
|
|
|
|
|
|
{$IFDEF IEINCLUDEWIC}
|
|
function WicRead(const sFilename: string; iImageIndex: Integer = 0; IOParams: TIOParams = nil): Boolean; overload;
|
|
function WicRead(Stream: TStream; FileType: integer = 0; iImageIndex: Integer = 0; IOParams: TIOParams = nil): Boolean; overload;
|
|
{$ENDIF}
|
|
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
// FILE FUNCTIONS
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IEResampleImageFile(const sInFilename, sOutFilename: string;
|
|
iJpegQuality: Integer;
|
|
iMaxX: Integer;
|
|
iMaxY: Integer;
|
|
bCanStretch: Boolean = False;
|
|
QualityFilter: TResampleFilter = rfLanczos3;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
bStripMetaData: Boolean = False
|
|
): Boolean;
|
|
{$ENDIF}
|
|
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IEConvertImageFile(const sInFilename, sOutFilename: string;
|
|
iJpegQuality: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
{$ENDIF}
|
|
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IECreateThumbnailFromFile(const sInFilename: string;
|
|
const sOutFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
iJPEGQuality: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter : TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
): Boolean;
|
|
{$ENDIF}
|
|
|
|
function GetImageDetails(const sFilename: string;
|
|
out iWidth: Integer;
|
|
out iHeight: Integer;
|
|
out iBitsPerPixel: Integer
|
|
): Boolean; overload;
|
|
function GetImageDetails(const sFilename: string): TPoint; overload;
|
|
|
|
function GetExifOrFileCreationDate(const sFilename: string;
|
|
bReturnCreateDate: Boolean = true {if true then the create date is returned if there is no exif date}
|
|
): TDateTime;
|
|
|
|
function JPEGLosslessRotateFile(const sInFilename : WideString; const sOutFilename : WideString; iRotateAngle : integer) : Boolean; overload;
|
|
function JPEGLosslessRotateFile(const sFilename : WideString; iRotateAngle : integer) : Boolean; overload;
|
|
|
|
function JPEGLosslessFlipFile(const sInFilename : WideString; const sOutFilename : WideString; Direction: TFlipDir) : Boolean; overload;
|
|
function JPEGLosslessFlipFile(const sFilename : WideString; Direction: TFlipDir) : Boolean; overload;
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IERotateImageFile(const sFilename : string;
|
|
iJpegQuality : integer;
|
|
iRotateAngle : integer;
|
|
AntiAliasMode: TIEAntialiasMode = ierFast;
|
|
bCanUseLossless: Boolean = true; // if true then a lossless rotate is used for JPEG images
|
|
cBackgroundColor: TColor = clWhite): Boolean; overload;
|
|
function IERotateImageFile(const sInFilename, sOutFilename : string;
|
|
iJpegQuality : integer;
|
|
iRotateAngle : integer;
|
|
AntiAliasMode: TIEAntialiasMode = ierFast;
|
|
bCanUseLossless: Boolean = true; // if true then a lossless rotate is used for JPEG images
|
|
cBackgroundColor: TColor = clWhite): Boolean; overload;
|
|
function IEFlipImageFile(const sFilename : string;
|
|
iJpegQuality : integer;
|
|
Direction: TFlipDir;
|
|
bCanUseLossless: Boolean = true // if true then a lossless rotate is used for JPEG images
|
|
): Boolean; overload;
|
|
function IEFlipImageFile(const sInFilename, sOutFilename : string;
|
|
iJpegQuality : integer;
|
|
Direction: TFlipDir;
|
|
bCanUseLossless: Boolean = true // if true then a lossless rotate is used for JPEG images
|
|
): Boolean; overload;
|
|
{$ENDIF}
|
|
|
|
function IEReadCorrectOrientationOfImageFile(const sFilename : string; bConservativeChecking : Boolean = True) : Integer;
|
|
function IEAutomaticallyRotateImageFile(const sFilename : string; bConservativeChecking : Boolean = True) : Integer;
|
|
function BitsPerPixelToStr(iBitsPerPixel: Integer) : string;
|
|
function ShowTempHourglass: IUnknown;
|
|
function QualityToZoomFilter(Quality: TIEQuality): TResampleFilter;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF IEINCLUDEWIC}
|
|
iewic,
|
|
{$ENDIF}
|
|
SysUtils, ImageEnView, Controls, Math, Forms, iesettings;
|
|
|
|
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
{ TImageEnIOHelper }
|
|
|
|
function TImageEnIOHelper.ImageSize: TPoint;
|
|
begin
|
|
if Assigned(IEBitmap) then
|
|
result := Point(IEBitmap.width, IEBitmap.height)
|
|
else
|
|
if Assigned(Bitmap) then
|
|
result := Point(Bitmap.width, Bitmap.height)
|
|
else
|
|
result := Point(0, 0);
|
|
end;
|
|
|
|
function TImageEnIOHelper.IsEmpty: Boolean;
|
|
begin
|
|
Result := (ImageSize.X <= 2) or (ImageSize.Y <= 2);
|
|
end;
|
|
|
|
|
|
function TImageEnIOHelper._LoadFromFileEx(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1;
|
|
bUseFileExt : Boolean = true): Boolean;
|
|
var
|
|
bFastLoad: Boolean;
|
|
iFastScaleUsed : Integer;
|
|
begin
|
|
bFastLoad := (iMaxX > 0) and (iMaxY > 0);
|
|
try
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
if bFastLoad and (IEFileIsOfFormat(sFilename, ioRaw) or IEFileIsOfFormat(sFilename, ioRaw)) then
|
|
begin
|
|
Result := LoadFromFileRawFast(sFilename, iMaxX, iMaxY);
|
|
end
|
|
else
|
|
{$ENDIF}
|
|
if bFastLoad and IEFileIsOfFormat(sFilename, ioJPEG) then
|
|
begin
|
|
Result := LoadFromFileJPEGFast(sFilename, iMaxX, iMaxY, iFastScaleUsed, bAutoAdjustOrientation);
|
|
end
|
|
else
|
|
begin
|
|
// reset any fast loading variables
|
|
Params.JPEG_Scale := ioJPEG_FullSize;
|
|
Params.JPEG_DCTMethod := ioJPEG_ISLOW;
|
|
Params.EnableAdjustOrientation := bAutoAdjustOrientation;
|
|
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
Params.RAW_HalfSize := false;
|
|
Params.RAW_GetExifThumbnail := false;
|
|
{$ENDIF}
|
|
|
|
Params.IEN_GetThumbnail := bFastLoad and ( iMaxX <= IEGlobalSettings().ThumbnailSize ) and ( iMaxY <= IEGlobalSettings().ThumbnailSize );
|
|
|
|
if iImageIndex <> -1 then
|
|
Params.ImageIndex := iImageIndex;
|
|
|
|
if bUseFileExt then
|
|
LoadFromFile(sFilename)
|
|
else
|
|
LoadFromFileAuto(sFilename);
|
|
Result := not (Aborting or IsEmpty);
|
|
end;
|
|
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TImageEnIOHelper._LoadFromStreamEx(Stream: TStream;
|
|
FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
var
|
|
bFastLoad: Boolean;
|
|
iFastScaleUsed : Integer;
|
|
begin
|
|
try
|
|
bFastLoad := (iMaxX > 0) and (iMaxY > 0);
|
|
|
|
if FileType = ioUnknown then
|
|
FileType := FindStreamFormat( Stream );
|
|
if FileType = ioUnknown then
|
|
raise EIEException.create('Unknown File Type');
|
|
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
if bFastLoad and ( FileType = ioRaw ) then
|
|
begin
|
|
Result := LoadFromStreamRawFast(Stream, iMaxX, iMaxY);
|
|
end
|
|
else
|
|
{$ENDIF}
|
|
if bFastLoad and ( FileType = ioJPEG ) then
|
|
begin
|
|
Result := LoadFromStreamJPEGFast(Stream, iMaxX, iMaxY, iFastScaleUsed, bAutoAdjustOrientation);
|
|
end
|
|
else
|
|
begin
|
|
// reset any fast loading variables
|
|
Params.JPEG_Scale := ioJPEG_FullSize;
|
|
Params.JPEG_DCTMethod := ioJPEG_ISLOW;
|
|
Params.EnableAdjustOrientation := bAutoAdjustOrientation;
|
|
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
Params.RAW_HalfSize := false;
|
|
Params.RAW_GetExifThumbnail := false;
|
|
{$ENDIF}
|
|
|
|
Params.IEN_GetThumbnail := bFastLoad and ( iMaxX <= IEGlobalSettings().ThumbnailSize ) and ( iMaxY <= IEGlobalSettings().ThumbnailSize );
|
|
|
|
if iImageIndex <> -1 then
|
|
Params.ImageIndex := iImageIndex;
|
|
|
|
LoadFromStream(Stream, FileType);
|
|
Result := not (Aborting or IsEmpty);
|
|
end;
|
|
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromFileFast
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromFileFast(const sFilename: string; iMaxX, iMaxY: integer; bAutoAdjustOrientation: Boolean = False): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.LoadFromFile> and allows you to specify a maximum size that you require an image so that it can be loaded as fast as possible, by using:
|
|
- <A TIOParams.JPEG_Scale> for JPEGs
|
|
- <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files
|
|
- <A TIOParams.IEN_GetThumbnail> for IEN files
|
|
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images
|
|
|
|
Returns True if loading was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Load the image specified in an open dialog as fast as possible, but bigger than the displaying TImageEnView
|
|
ImageEnView1.AutoShrink := True;
|
|
ImageEnView1.IO.LoadFromFileFast(OpenPictureDialog1.FileName, ImageEnView1.Width, ImageEnView1.Height)
|
|
!!}
|
|
function TImageEnIOHelper.LoadFromFileFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False): Boolean;
|
|
begin
|
|
Result := _LoadFromFileEx(sFilename, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromStreamFast
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromStreamFast(Stream: TStream; FileType: <A TIOFileType> = 0; iMaxX, iMaxY: integer; bAutoAdjustOrientation: Boolean = False): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.LoadFromStream> and allows you to specify a maximum size that you require an image so that it can be loaded as fast as possible, by using:
|
|
- <A TIOParams.JPEG_Scale> for JPEGs
|
|
- <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files
|
|
- <A TIOParams.IEN_GetThumbnail> for IEN files
|
|
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images.
|
|
|
|
If you know the <L TIOFileType>FileType</L> type of the stream, pass it to speed up loading.
|
|
|
|
Returns True if loading was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Load an image as fast as possible, but bigger than the displaying TImageEnView
|
|
ImageEnView1.AutoShrink := True;
|
|
ImageEnView1.IO.LoadFromStreamFast( MyStream, ImageEnView1.Width, ImageEnView1.Height )
|
|
!!}
|
|
function TImageEnIOHelper.LoadFromStreamFast(Stream: TStream; FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False): Boolean;
|
|
begin
|
|
Result := _LoadFromStreamEx(Stream, FileType, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromFileEx
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromFileEx(const sFilename: string; bAutoAdjustOrientation: Boolean; iImageIndex : Integer = -1): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.LoadFromFile>, optionally setting <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images and <A TIOParams.ImageIndex> to display a specific image.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Load the third page of MyImage.tiff
|
|
ImageEnView1.IO.LoadFromFileEx('D:\MyImage.tiff', False, 2);
|
|
!!}
|
|
function TImageEnIOHelper.LoadFromFileEx(const sFilename: string;
|
|
bAutoAdjustOrientation: Boolean;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
begin
|
|
Result := _LoadFromFileEx(sFilename, -1, -1, bAutoAdjustOrientation, iImageIndex);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromStreamEx
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromStreamEx(Stream: TStream; FileType: <A TIOFileType> = 0; bAutoAdjustOrientation: Boolean; iImageIndex : Integer = -1): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.LoadFromStream>, optionally setting <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images and <A TIOParams.ImageIndex> to display a specific image.
|
|
If you know the <L TIOFileType>FileType</L> type of the stream, pass it to speed up loading.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Load the third page of a TIFF stream
|
|
ImageEnView1.IO.LoadFromStreamEx(MyStream, False, 2);
|
|
!!}
|
|
function TImageEnIOHelper.LoadFromStreamEx(Stream: TStream; FileType: integer = 0;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
begin
|
|
Result := _LoadFromStreamEx(Stream, FileType, -1, -1, bAutoAdjustOrientation, iImageIndex);
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromFileAutoEx
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromFileAutoEx(const sFilename: string; bAutoAdjustOrientation: Boolean; iImageIndex : Integer = -1): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
A modified version of <A TImageEnIO.LoadFromFileEx> that copes with image files with a incorrect extension (e.g. a GIF file named MyImage.jpg).
|
|
|
|
This function will attempt to load the file using its extension (using <A TImageEnIO.LoadFromFile>) but on failure will examine the message content to determine its type (i.e. falling back to <A TImageEnIO.LoadFromFileAuto>).
|
|
|
|
Optionally it will set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images and <A TIOParams.ImageIndex> to display a specific image.
|
|
Returns True if loading was successful, or False on error (i.e. the file could not be loaded even by examining its content).
|
|
|
|
<FM>Example<FC>
|
|
// Load MyImage.tiff (even if it is a JPEG or GIF)
|
|
ImageEnView1.IO.LoadFromFileAutoEx('D:\MyImage.tiff');
|
|
!!}
|
|
function TImageEnIOHelper.LoadFromFileAutoEx(const sFilename: string;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1): Boolean;
|
|
begin
|
|
Result := _LoadFromFileEx(sFilename, -1, -1, bAutoAdjustOrientation, iImageIndex);
|
|
|
|
// Try loading without extension
|
|
if not Result then
|
|
Result := _LoadFromFileEx(sFilename, -1, -1, bAutoAdjustOrientation, iImageIndex, False);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromFileJPEGFast
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromFileJPEGFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
var iFastScaleUsed: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.LoadFromFileJpeg> to load a JPEG image and allows you to specify a maximum size that you require an image so that it can be loaded as fast as possible, by using <A TIOParams.JPEG_Scale>.
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images
|
|
Returns True if loading was successful, or False on error. iFastScaleUsed is set with the scaling that was used, i.e. 1 = loaded full size, 2 = loaded at half size, etc.
|
|
|
|
<FM>Example<FC>
|
|
// Load the JPEG specified in an open dialog as fast as possible, but bigger than the displaying TImageEnView
|
|
ImageEnView1.AutoShrink := True;
|
|
ImageEnView1.IO.LoadFromFileJpegFast(OpenPictureDialog1.FileName, ImageEnView1.Width, ImageEnView1.Height, iFastScaleUsed)
|
|
!!}
|
|
function TImageEnIOHelper.LoadFromFileJPEGFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
var iFastScaleUsed: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
begin
|
|
Result := True;
|
|
try
|
|
iFastScaleUsed := 1;
|
|
|
|
if (iMaxX < 1) or (iMaxY < 1) then
|
|
Params.JPEG_Scale := ioJPEG_FullSize
|
|
else
|
|
begin
|
|
// Fast Loading
|
|
Params.Width := iMaxX;
|
|
Params.Height := iMaxY;
|
|
Params.JPEG_Scale := ioJPEG_AUTOCALC;
|
|
|
|
// Is it a thumbnail?
|
|
if iMaxX + iMaxY < 500 then
|
|
Params.JPEG_DCTMethod := ioJPEG_IFAST;
|
|
end;
|
|
Params.EnableAdjustOrientation := bAutoAdjustOrientation;
|
|
|
|
LoadFromFileJpeg(sFilename);
|
|
|
|
if Aborting or IsEmpty then
|
|
raise EIEException.create('Load Error');
|
|
|
|
iFastScaleUsed := Params.Jpeg_Scale_Used;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromStreamJPEGFast
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromStreamJPEGFast(Stream: TStream;
|
|
iMaxX, iMaxY: integer;
|
|
var iFastScaleUsed: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.LoadFromStreamJpeg> to load a JPEG image and allows you to specify a maximum size that you require an image so that it can be loaded as fast as possible, by using <A TIOParams.JPEG_Scale>.
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images
|
|
Returns True if loading was successful, or False on error. iFastScaleUsed is set with the scaling that was used, i.e. 1 = loaded full size, 2 = loaded at half size, etc.
|
|
|
|
<FM>Example<FC>
|
|
// Load the JPEG from a stream as fast as possible, but bigger than the displaying TImageEnView
|
|
ImageEnView1.AutoShrink := True;
|
|
ImageEnView1.IO.LoadFromStreamJpegFast(MyStream, ImageEnView1.Width, ImageEnView1.Height, iFastScaleUsed)
|
|
!!}
|
|
function TImageEnIOHelper.LoadFromStreamJPEGFast(Stream: TStream;
|
|
iMaxX, iMaxY: integer;
|
|
var iFastScaleUsed: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
begin
|
|
Result := True;
|
|
try
|
|
iFastScaleUsed := 1;
|
|
|
|
if (iMaxX < 1) or (iMaxY < 1) then
|
|
Params.JPEG_Scale := ioJPEG_FullSize
|
|
else
|
|
begin
|
|
// Fast Loading
|
|
Params.Width := iMaxX;
|
|
Params.Height := iMaxY;
|
|
Params.JPEG_Scale := ioJPEG_AUTOCALC;
|
|
|
|
// Is it a thumbnail?
|
|
if iMaxX + iMaxY < 500 then
|
|
Params.JPEG_DCTMethod := ioJPEG_IFAST;
|
|
end;
|
|
Params.EnableAdjustOrientation := bAutoAdjustOrientation;
|
|
|
|
LoadFromStreamJpeg(Stream);
|
|
|
|
if Aborting or IsEmpty then
|
|
raise EIEException.create('Load Error');
|
|
|
|
iFastScaleUsed := Params.Jpeg_Scale_Used;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
const
|
|
// SOME APPROXIMATE VALUES TO OPTIMIZE RAW LOADING
|
|
SMALLEST_RAW_THUMBNAIL_WIDTH = 150;
|
|
SMALLEST_RAW_THUMBNAIL_HEIGHT = 100;
|
|
SMALLEST_RAW_IMAGE_WIDTH = 1800;
|
|
SMALLEST_RAW_IMAGE_HEIGHT = 1400;
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromFileRawFast
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromFileRawFast(const sFilename: string; iMaxX, iMaxY: integer): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.LoadFromFile> to load a camera Raw image and allows you to specify a maximum size that you require an image so that it can be loaded as fast as possible, by using <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Load the image specified in an open dialog as fast as possible, but bigger than the displaying TImageEnView
|
|
ImageEnView1.AutoShrink := True;
|
|
ImageEnView1.IO.LoadFromFileRawFast(OpenPictureDialog1.FileName, ImageEnView1.Width, ImageEnView1.Height)
|
|
!!}
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
function TImageEnIOHelper.LoadFromFileRawFast(const sFilename: string; iMaxX, iMaxY: integer): Boolean;
|
|
begin
|
|
try
|
|
Params.RAW_HalfSize := (iMaxX <= SMALLEST_RAW_IMAGE_WIDTH) and (iMaxY <= SMALLEST_RAW_IMAGE_HEIGHT);
|
|
Params.RAW_GetExifThumbnail := (iMaxX <= SMALLEST_RAW_THUMBNAIL_WIDTH) and (iMaxY <= SMALLEST_RAW_THUMBNAIL_HEIGHT);
|
|
|
|
LoadFromFileRaw(sFilename);
|
|
|
|
result := not (Aborting or IsEmpty);
|
|
except
|
|
on E:Exception do
|
|
result := false;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
function TImageEnIOHelper.LoadFromStreamRawFast(Stream: TStream; iMaxX, iMaxY: integer): Boolean;
|
|
begin
|
|
try
|
|
Params.RAW_HalfSize := (iMaxX <= SMALLEST_RAW_IMAGE_WIDTH) and (iMaxY <= SMALLEST_RAW_IMAGE_HEIGHT);
|
|
Params.RAW_GetExifThumbnail := (iMaxX <= SMALLEST_RAW_THUMBNAIL_WIDTH) and (iMaxY <= SMALLEST_RAW_THUMBNAIL_HEIGHT);
|
|
|
|
LoadFromStreamRaw(Stream);
|
|
|
|
result := not (Aborting or IsEmpty);
|
|
except
|
|
on E:Exception do
|
|
result := false;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.Reload
|
|
|
|
<FM>Declaration<FC>
|
|
function Reload(const sFilename : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Reload the image.
|
|
|
|
<FM>Example<FC>
|
|
ImageEnView1.IO.Reload;
|
|
!!}
|
|
function TImageEnIOHelper.Reload : Boolean;
|
|
begin
|
|
Result := True;
|
|
try
|
|
if Params.FileName = '' then
|
|
raise EIEException.create('Nothing to Load');
|
|
|
|
LoadFromFile(Params.FileName);
|
|
|
|
if Aborting or IsEmpty then
|
|
raise EIEException.create('Load Error');
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.SaveToFileEx
|
|
|
|
<FM>Declaration<FC>
|
|
function SaveToFileEx(const sFilename : string;
|
|
iJpegQuality: integer = 0): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.SaveToFile>, optionally setting <A TIOParams.JPEG_Quality>.
|
|
Returns True if saving was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Save the image to MyImage.jpeg at 90% quality
|
|
ImageEnView1.IO.SaveToFileEx('D:\MyImage.jpeg', 90);
|
|
!!}
|
|
function TImageEnIOHelper.SaveToFileEx(const sFilename: string;
|
|
iJpegQuality: integer = 0): Boolean;
|
|
const
|
|
Reset_Jpeg_Orientation_On_Save = False;
|
|
begin
|
|
try
|
|
if iJpegQuality > 0 then
|
|
Params.JPEG_Quality := iJpegQuality;
|
|
|
|
if Reset_Jpeg_Orientation_On_Save then
|
|
Params.EXIF_Orientation := _exoCorrectOrientation;
|
|
|
|
SavetoFile(sFilename);
|
|
|
|
Result := not Aborting;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.SaveToStreamEx
|
|
|
|
<FM>Declaration<FC>
|
|
function SaveToStreamEx(Stream: TStream; FileType: <A TIOFileType>; iJpegQuality: integer = 0): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnIO.SaveToStream>, optionally setting <A TIOParams.JPEG_Quality>.
|
|
You must specify the <L TIOFileType>file format</L>.
|
|
Returns True if saving was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Save the image to MyImage.jpeg at 90% quality
|
|
ImageEnView1.IO.SaveToStreamEx( DestStream, ioJPEG, 90 );
|
|
!!}
|
|
function TImageEnIOHelper.SaveToStreamEx(Stream: TStream; FileType: integer; iJpegQuality: integer = 0): Boolean;
|
|
const
|
|
Reset_Jpeg_Orientation_On_Save = False;
|
|
begin
|
|
try
|
|
if FileType = ioUnknown then
|
|
raise EIEException.create('Invalid File Type');
|
|
|
|
if iJpegQuality > 0 then
|
|
Params.JPEG_Quality := iJpegQuality;
|
|
|
|
if Reset_Jpeg_Orientation_On_Save then
|
|
Params.EXIF_Orientation := _exoCorrectOrientation;
|
|
|
|
SaveToStream(Stream, FileType);
|
|
|
|
Result := not Aborting;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.CreatePDFFromFileList
|
|
|
|
<FM>Declaration<FC>
|
|
function CreatePDFFromFileList(const sDestFilename : string;
|
|
ssFileList : TStrings;
|
|
const aPaperSize : <A TIOPDFPaperSize>;
|
|
const aCompression : <A TIOPDFCompression>;
|
|
const sTitle : string;
|
|
const sAuthor : string;
|
|
const bFailOnUnsupportedImage : Boolean = True;
|
|
const bRaiseExceptions : Boolean = False
|
|
) : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Generates a PDF file from all images specified in a TStrings list, by combining the functions of <A TImageEnIO.CreatePDFFile>, <A TImageEnIO.SaveToPDF> and <A TImageEnIO.ClosePDFFile>.
|
|
Result is true unless an error is encountered.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>sDestFilename<FN></C> <C>The .PDF filename to save the file to</C> </R>
|
|
<R> <C><FC>ssFileList<FN></C> <C>A list of all images to add to the PDF file</C> </R>
|
|
<R> <C><FC>aPaperSize<FN></C> <C>The <L TIOPDFPaperSize>size</L> at which to create the PDF file</C> </R>
|
|
<R> <C><FC>aCompression<FN></C> <C>The level of <L TIOPDFCompression>compression</L> to use</C> </R>
|
|
<R> <C><FC>sTitle<FN></C> <C>The title for the PDF document (appears in "Properties")</C> </R>
|
|
<R> <C><FC>sAuthor<FN></C> <C>The author for the PDF document (appears in "Properties")</C> </R>
|
|
<R> <C><FC>bFailOnUnsupportedImage<FN></C> <C>When true this procedure will fail if unsupported images (or other file types) are found in ssFileList. If false, unsupported file types are skipped</C> </R>
|
|
<R> <C><FC>bRaiseExceptions<FN></C> <C>When true this procedure will generate an exception if it fails. If false, you will need to check the result to detect failure</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
CreatePDFFromFileList('D:\MyNewPDF.pdf',
|
|
ssMyImageList,
|
|
iepA4,
|
|
ioPDF_JPEG,
|
|
'My Cool PDF',
|
|
'Mr Developer');
|
|
!!}
|
|
{$IFDEF IEINCLUDEPDFWRITING}
|
|
function TImageEnIOHelper.CreatePDFFromFileList(const sDestFilename : string;
|
|
ssFileList : TStrings;
|
|
const aPaperSize : TIOPDFPaperSize;
|
|
const aCompression : TIOPDFCompression;
|
|
const sTitle : string;
|
|
const sAuthor : string;
|
|
const bFailOnUnsupportedImage : Boolean = True;
|
|
const bRaiseExceptions : Boolean = False
|
|
) : Boolean;
|
|
var
|
|
I: Integer;
|
|
sCurrFile: string;
|
|
begin
|
|
Result := True;
|
|
try
|
|
Params.PDF_PaperSize := aPaperSize;
|
|
Params.PDF_Title := AnsiString(sTitle);
|
|
Params.PDF_Author := AnsiString(sAuthor);
|
|
CreatePDFFile(sDestFilename);
|
|
|
|
for I := 0 to ssFileList.Count - 1 do
|
|
begin
|
|
sCurrFile := ssFileList[I];
|
|
if (bFailOnUnsupportedImage = False) or IsKnownFormat(sCurrFile) then
|
|
begin
|
|
LoadFromFile(sCurrFile);
|
|
Params.PDF_Compression := aCompression;
|
|
SaveToPDF;
|
|
end;
|
|
end;
|
|
|
|
ClosePDFFile;
|
|
Except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.CreatePSFromFileList
|
|
|
|
<FM>Declaration<FC>
|
|
function CreatePSFromFileList(const sDestFilename : string;
|
|
ssFileList : TStrings;
|
|
const aPaperSize : <A TIOPDFPaperSize>;
|
|
const aCompression : <A TIOPSCompression>;
|
|
const sTitle : string = '';
|
|
const bFailOnUnsupportedImage : Boolean = True;
|
|
const bRaiseExceptions : Boolean = False
|
|
) : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Generates a PS file from all images specified in a TStrings list, by combining the functions of <A TImageEnIO.CreatePSFile>, <A TImageEnIO.SaveToPS> and <A TImageEnIO.ClosePSFile>.
|
|
Result is true unless an error is encountered.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>sDestFilename<FN></C> <C>The .PS filename to save the file to</C> </R>
|
|
<R> <C><FC>ssFileList<FN></C> <C>A list of all images to add to the PS file</C> </R>
|
|
<R> <C><FC>aPaperSize<FN></C> <C>The <L TIOPDFPaperSize>size</L> at which to create the PS file</C> </R>
|
|
<R> <C><FC>aCompression<FN></C> <C>The level of <L TIOPSCompression>compression</L> to use</C> </R>
|
|
<R> <C><FC>sTitle<FN></C> <C>The title for the PS document</C> </R>
|
|
<R> <C><FC>bFailOnUnsupportedImage<FN></C> <C>When true this procedure will fail if unsupported images (or other file types) are found in ssFileList. If false, unsupported file types are skipped</C> </R>
|
|
<R> <C><FC>bRaiseExceptions<FN></C> <C>When true this procedure will generate an exception if it fails. If false, you will need to check the result to detect failure</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
CreatePSFromFileList('D:\MyNewPS.PS',
|
|
ssMyImageList,
|
|
iepA4,
|
|
ioPS_JPEG);
|
|
!!}
|
|
function TImageEnIOHelper.CreatePSFromFileList(const sDestFilename : string;
|
|
ssFileList : TStrings;
|
|
const aPaperSize : TIOPDFPaperSize;
|
|
const aCompression : TIOPSCompression;
|
|
const sTitle : string = '';
|
|
const bFailOnUnsupportedImage : Boolean = True;
|
|
const bRaiseExceptions : Boolean = False
|
|
) : Boolean;
|
|
var
|
|
I: Integer;
|
|
sCurrFile: string;
|
|
begin
|
|
Result := True;
|
|
try
|
|
Params.PS_PaperSize := aPaperSize;
|
|
Params.PS_Title := AnsiString(sTitle);
|
|
CreatePSFile(sDestFilename);
|
|
|
|
for I := 0 to ssFileList.Count - 1 do
|
|
begin
|
|
sCurrFile := ssFileList[I];
|
|
if (bFailOnUnsupportedImage = False) or IsKnownFormat(sCurrFile) then
|
|
begin
|
|
LoadFromFile(sCurrFile);
|
|
Params.PS_Compression := aCompression;
|
|
SaveToPS;
|
|
end;
|
|
end;
|
|
|
|
ClosePSFile;
|
|
Except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromBlob
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromBlob(aField: TBlobField;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Uses streams to load an image from the blob field of a database table, optionally setting <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images and <A TIOParams.ImageIndex> to display a specific image.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
Note: You must define IE_DB_Helpers in iexHelperFunctions.pas to use this method
|
|
|
|
<FM>Example<FC>
|
|
// Load the image from the MyTableImageBlob field at the current position in the database
|
|
ImageEnView1.IO.LoadFromBlob(MyTableImageBlob);
|
|
!!}
|
|
{$IFDEF IE_DB_Helpers}
|
|
function TImageEnIOHelper.LoadFromBlob(aField: TBlobField;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1
|
|
): Boolean;
|
|
begin
|
|
Result := LoadFromBlobFast( aField, 0, 0, bAutoAdjustOrientation, iImageIndex);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{!!
|
|
<FS>TImageEnIO.LoadFromBlobFast
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromBlobFast(aField: TBlobField;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Uses streams to load an image from the blob field of a database table and allows you to specify a maximum size that you require an image so that it can be loaded as fast as possible, by using:
|
|
- <A TIOParams.JPEG_Scale> for JPEGs
|
|
- <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files
|
|
- <A TIOParams.IEN_GetThumbnail> for IEN files
|
|
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images
|
|
|
|
Returns True if loading was successful, or False on error
|
|
|
|
Note: You must define IE_DB_Helpers in iexHelperFunctions.pas to use this method
|
|
|
|
<FM>Example<FC>
|
|
// Load the image from the MyTableImageBlob field as fast as possible, but bigger than the displaying TImageEnView
|
|
ImageEnView1.AutoShrink := True;
|
|
ImageEnView1.IO.LoadFromBlobFast(MyTableImageBlob, ImageEnView1.Width, ImageEnView1.Height)
|
|
!!}
|
|
{$IFDEF IE_DB_Helpers}
|
|
function TImageEnIOHelper.LoadFromBlobFast(aField: TBlobField;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
iImageIndex : Integer = -1
|
|
): Boolean;
|
|
var
|
|
aMemStream: TMemoryStream;
|
|
bFastLoad: Boolean;
|
|
begin
|
|
Result := True;
|
|
try
|
|
// SET PARAMS
|
|
bFastLoad := (iMaxX > 0) and (iMaxY > 0);
|
|
if bFastLoad then
|
|
begin
|
|
{$IFDEF IEINCLUDERAWFORMATS}
|
|
// RAW PARAMS
|
|
Params.RAW_HalfSize := (iMaxX <= SMALLEST_RAW_IMAGE_WIDTH) and (iMaxY <= SMALLEST_RAW_IMAGE_HEIGHT);
|
|
Params.RAW_GetExifThumbnail := (iMaxX <= SMALLEST_RAW_THUMBNAIL_WIDTH) and (iMaxY <= SMALLEST_RAW_THUMBNAIL_HEIGHT);
|
|
{$ENDIF}
|
|
|
|
// JPEG PARAMS
|
|
Params.Width := iMaxX;
|
|
Params.Height := iMaxY;
|
|
Params.JPEG_Scale := ioJPEG_AUTOCALC;
|
|
|
|
Params.IEN_GetThumbnail := ( iMaxX <= IEGlobalSettings().ThumbnailSize ) and ( iMaxY <= IEGlobalSettings().ThumbnailSize );
|
|
|
|
// Is it a thumbnail?
|
|
if iMaxX + iMaxY < 500 then
|
|
Params.JPEG_DCTMethod := ioJPEG_IFAST;
|
|
end
|
|
else
|
|
begin
|
|
// reset any fast loading variables
|
|
Params.RAW_HalfSize := false;
|
|
Params.RAW_GetExifThumbnail := false;
|
|
|
|
Params.JPEG_Scale := ioJPEG_fullsize;
|
|
Params.JPEG_DCTMethod := ioJPEG_ISLOW;
|
|
end;
|
|
|
|
Params.EnableAdjustOrientation := bAutoAdjustOrientation;
|
|
if iImageIndex <> -1 then
|
|
Params.ImageIndex := iImageIndex;
|
|
|
|
aMemStream := TMemoryStream.create;
|
|
try
|
|
aField.SaveToStream( aMemStream );
|
|
aMemStream.Position := 0;
|
|
LoadFromStream(aMemStream);
|
|
finally
|
|
aMemStream.free;
|
|
end;
|
|
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnIO.SaveToBlob
|
|
|
|
<FM>Declaration<FC>
|
|
function SaveToBlob(aField : TBlobField;
|
|
aFileType : TIOFileType;
|
|
iJpegQuality: integer = 0): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Uses streams to set a blob field with an image, optionally setting <A TIOParams.JPEG_Quality>. You must specify a <L TIOFileType>file type</L>, e.g. ioJPEG.
|
|
Returns True if saving was successful, or False on error
|
|
|
|
Note: You must define IE_DB_Helpers in iexHelperFunctions.pas to use this method
|
|
|
|
<FM>Example<FC>
|
|
// Update the current image in the table with that displayed in our TImageEnView
|
|
MyDBTable.Edit;
|
|
ImageEnView1.IO.SaveToFileEx(MyDBTableImageField, ioJPEG, 90)
|
|
MyDBTableEditDate.AsDateTime := Now;
|
|
MyDBTable.Post;
|
|
!!}
|
|
{$IFDEF IE_DB_Helpers}
|
|
function TImageEnIOHelper.SaveToBlob(aField : TBlobField;
|
|
aFileType : TIOFileType;
|
|
iJpegQuality: integer = 0): Boolean;
|
|
const
|
|
Reset_Jpeg_Orientation_On_Save = False;
|
|
var
|
|
aMemStream: TMemoryStream;
|
|
aBlobStream: TStream;
|
|
begin
|
|
Result := False;
|
|
|
|
if aFileType <> ioUnknown then
|
|
try
|
|
if iJpegQuality > 0 then
|
|
Params.JPEG_Quality := iJpegQuality;
|
|
|
|
if Reset_Jpeg_Orientation_On_Save then
|
|
Params.EXIF_Orientation := _exoCorrectOrientation;
|
|
|
|
aMemStream := TMemoryStream.create;
|
|
try
|
|
SaveToStream(aMemStream, aFileType);
|
|
aMemStream.Position := 0;
|
|
|
|
aBlobStream := aField.DataSet.CreateBlobStream( aField, bmWrite );
|
|
try
|
|
aMemStream.SaveToStream(aBlobStream);
|
|
finally
|
|
aBlobStream.Free;
|
|
end;
|
|
|
|
result := true;
|
|
finally
|
|
aMemStream.free;
|
|
end;
|
|
except
|
|
result := False;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
{ TBitmapHelper }
|
|
|
|
// Provide link to TBitmap references
|
|
{!!
|
|
<FS>TBitmap
|
|
|
|
<FM>Description<FN>
|
|
Standard Windows TBitmap class. See Delphi documentation for more detail.
|
|
|
|
ImageEn provides a similar class for holding images in memory, <A TIEBitmap>.
|
|
!!}
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.IEInitialize
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEInitialize(iWidth, iHeight: Integer; ABackgroundColor : TColor = clNone);
|
|
|
|
<FM>Description<FN>
|
|
Resizes a bitmap and optionally fills it with the specified color.
|
|
|
|
<FM>Example<FC>
|
|
// Make a bitmap of screen size and black background
|
|
MyBitmap.IEInitialize(Screen.Width, Screen.Height, clBlack);
|
|
!!}
|
|
procedure TBitmapHelper.IEInitialize(iWidth, iHeight: Integer; ABackgroundColor : TColor = clNone);
|
|
begin
|
|
Width := iWidth;
|
|
Height := iHeight;
|
|
|
|
if ABackgroundColor <> clNone then
|
|
begin
|
|
Canvas.Brush.Color := ABackgroundColor;
|
|
Canvas.FillRect(Rect(0, 0, Width, Height));
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TBitmap.IERotate
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IERotate(Angle: double; AntiAliasMode: <A TIEAntialiasMode> = ierFast; BackgroundColor: TColor = -1);
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnProc.Rotate> to rotate a TBitmap.
|
|
|
|
<FM>Example<FC>
|
|
// Rotate the image 90 deg. counter-clockwise
|
|
MyBitmap.IERotate(90);
|
|
|
|
// Rotate the image 45 deg. clockwise and fill new areas with black
|
|
MyBitmap.IERotate(315, ierFast, clBlack);
|
|
!!}
|
|
procedure TBitmapHelper.IERotate(Angle: double; AntiAliasMode: TIEAntialiasMode = ierFast; BackgroundColor: TColor = -1);
|
|
var
|
|
AImageEnProc: TImageEnProc;
|
|
begin
|
|
AImageEnProc := TImageEnProc.CreateFromBitmap(self);
|
|
try
|
|
AImageEnProc.Rotate(Angle, AntialiasMode, BackgroundColor);
|
|
finally
|
|
AImageEnProc.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.IEFlip
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEFlip(Direction: <A TFlipDir>);
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnProc.Flip> to flip a TBitmap.
|
|
|
|
<FM>Example<FC>
|
|
// Flip the bitmap image horizontally
|
|
MyBitmap.IEFlip(fdHorizontal);
|
|
!!}
|
|
procedure TBitmapHelper.IEFlip(Direction: TFlipDir);
|
|
var
|
|
AImageEnProc: TImageEnProc;
|
|
begin
|
|
AImageEnProc := TImageEnProc.CreateFromBitmap(self);
|
|
try
|
|
AImageEnProc.Flip(Direction);
|
|
finally
|
|
AImageEnProc.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.IEResample
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEResample(iNewWidth, iNewHeight: integer; QualityFilter: TResampleFilter = rfNone; bMaintainAspectRatio : Boolean = False);
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnProc.Resample> to resize a TBitmap and its content.
|
|
|
|
<FM>Example<FC>
|
|
// Resize the bitmap to screen dimensions (and good quality)
|
|
MyBitmap.IEResample(Screen.Width, Screen.Height, rfLanczos3);
|
|
!!}
|
|
procedure TBitmapHelper.IEResample(iNewWidth, iNewHeight: integer; QualityFilter: TResampleFilter = rfNone; bMaintainAspectRatio : Boolean = False);
|
|
var
|
|
AImageEnProc: TImageEnProc;
|
|
begin
|
|
if (Width = iNewWidth) and (Height = iNewHeight) then
|
|
exit;
|
|
|
|
AImageEnProc := TImageEnProc.CreateFromBitmap(Self);
|
|
try
|
|
AImageEnProc.Resample(iNewWidth, iNewHeight, QualityFilter, bMaintainAspectRatio);
|
|
finally
|
|
AImageEnProc.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.IELoadFromFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromFile(const sFilename : string): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TBitmap to load any format supported by ImageEn.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Load MyImage.jpeg into a bitmap
|
|
MyBitmap.IELoadFromFile('D:\MyImage.jpeg')
|
|
!!}
|
|
function TBitmapHelper.IELoadFromFile(const sFilename: string): Boolean;
|
|
begin
|
|
Result := IELoadFromFileFast(sFilename, -1, -1);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TBitmap.IELoadFromStream
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromStream(Stream: TStream; FileType: <A TIOFileType> = 0): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TBitmap to load any format supported by ImageEn.
|
|
If you know the <L TIOFileType>FileType</L> type of the stream, pass it to speed up loading.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Load MyImage.jpeg into a bitmap
|
|
MyBitmap.IELoadFromStream( MyStream )
|
|
!!}
|
|
function TBitmapHelper.IELoadFromStream(Stream: TStream; FileType: integer = 0): Boolean;
|
|
begin
|
|
Result := IELoadFromStreamFast(Stream, FileType, -1, -1);
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.IELoadFromFileFast
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromFileFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows you to load an image into a TBitmap using the fastest method by specifying the maximum size it is required. It uses:
|
|
- <A TIOParams.JPEG_Scale> for JPEGs
|
|
- <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files
|
|
- <A TIOParams.IEN_GetThumbnail> for IEN files
|
|
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images.
|
|
|
|
Returns True if loading was successful, or False on error.
|
|
|
|
<FM>Example<FC>
|
|
// Load the specified image as fast as possible, but bigger than screen size
|
|
MyBitmap.IELoadFromFileFast('D:\MyImage.jpeg', Screen.Width, Screen.Height)
|
|
!!}
|
|
function TBitmapHelper.IELoadFromFileFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
Result := True;
|
|
try
|
|
if IEFilenameInExtensions(sFilename, '.bmp') then
|
|
begin
|
|
LoadFromFile(sFilename);
|
|
end
|
|
else
|
|
begin
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
// Loaded image may have transparency (e.g. WMF files), so match background color to existing background of images (i.e. honour IEInitialize)
|
|
if (Width > 0) and (Height > 0) then
|
|
AImageEnIO.Background := Canvas.Pixels[0, 0];
|
|
Result := AImageEnIO.LoadFromFileFast(sFilename, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
AImageEnIO.Free;
|
|
end;
|
|
except
|
|
result := False;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TBitmap.IELoadFromStreamFast
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromStreamFast(Stream: TStream; FileType: <A TIOFileType>;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows you to load an image into a TBitmap using the fastest method by specifying the maximum size it is required. It uses:
|
|
- <A TIOParams.JPEG_Scale> for JPEGs
|
|
- <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files
|
|
- <A TIOParams.IEN_GetThumbnail> for IEN files
|
|
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images.
|
|
|
|
If you know the <L TIOFileType>FileType</L> type of the stream, pass it to speed up loading. Otherwise specify ioUnknown.
|
|
|
|
Returns True if loading was successful, or False on error.
|
|
|
|
<FM>Example<FC>
|
|
// Load the specified image as fast as possible, but bigger than screen size
|
|
MyBitmap.IELoadFromStreamFast( MyStream, ioUnknown, Screen.Width, Screen.Height )
|
|
!!}
|
|
function TBitmapHelper.IELoadFromStreamFast(Stream: TStream;
|
|
FileType: Integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
try
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
// Loaded image may have transparency (e.g. WMF files), so match background color to existing background of images (i.e. honour IEInitialize)
|
|
if (Width > 0) and (Height > 0) then
|
|
AImageEnIO.Background := Canvas.Pixels[0, 0];
|
|
Result := AImageEnIO.LoadFromStreamFast(Stream, FileType, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
AImageEnIO.Free;
|
|
except
|
|
result := False;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.LoadFromURL
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromURL(const URL : WideString;
|
|
const sProxyAddress : WideString = '';
|
|
const sProxyUser : WideString = '';
|
|
const sProxyPassword : WideString = ''
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Load an image from the internet using the HTTP or FTP protocol.
|
|
|
|
Note: See documentation for <L TImageEnIO.LoadFromURL>TImageEnIO.LoadFromURL</L>
|
|
|
|
<FM>Example<FC>
|
|
MyBitmapLoadFromURL('http://www.imageen.com/image.jpg');
|
|
!!}
|
|
function TBitmapHelper.LoadFromURL(const URL : WideString;
|
|
const sProxyAddress : WideString = '';
|
|
const sProxyUser : WideString = '';
|
|
const sProxyPassword : WideString = ''
|
|
): Boolean;
|
|
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
try
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
|
|
IEGlobalSettings().ProxyAddress := sProxyAddress;
|
|
IEGlobalSettings().ProxyUser := sProxyUser;
|
|
IEGlobalSettings().ProxyPassword := sProxyPassword;
|
|
|
|
Result := AImageEnIO.LoadFromURL(URL);
|
|
AImageEnIO.Free;
|
|
except
|
|
result := False;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TBitmap.IESaveToFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IESaveToFile(const sFilename : string; iJPEGQuality : Integer): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TBitmap to save to any format supported by ImageEn. If you are saving to JPEG you can also specify the <A TIOParams.JPEG_Quality>.
|
|
Returns True if saving was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Save the image at 90% quality
|
|
MyBitmap.IESaveToFile(SavePictureDialog1.FileName, 90);
|
|
!!}
|
|
function TBitmapHelper.IESaveToFile(const sFilename: string; iJPEGQuality : Integer): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
result := True;
|
|
try
|
|
if IEFilenameInExtensions(sFilename, '.bmp') then
|
|
begin
|
|
SaveToFile(sFilename);
|
|
end
|
|
else
|
|
begin
|
|
if PixelFormat = pfDevice then
|
|
PixelFormat := pf24bit;
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
Result := AImageEnIO.SaveToFileEx(sFilename, iJPEGQuality);
|
|
AImageEnIO.Free;
|
|
end;
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TBitmap.IESaveToStream
|
|
|
|
<FM>Declaration<FC>
|
|
function IESaveToStream(Stream: TStream; FileType: integer; iJPEGQuality : Integer): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TBitmap to save to any format supported by ImageEn. If you are saving to JPEG you can also specify the <A TIOParams.JPEG_Quality>.
|
|
You must specify the <L TIOFileType>file format</L>.
|
|
Returns True if saving was successful, or False on error
|
|
|
|
<FM>Example<FC>
|
|
// Save the image at 90% quality
|
|
MyBitmap.IESaveToStream( DestStream, ioJPEG, 90 );
|
|
!!}
|
|
function TBitmapHelper.IESaveToStream(Stream: TStream; FileType: integer; iJPEGQuality : Integer): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
try
|
|
if PixelFormat = pfDevice then
|
|
PixelFormat := pf24bit;
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
Result := AImageEnIO.SaveToStreamEx(Stream, FileType, iJPEGQuality);
|
|
AImageEnIO.Free;
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
// CalcSoftShadowWidth: Use IESoftShadowSize
|
|
|
|
{!!
|
|
<FS>TBitmap.IELoadAsThumbnail
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadAsThumbnail(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter : <A TResampleFilter> = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
) : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Loads an image of any format into a TBitmap reducing it to the specified size (while maintaining the aspect ratio, thus one of the dimensions is likely to be less than the specified value).
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>iMaxX, iMaxY<FN></C> <C>The maximum size of the new image (as the aspect ratio is maintained, one of the dimensions is likely to be less than the specified value)</C> </R>
|
|
<R> <C><FC>bCanStretch<FN></C> <C>Set to false to avoid images smaller than iMaxX x iMaxY from being made larger</C> </R>
|
|
<R> <C><FC>bAutoAdjustOrientation<FN></C> <C>Sets <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images</C> </R>
|
|
<R> <C><FC>QualityFilter<FN></C> <C>Specify the quality that is used for rescaling the image</C> </R>
|
|
<R> <C><FC>bAddBorder<FN></C> <C>Set to true to add a 1 pixel border to the thumbnail</C> </R>
|
|
<R> <C><FC>cBorderColor<FN></C> <C>The color of the added border</C> </R>
|
|
<R> <C><FC>bAddShadow<FN></C> <C>Add a solid or soft shadow to the image</C> </R>
|
|
<R> <C><FC>iBlurRadius<FN></C> <C>Set to 0 to add a solid shadow or any other value for the width of the <L TImageEnProc.AddSoftShadow>Soft Shadow</L></C> </R>
|
|
<R> <C><FC>iShadowOffset<FN></C> <C>The <L TImageEnProc.AddSoftShadow>offset</L> of the shadow from the image</C> </R>
|
|
<R> <C><FC>cShadowColor<FN></C> <C>The shadow color</C> </R>
|
|
<R> <C><FC>cBGColor<FN></C> <C>The color of the image behind the shadow</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Load an image at the size 160x120
|
|
MyBitmap.IELoadAsThumbnail('D:\MyImage.jpeg', 160, 120, False);
|
|
!!}
|
|
function TBitmapHelper.IELoadAsThumbnail(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter : TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
) : Boolean;
|
|
begin
|
|
try
|
|
Result := IELoadFromFileFast(sFilename, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
if Result then
|
|
IEConvertToThumbnail(iMaxX, iMaxY, bCanStretch, QualityFilter,
|
|
bAddBorder, cBorderColor,
|
|
bAddShadow, iBlurRadius, iShadowOffset, cShadowColor, cBGColor);
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
procedure TBitmapHelper.ConvertTo24Bit;
|
|
var
|
|
AImageEnProc: TImageEnProc;
|
|
begin
|
|
AImageEnProc := TImageEnProc.CreateFromBitmap(Self);
|
|
try
|
|
AImageEnProc.ConvertTo24Bit;
|
|
finally
|
|
AImageEnProc.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.IEConvertToThumbnail
|
|
|
|
<FM>Declaration<FC>
|
|
|
|
procedure IEConvertToThumbnail(iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
QualityFilter : <A TResampleFilter> = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite);
|
|
|
|
<FM>Description<FN>
|
|
Resize an image in a TBitmap to the specified size (while maintaining the aspect ratio, thus one of the dimensions is likely to be less than the specified value).
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>iMaxX, iMaxY<FN></C> <C>The maximum size of the new image (as the aspect ratio is maintained, one of the dimensions is likely to be less than the specified value)</C> </R>
|
|
<R> <C><FC>bCanStretch<FN></C> <C>Set to false to avoid images smaller than iMaxX x iMaxY from being made larger</C> </R>
|
|
<R> <C><FC>bAutoAdjustOrientation<FN></C> <C>Sets <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images</C> </R>
|
|
<R> <C><FC>QualityFilter<FN></C> <C>Specify the quality that is used for rescaling the image</C> </R>
|
|
<R> <C><FC>bAddBorder<FN></C> <C>Set to true to add a 1 pixel border to the thumbnail</C> </R>
|
|
<R> <C><FC>cBorderColor<FN></C> <C>The color of the added border</C> </R>
|
|
<R> <C><FC>bAddShadow<FN></C> <C>Add a solid or soft shadow to the image</C> </R>
|
|
<R> <C><FC>iBlurRadius<FN></C> <C>Set to 0 to add a solid shadow or any other value for the width of the <L TImageEnProc.AddSoftShadow>Soft Shadow</L></C> </R>
|
|
<R> <C><FC>iShadowOffset<FN></C> <C>The <L TImageEnProc.AddSoftShadow>offset</L> of the shadow from the image</C> </R>
|
|
<R> <C><FC>cShadowColor<FN></C> <C>The shadow color</C> </R>
|
|
<R> <C><FC>cBGColor<FN></C> <C>The color of the image behind the shadow</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Resize the current bitmap image to 160x120 with a black border
|
|
MyBitmap.IEConvertToThumbnail(160, 120, True, rfFastLinear, True, clBlack);
|
|
!!}
|
|
procedure TBitmapHelper.IEConvertToThumbnail(iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
QualityFilter : TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite);
|
|
var
|
|
ASize: TPoint;
|
|
bUseSoftShadow : Boolean;
|
|
begin
|
|
bUseSoftShadow := iBlurRadius > 0;
|
|
|
|
// if a shadow is to be added remove the size of the shadow from the bitmap dimension
|
|
if bAddShadow and bUseSoftShadow then
|
|
begin
|
|
Dec(iMaxX, IESoftShadowSize(iBlurRadius, iShadowOffset, iShadowOffset));
|
|
Dec(iMaxY, IESoftShadowSize(iBlurRadius, iShadowOffset, iShadowOffset));
|
|
end
|
|
else
|
|
if bAddShadow and (bUseSoftShadow = false) then
|
|
begin
|
|
Dec(iMaxX, iShadowOffset);
|
|
Dec(iMaxY, iShadowOffset);
|
|
end;
|
|
|
|
if baddshadow or bAddBorder then
|
|
ConvertTo24Bit;
|
|
|
|
if PixelFormat = pfCustom then
|
|
PixelFormat := pf24bit;
|
|
|
|
// RESIZE
|
|
ASize := GetImageSizeWithinArea(Width, Height, iMaxX, iMaxY);
|
|
if bCanStretch or (Width > ASize.X) then
|
|
IEResample(ASize.X, ASize.Y, QualityFilter, false);
|
|
|
|
|
|
// BORDER
|
|
if bAddBorder then
|
|
begin
|
|
Canvas.pen.color := cBorderColor;
|
|
Canvas.Polyline([Point(0, 0),
|
|
Point(Width - 1, 0),
|
|
Point(Width - 1, Height - 1),
|
|
Point(0, Height - 1),
|
|
Point(0, 0)]);
|
|
end;
|
|
|
|
// SHADOW
|
|
if bAddShadow then
|
|
begin
|
|
if bUseSoftShadow then
|
|
IEAddSoftShadow(iBlurRadius, iShadowOffset, cBGColor, _loTopLeft, cShadowColor)
|
|
else
|
|
begin
|
|
// add back the pixels we removed
|
|
width := width + iShadowOffset;
|
|
Height := Height + iShadowOffset;
|
|
|
|
// Draw the shadowm
|
|
Canvas.Brush.color := cShadowColor;
|
|
|
|
// along the right
|
|
Canvas.FillRect(Rect(Width - iShadowOffset, 0, Width, Height));
|
|
|
|
// along the bottom
|
|
Canvas.FillRect(Rect(0, Height - iShadowOffset, Width, Height));
|
|
|
|
// now add the background color
|
|
Canvas.Brush.color := cBGColor;
|
|
|
|
// at the top right
|
|
Canvas.FillRect(Rect(Width - iShadowOffset, 0, Width, iShadowOffset));
|
|
|
|
// at the bottom left
|
|
Canvas.FillRect(Rect(0, Height - iShadowOffset, iShadowOffset, Height));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.IEAddSoftShadow
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEAddSoftShadow(iBlurRadius: integer;
|
|
iShadowOffset : Integer;
|
|
cBGColor: TColor;
|
|
LightOrigin: <A TLightOrigin> = _loTopLeft;
|
|
cShadowColor: TColor = clblack);
|
|
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnProc.AddSoftShadow> to add a soft shadow to an image in a TBitmap
|
|
|
|
<FM>Example<FC>
|
|
// Add a soft shadow to the bitmap image
|
|
MyBitmap.IEAddSoftShadow(3, 3, clWhite);
|
|
!!}
|
|
procedure TBitmapHelper.IEAddSoftShadow(iBlurRadius: integer;
|
|
iShadowOffset : Integer;
|
|
cBGColor: TColor;
|
|
LightOrigin: TLightOrigin = _loTopLeft;
|
|
cShadowColor: TColor = clblack);
|
|
var
|
|
ie: TImageEnView;
|
|
iOffSetX, iOffSetY: integer;
|
|
begin
|
|
ie := TImageEnView.Create(nil);
|
|
try
|
|
ie.Background := cBGColor;
|
|
ie.Bitmap.assign(Self);
|
|
ie.update;
|
|
iOffSetX := iShadowOffset;
|
|
iOffSetY := iShadowOffset;
|
|
if LightOrigin in [_loTopRight, _loBottomRight] then
|
|
iOffSetX := -iOffSetX;
|
|
if LightOrigin in [_loBottomLeft, _loBottomRight] then
|
|
iOffSetY := -iOffSetY;
|
|
|
|
ie.Proc.AddSoftShadow(iBlurRadius, iOffSetX, iOffSetY, TRUE, cShadowColor);
|
|
ie.RemoveAlphaChannel(True);
|
|
Self.assign(ie.bitmap);
|
|
finally
|
|
ie.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TBitmap.PrintImage
|
|
|
|
<FM>Declaration<FC>
|
|
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; SubsampleFilter: <A TResampleFilter> = rfFastLinear);
|
|
|
|
<FM>Description<FN>
|
|
Print the current bitmap 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. Generally the application will pass this as 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>SubsampleFilter<FN></C> <C>The filter that is used to enhance quality if hte image needs to be resampled for printing</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Print the image in the center of the page at the original size
|
|
Printer.BeginDoc;
|
|
ABitmap.PrintImage(Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesNormal, 0, 0, 1);
|
|
Printer.EndDoc;
|
|
|
|
// Print the image in the center of the page stretched to page dimensions (respecting the proportions)
|
|
Printer.BeginDoc;
|
|
ABitmap.PrintImage(Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesFitToPage, 0, 0, 1);
|
|
Printer.EndDoc;
|
|
|
|
// Print the image as a poster, four pages wide and six pages high
|
|
Printer.BeginDoc;
|
|
ABitmap.PrintImage(Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesMultiplePages, 4, 6, 1);
|
|
Printer.EndDoc;
|
|
|
|
!!}
|
|
|
|
procedure TBitmapHelper.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;
|
|
SubsampleFilter: TResampleFilter = rfFastLinear);
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
try
|
|
AImageEnIO.PrintingFilterOnSubsampling := SubsampleFilter;
|
|
AImageEnIO.PrintImage(PrtCanvas, MarginLeft, MarginTop, MarginRight, MarginBottom, VerticalPos, HorizontalPos, Size, SpecWidth, SpecHeight, GammaCorrection);
|
|
finally
|
|
AImageEnIO.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
|
|
{$IFDEF Delphi2005orNewer}
|
|
{ TIEBitmapHelper }
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IEInitialize
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEInitialize(iWidth, iHeight: Integer; ABackgroundColor : TColor = clNone); overload;
|
|
procedure IEInitialize(iWidth, iHeight: Integer; Transparent: Boolean); overload;
|
|
|
|
<FM>Description<FN>
|
|
Resizes a TIEBitmap and optionally fills it with the specified color (or make transparent).
|
|
|
|
<FM>Example<FC>
|
|
// Resize the IEBitmap to screen size with a black background
|
|
MyIEBitmap.IEInitialize(Screen.Width, Screen.Height, clBlack);
|
|
|
|
// Resize the IEBitmap to screen size with transparency
|
|
MyIEBitmap.IEInitialize(Screen.Width, Screen.Height, clBlack, True);
|
|
!!}
|
|
procedure TIEBitmapHelper.IEInitialize(iWidth, iHeight: Integer; ABackgroundColor: TColor = clNone);
|
|
begin
|
|
Width := iWidth;
|
|
Height := iHeight;
|
|
|
|
if ABackgroundColor <> clNone then
|
|
begin
|
|
Canvas.Brush.Color := ABackgroundColor;
|
|
Canvas.FillRect(Rect(0, 0, Width, Height));
|
|
end;
|
|
end;
|
|
|
|
procedure TIEBitmapHelper.IEInitialize(iWidth, iHeight: Integer; Transparent: Boolean);
|
|
begin
|
|
Width := iWidth;
|
|
Height := iHeight;
|
|
|
|
if Transparent then
|
|
AlphaChannel.Fill(0);
|
|
end;
|
|
|
|
|
|
const
|
|
// The ImageEn types that can be loaded via WIC
|
|
WIC_SUPPORTED_FILETYPES = [ ioBMP, ioPNG, ioICO, ioJPEG, ioGIF, ioTIFF, ioHDP ];
|
|
|
|
|
|
function TIEBitmapHelper.IELoadFromFileEx(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean;
|
|
IOParams: TIOParams;
|
|
iImageIndex: Integer
|
|
): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
bFastJPEG: Boolean;
|
|
begin
|
|
try
|
|
// Can we use WIC to speed up loading?
|
|
bFastJPEG := (iMaxX > 0) and (iMaxY > 0) and IEFilenameInExtensions(sFilename, '*.jpeg;*.jpg;*.jpe;');
|
|
{$IFDEF IEINCLUDEWIC}
|
|
if ( IOParams = nil ) and
|
|
( bAutoAdjustOrientation = False ) and
|
|
( bFastJPEG = False ) and
|
|
( IEFilenameToInternalFileType( sFileName ) in WIC_SUPPORTED_FILETYPES ) then
|
|
begin
|
|
Result := WicRead( sFilename, iImageIndex );
|
|
end
|
|
else
|
|
{$ENDIF}
|
|
begin
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
if assigned( IOParams ) then
|
|
AImageEnIO.Params.Assign( IOParams as TIOParams );
|
|
if iImageIndex > 0 then
|
|
Result := AImageEnIO.LoadFromFileEx(sFilename, bAutoAdjustOrientation, iImageIndex)
|
|
else
|
|
Result := AImageEnIO.LoadFromFileFast(sFilename, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
if assigned( IOParams ) then
|
|
TIOParams( IOParams ).Assign( AImageEnIO.Params );
|
|
AImageEnIO.Free;
|
|
end;
|
|
except
|
|
result := False;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IELoadFromFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromFile(const sFilename : string; IOParams: <A TIOParams> = nil; iImageIndex: Integer = 0): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TIEBitmap to load any format supported by ImageEn.
|
|
You can optionally pass an <A TIOParams> object for the I/O parameters of the file. The index of an image to load within a multiframe format can also be specified.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
Note: Unlike <A TIEBitmap.Read>, IELoadFromStream will use <A TIEWicReader> for better performance where possible
|
|
|
|
<FM>Example<FC>
|
|
// Load the image specified in an open dialog
|
|
ImageEnView1.Bitmap.IELoadFromFile(OpenPictureDialog1.FileName)
|
|
!!}
|
|
function TIEBitmapHelper.IELoadFromFile(const sFilename: string; IOParams: TIOParams = nil; iImageIndex: Integer = 0): Boolean;
|
|
begin
|
|
Result := IELoadFromFileEx(sFilename, -1, -1, False, IOParams, iImageIndex);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IELoadFromFileFast
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromFileFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
IOParams: <A TIOParams> = nil
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows you to load an image into a TIEBitmap using the fastest method by specifying the maximum size it is required. It uses:
|
|
- <A TIOParams.JPEG_Scale> for JPEGs
|
|
- <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files
|
|
- <A TIOParams.IEN_GetThumbnail> for IEN files
|
|
- <A TIEWicReader> for other file types (where possible)
|
|
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images.
|
|
You can optionally pass an <A TIOParams> object for the I/O parameters of the file.
|
|
|
|
Returns True if loading was successful, or False on error.
|
|
|
|
<FM>Example<FC>
|
|
// Load the specified image as fast as possible, but bigger than the screen dimensions
|
|
MyIEBitmap.IELoadFromFileFast('D:\MyImage.jpeg', Screen.Width, Screen.Height)
|
|
!!}
|
|
function TIEBitmapHelper.IELoadFromFileFast(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
IOParams: TIOParams = nil
|
|
): Boolean;
|
|
begin
|
|
Result := IELoadFromFileEx( sFilename, iMaxX, iMaxY, bAutoAdjustOrientation, IOParams, 0 );
|
|
end;
|
|
|
|
|
|
function TIEBitmapHelper.IELoadFromStreamEx(Stream: TStream; FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean;
|
|
IOParams: TIOParams;
|
|
iImageIndex: Integer
|
|
): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
bFastJPEG: Boolean;
|
|
begin
|
|
try
|
|
if FileType = ioUnknown then
|
|
FileType := FindStreamFormat( Stream );
|
|
|
|
// Can we use WIC to speed up loading?
|
|
bFastJPEG := ( FileType = ioJPEG) and ( iMaxX > 0 ) and ( iMaxY > 0 );
|
|
{$IFDEF IEINCLUDEWIC}
|
|
if ( IOParams = nil ) and
|
|
( bAutoAdjustOrientation = False ) and
|
|
( bFastJPEG = False ) and
|
|
( FileType in WIC_SUPPORTED_FILETYPES ) then
|
|
begin
|
|
Result := WicRead( Stream, FileType );
|
|
end
|
|
else
|
|
{$ENDIF}
|
|
begin
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
if assigned( IOParams ) then
|
|
AImageEnIO.Params.Assign( IOParams as TIOParams );
|
|
if iImageIndex > 0 then
|
|
Result := AImageEnIO.LoadFromStreamEx(Stream, FileType, bAutoAdjustOrientation, iImageIndex)
|
|
else
|
|
Result := AImageEnIO.LoadFromStreamFast(Stream, FileType, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
if assigned( IOParams ) then
|
|
TIOParams( IOParams ).Assign( AImageEnIO.Params );
|
|
AImageEnIO.Free;
|
|
end;
|
|
except
|
|
result := False;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IELoadFromStream
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromStream(Stream: TStream; FileType: integer = 0; IOParams: <A TIOParams> = nil; iImageIndex: Integer = 0): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TIEBitmap to load any format supported by ImageEn.
|
|
If you know the <L TIOFileType>FileType</L> type of the stream, pass it to speed up loading.
|
|
You can optionally pass an <A TIOParams> object for the I/O parameters of the file. The index of an image to load within a multiframe format can also be specified.
|
|
Returns True if loading was successful, or False on error
|
|
|
|
Note: Unlike <A TIEBitmap.Read>, IELoadFromStream will use <A TIEWicReader> for better performance where possible
|
|
|
|
<FM>Example<FC>
|
|
ImageEnView1.Bitmap.IELoadFromStream(MyStream)
|
|
!!}
|
|
function TIEBitmapHelper.IELoadFromStream(Stream: TStream; FileType: integer = 0; IOParams: TIOParams = nil; iImageIndex: Integer = 0): Boolean;
|
|
begin
|
|
Result := IELoadFromStreamEx(Stream, FileType, -1, -1, False, IOParams, iImageIndex);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IELoadFromStreamFast
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadFromStreamFast(Stream: TStream;
|
|
FileType: <A TIOFileType>;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
IOParams: <A TIOParams> = nil
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows you to load an image into a TIEBitmap using the fastest method by specifying the maximum size it is required. It uses:
|
|
- <A TIOParams.JPEG_Scale> for JPEGs
|
|
- <A TIOParams.RAW_GetExifThumbnail> and <A TIOParams.RAW_HalfSize> for Camera Raw files
|
|
- <A TIOParams.IEN_GetThumbnail> for IEN files
|
|
- <A TIEWicReader> for other file types (where possible)
|
|
|
|
You can also set <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images.
|
|
If you know the <L TIOFileType>FileType</L> type of the stream, pass it to speed up loading. Otherwise specify ioUnknown.
|
|
You can optionally pass an <A TIOParams> object for the I/O parameters of the file.
|
|
|
|
Returns True if loading was successful, or False on error.
|
|
|
|
<FM>Example<FC>
|
|
// Load the specified image as fast as possible, but bigger than the screen dimensions
|
|
MyIEBitmap.IELoadFromStreamFast( MyStream, ioUnknown, Screen.Width, Screen.Height )
|
|
!!}
|
|
function TIEBitmapHelper.IELoadFromStreamFast(Stream: TStream; FileType: integer;
|
|
iMaxX, iMaxY: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
IOParams: TIOParams = nil
|
|
): Boolean;
|
|
begin
|
|
Result := IELoadFromStreamEx(Stream, FileType, iMaxX, iMaxY, bAutoAdjustOrientation, IOParams, 0);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.LoadFromURL
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadFromURL(const URL : WideString;
|
|
const sProxyAddress : WideString = '';
|
|
const sProxyUser : WideString = '';
|
|
const sProxyPassword : WideString = ''
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Load an image from the internet using the HTTP or FTP protocol.
|
|
|
|
Note: See documentation for <L TImageEnIO.LoadFromURL>TImageEnIO.LoadFromURL</L>
|
|
|
|
<FM>Example<FC>
|
|
MyBitmap.LoadFromURL('http://www.imageen.com/image.jpg');
|
|
!!}
|
|
function TIEBitmapHelper.LoadFromURL(const URL : WideString;
|
|
const sProxyAddress : WideString = '';
|
|
const sProxyUser : WideString = '';
|
|
const sProxyPassword : WideString = ''
|
|
): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
try
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
|
|
IEGlobalSettings().ProxyAddress := sProxyAddress;
|
|
IEGlobalSettings().ProxyUser := sProxyUser;
|
|
IEGlobalSettings().ProxyPassword := sProxyPassword;
|
|
|
|
Result := AImageEnIO.LoadFromURL(URL);
|
|
AImageEnIO.Free;
|
|
except
|
|
result := False;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TIEBitmap.WicRead
|
|
|
|
<FM>Declaration<FC>
|
|
function WicRead(const sFilename: string; iImageIndex: Integer = 0; IOParams: <A TIOParams> = nil): Boolean; overload;
|
|
function WicRead(Stream: TStream; FileType: integer = 0; iImageIndex: Integer = 0; IOParams: <A TIOParams> = nil): Boolean; overload;
|
|
|
|
<FM>Description<FN>
|
|
Use <A TIEWICReader> to load an image into a <A TIEBitmap> from a file or a stream. This will often be more than 100% faster than loading via native Delphi code.
|
|
|
|
The index of an image to load within a multiframe format can also be specified. For streams you must specify the <A TIOFileType> must be specified (one of: ioBMP, ioPNG, ioICO, ioJPEG, ioGIF, ioTIFF, ioHDP).
|
|
|
|
Note: <A TIEWICReader> only supports BMP, PNG, ICO, JPEG, GIF, TIFF and HDP file types.
|
|
|
|
<FM>Example<FC>
|
|
if dlgOpenImage.Execute() then
|
|
begin
|
|
ImageEnView1.IEBitmap.WicRead( dlgOpenImage.FileName );
|
|
ImageEnView1.Update();
|
|
end;
|
|
!!}
|
|
{$IFDEF IEINCLUDEWIC}
|
|
function TIEBitmapHelper.WicRead(const sFilename: string; iImageIndex: Integer = 0; IOParams: TIOParams = nil): Boolean;
|
|
var
|
|
fs: TIEWideFileStream;
|
|
begin
|
|
fs := TIEWideFileStream.create(sFileName, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
Result := WicRead( fs, IEFilenameToInternalFileType( sFilename ), iImageIndex, IOParams );
|
|
finally
|
|
FreeAndNil(fs);
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF IEINCLUDEWIC}
|
|
function TIEBitmapHelper.WicRead(Stream: TStream; FileType: integer = 0; iImageIndex: Integer = 0; IOParams: TIOParams = nil): Boolean;
|
|
var
|
|
wic: TIEWICReader;
|
|
begin
|
|
Result := True;
|
|
try
|
|
wic := TIEWICReader.Create;
|
|
try
|
|
wic.Open(Stream, FileType);
|
|
if ( iImageIndex = 0 ) and ( IOParams <> nil ) and ( IOParams is TIOParams ) then
|
|
iImageIndex := TIOParams( IOParams ).ImageIndex;
|
|
|
|
IEInitialize( 0, 0 );
|
|
wic.GetFrame(iImageIndex, Self, TIOParams( IOParams ), nil );
|
|
if IsEmpty() then
|
|
raise EIEException.create( 'Load error' );
|
|
|
|
finally
|
|
wic.Free; // wic.Close called in Free
|
|
end;
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IESaveToFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IESaveToFile(const sFilename : string; iJPEGQuality : Integer; IOParams: <A TIOParams> = nil): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TIEBitmap to save to any format supported by ImageEn. If you are saving to JPEG you can also specify the <A TIOParams.JPEG_Quality>.
|
|
You can optionally specify an <A TIOParams> object containing the I/O parameters of the file.
|
|
Returns True if saving was successful, or False on error.
|
|
|
|
<FM>Example<FC>
|
|
// Save the image at 90% quality
|
|
MyIEBitmap.IESaveToFile(SavePictureDialog1.FileName, 90)
|
|
!!}
|
|
function TIEBitmapHelper.IESaveToFile(const sFilename: string; iJPEGQuality: Integer; IOParams: TIOParams = nil): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
try
|
|
if IEFilenameInExtensions(sFilename, '*.jpeg;*.jpg;*.jpe;') = False then
|
|
begin
|
|
Result := Write(sFilename, IOParams);
|
|
end
|
|
else
|
|
begin
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
if assigned( IOParams ) then
|
|
AImageEnIO.Params.Assign( IOParams as TIOParams );
|
|
Result := AImageEnIO.SaveToFileEx(sFilename, iJPEGQuality);
|
|
if assigned( IOParams ) then
|
|
TIOParams( IOParams ).Assign( AImageEnIO.Params );
|
|
AImageEnIO.Free;
|
|
end;
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IESaveToStream
|
|
|
|
<FM>Declaration<FC>
|
|
function IESaveToStream(Stream: TStream; FileType: <A TIOFileType>; iJPEGQuality : Integer; IOParams: <A TIOParams> = nil): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Allows a TIEBitmap to save to any format supported by ImageEn. If you are saving to JPEG you can also specify the <A TIOParams.JPEG_Quality>.
|
|
You must specify the <L TIOFileType>file format</L>.
|
|
You can optionally specify an <A TIOParams> object containing the I/O parameters of the file.
|
|
Returns True if saving was successful, or False on error.
|
|
|
|
<FM>Example<FC>
|
|
// Save the image at 90% quality
|
|
MyIEBitmap.IESaveToStream(DestStream, ioJPEG, 90)
|
|
!!}
|
|
function TIEBitmapHelper.IESaveToStream(Stream: TStream; FileType: integer; iJPEGQuality: Integer; IOParams: TIOParams = nil): Boolean;
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
try
|
|
if FileType <> ioJPEG then
|
|
begin
|
|
Result := Write(Stream, FileType, IOParams);
|
|
end
|
|
else
|
|
begin
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
if assigned( IOParams ) then
|
|
AImageEnIO.Params.Assign( IOParams as TIOParams );
|
|
Result := AImageEnIO.SaveToStreamEx(Stream, FileType, iJPEGQuality);
|
|
if assigned( IOParams ) then
|
|
TIOParams( IOParams ).Assign( AImageEnIO.Params );
|
|
AImageEnIO.Free;
|
|
end;
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IELoadAsThumbnail
|
|
|
|
<FM>Declaration<FC>
|
|
function IELoadAsThumbnail(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter : <A TResampleFilter> = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
) : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Loads an image of any format into a TIEBitmap reducing it to the specified size (while maintaining the aspect ratio, thus one of the dimensions is likely to be less than the specified value).
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>iMaxX, iMaxY<FN></C> <C>The maximum size of the new image (as the aspect ratio is maintained, one of the dimensions is likely to be less than the specified value)</C> </R>
|
|
<R> <C><FC>bCanStretch<FN></C> <C>Set to false to avoid images smaller than iMaxX x iMaxY from being made larger</C> </R>
|
|
<R> <C><FC>bAutoAdjustOrientation<FN></C> <C>Sets <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images</C> </R>
|
|
<R> <C><FC>QualityFilter<FN></C> <C>Specify the quality that is used for rescaling the image</C> </R>
|
|
<R> <C><FC>bAddBorder<FN></C> <C>Set to true to add a 1 pixel border to the thumbnail</C> </R>
|
|
<R> <C><FC>cBorderColor<FN></C> <C>The color of the added border</C> </R>
|
|
<R> <C><FC>bAddShadow<FN></C> <C>Add a solid or soft shadow to the image</C> </R>
|
|
<R> <C><FC>iBlurRadius<FN></C> <C>Set to 0 to add a solid shadow or any other value for the width of the <L TImageEnProc.AddSoftShadow>Soft Shadow</L></C> </R>
|
|
<R> <C><FC>iShadowOffset<FN></C> <C>The <L TImageEnProc.AddSoftShadow>offset</L> of the shadow from the image</C> </R>
|
|
<R> <C><FC>cShadowColor<FN></C> <C>The shadow color</C> </R>
|
|
<R> <C><FC>cBGColor<FN></C> <C>The color of the image behind the shadow</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Load an image at the size 160x120
|
|
MyIEBitmap.IELoadAsThumbnail('D:\MyImage.jpeg', 160, 120, False);
|
|
!!}
|
|
function TIEBitmapHelper.IELoadAsThumbnail(const sFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter: TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius: Integer = 4;
|
|
iShadowOffset: Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
): Boolean;
|
|
begin
|
|
try
|
|
Result := IELoadFromFileFast(sFilename, iMaxX, iMaxY, bAutoAdjustOrientation);
|
|
if Result then
|
|
IEConvertToThumbnail(iMaxX, iMaxY, bCanStretch, QualityFilter,
|
|
bAddBorder, cBorderColor,
|
|
bAddShadow, iBlurRadius, iShadowOffset, cShadowColor, cBGColor);
|
|
except
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TIEBitmapHelper.ConvertTo24Bit;
|
|
var
|
|
AImageEnProc: TImageEnProc;
|
|
begin
|
|
AImageEnProc := TImageEnProc.CreateFromBitmap(Self);
|
|
try
|
|
AImageEnProc.ConvertTo24Bit;
|
|
finally
|
|
AImageEnProc.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IEConvertToThumbnail
|
|
|
|
<FM>Declaration<FC>
|
|
|
|
procedure IEConvertToThumbnail(iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
QualityFilter : <A TResampleFilter> = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite);
|
|
|
|
<FM>Description<FN>
|
|
Resize an image in a TIEBitmap to the specified size (while maintaining the aspect ratio, thus one of the dimensions is likely to be less than the specified value).
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>iMaxX, iMaxY<FN></C> <C>The maximum size of the new image (as the aspect ratio is maintained, one of the dimensions is likely to be less than the specified value)</C> </R>
|
|
<R> <C><FC>bCanStretch<FN></C> <C>Set to false to avoid images smaller than iMaxX x iMaxY from being made larger</C> </R>
|
|
<R> <C><FC>bAutoAdjustOrientation<FN></C> <C>Sets <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images</C> </R>
|
|
<R> <C><FC>QualityFilter<FN></C> <C>Specify the quality that is used for rescaling the image</C> </R>
|
|
<R> <C><FC>bAddBorder<FN></C> <C>Set to true to add a 1 pixel border to the thumbnail</C> </R>
|
|
<R> <C><FC>cBorderColor<FN></C> <C>The color of the added border</C> </R>
|
|
<R> <C><FC>bAddShadow<FN></C> <C>Add a solid or soft shadow to the image</C> </R>
|
|
<R> <C><FC>iBlurRadius<FN></C> <C>Set to 0 to add a solid shadow or any other value for the width of the <L TImageEnProc.AddSoftShadow>Soft Shadow</L></C> </R>
|
|
<R> <C><FC>iShadowOffset<FN></C> <C>The <L TImageEnProc.AddSoftShadow>offset</L> of the shadow from the image</C> </R>
|
|
<R> <C><FC>cShadowColor<FN></C> <C>The shadow color</C> </R>
|
|
<R> <C><FC>cBGColor<FN></C> <C>The color of the image behind the shadow</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Resize the IEBitmap to 160x120 with a black border
|
|
MyIEBitmap.IEConvertToThumbnail(160, 120, True, rfFastLinear, True, clBlack);
|
|
!!}
|
|
procedure TIEBitmapHelper.IEConvertToThumbnail(iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
QualityFilter: TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius: Integer = 4;
|
|
iShadowOffset: Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite);
|
|
var
|
|
ASize: tpoint;
|
|
bUseSoftShadow: Boolean;
|
|
begin
|
|
bUseSoftShadow := iBlurRadius > 0;
|
|
|
|
// if a shadow is to be added remove the size of the shadow from the bitmap dimension
|
|
if bAddShadow and bUseSoftShadow then
|
|
begin
|
|
Dec(iMaxX, IESoftShadowSize(iBlurRadius, iShadowOffset, iShadowOffset));
|
|
Dec(iMaxY, IESoftShadowSize(iBlurRadius, iShadowOffset, iShadowOffset));
|
|
end
|
|
else
|
|
if bAddShadow and (bUseSoftShadow = false) then
|
|
begin
|
|
Dec(iMaxX, iShadowOffset);
|
|
Dec(iMaxY, iShadowOffset);
|
|
end;
|
|
|
|
if baddshadow or bAddBorder then
|
|
ConvertTo24Bit;
|
|
|
|
// RESIZE
|
|
ASize := GetImageSizeWithinArea(Width, Height, iMaxX, iMaxY);
|
|
if bCanStretch or (Width > ASize.X) then
|
|
Resample(ASize.X, ASize.Y, QualityFilter, false);
|
|
|
|
// BORDER
|
|
if bAddBorder then
|
|
begin
|
|
Canvas.pen.color := cBorderColor;
|
|
Canvas.Polyline([Point(0, 0),
|
|
Point(Width - 1, 0),
|
|
Point(Width - 1, Height - 1),
|
|
Point(0, Height - 1),
|
|
Point(0, 0)]);
|
|
end;
|
|
|
|
// SHADOW
|
|
if bAddShadow then
|
|
begin
|
|
if bUseSoftShadow then
|
|
IEAddSoftShadow(iBlurRadius, iShadowOffset, cBGColor, _loTopLeft, cShadowColor)
|
|
else
|
|
begin
|
|
// add back the pixels we removed
|
|
width := width + iShadowOffset;
|
|
Height := Height + iShadowOffset;
|
|
|
|
// Draw the shadowm
|
|
Canvas.Brush.color := cShadowColor;
|
|
|
|
// along the right
|
|
Canvas.FillRect(Rect(Width - iShadowOffset, 0, Width, Height));
|
|
|
|
// along the bottom
|
|
Canvas.FillRect(Rect(0, Height - iShadowOffset, Width, Height));
|
|
|
|
// now add the background color
|
|
Canvas.Brush.color := cBGColor;
|
|
|
|
// at the top right
|
|
Canvas.FillRect(Rect(Width - iShadowOffset, 0, Width, iShadowOffset));
|
|
|
|
// at the bottom left
|
|
Canvas.FillRect(Rect(0, Height - iShadowOffset, iShadowOffset, Height));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.IEAddSoftShadow
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEAddSoftShadow(iBlurRadius: integer;
|
|
iShadowOffset : Integer;
|
|
cBGColor: TColor;
|
|
LightOrigin: <A TLightOrigin> = _loTopLeft;
|
|
cShadowColor: TColor = clblack);
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TImageEnProc.AddSoftShadow> to add a soft shadow to an image in a TIEBitmap
|
|
|
|
<FM>Example<FC>
|
|
// Add a soft shadow to the bitmap image
|
|
MyIEBitmap.IEAddSoftShadow(3, 3, clWhite);
|
|
!!}
|
|
procedure TIEBitmapHelper.IEAddSoftShadow(iBlurRadius: integer;
|
|
iShadowOffset: Integer;
|
|
cBGColor: TColor;
|
|
LightOrigin: TLightOrigin = _loTopLeft;
|
|
cShadowColor: TColor = clblack);
|
|
var
|
|
ie: TImageEnView;
|
|
iOffSetX, iOffSetY: integer;
|
|
begin
|
|
ie := TImageEnView.Create(nil);
|
|
try
|
|
ie.Background := cBGColor;
|
|
ie.IEBitmap.assign(Self);
|
|
ie.update;
|
|
iOffSetX := iShadowOffset;
|
|
iOffSetY := iShadowOffset;
|
|
if LightOrigin in [_loTopRight, _loBottomRight] then
|
|
iOffSetX := -iOffSetX;
|
|
if LightOrigin in [_loBottomLeft, _loBottomRight] then
|
|
iOffSetY := -iOffSetY;
|
|
|
|
ie.Proc.AddSoftShadow(iBlurRadius, iOffSetX, iOffSetY, TRUE, cShadowColor);
|
|
ie.RemoveAlphaChannel(True);
|
|
Self.assign(ie.IEBitmap);
|
|
finally
|
|
ie.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEBitmap.PrintImage
|
|
|
|
<FM>Declaration<FC>
|
|
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; SubsampleFilter: <A TResampleFilter> = rfFastLinear);
|
|
|
|
<FM>Description<FN>
|
|
Print the current bitmap 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. Generally the application will pass this as 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>SubsampleFilter<FN></C> <C>The filter that is used to enhance quality if hte image needs to be resampled for printing</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Print the image in the center of the page at the original size
|
|
Printer.BeginDoc;
|
|
ABitmap.PrintImage(Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesNormal, 0, 0, 1);
|
|
Printer.EndDoc;
|
|
|
|
// Print the image in the center of the page stretched to page dimensions (respecting the proportions)
|
|
Printer.BeginDoc;
|
|
ABitmap.PrintImage(Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesFitToPage, 0, 0, 1);
|
|
Printer.EndDoc;
|
|
|
|
|
|
// Print the image as a poster, four pages wide and six pages high
|
|
Printer.BeginDoc;
|
|
ABitmap.PrintImage(Printer.Canvas, 0, 0, 0, 0, ievpCenter, iehpCenter, iesMultiplePages, 4, 6, 1);
|
|
Printer.EndDoc;
|
|
|
|
!!}
|
|
|
|
procedure TIEBitmapHelper.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;
|
|
SubsampleFilter: TResampleFilter = rfFastLinear);
|
|
var
|
|
AImageEnIO: TImageEnIO;
|
|
begin
|
|
AImageEnIO := TImageEnIO.CreateFromBitmap(Self);
|
|
try
|
|
AImageEnIO.PrintingFilterOnSubsampling := SubsampleFilter;
|
|
AImageEnIO.PrintImage(PrtCanvas, MarginLeft, MarginTop, MarginRight, MarginBottom, VerticalPos, HorizontalPos, Size, SpecWidth, SpecHeight, GammaCorrection);
|
|
finally
|
|
AImageEnIO.Free;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
|
|
// FILE FUNCTIONS
|
|
|
|
{!!
|
|
<FS>IEResampleImageFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IEResampleImageFile(const sInFilename, sOutFilename: string;
|
|
iJpegQuality: Integer;
|
|
iMaxX: Integer;
|
|
iMaxY: Integer;
|
|
bCanStretch: Boolean = False;
|
|
QualityFilter: <A TResampleFilter> = rfLanczos3;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
bStripMetaData: Boolean = False
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Loads an image of any format, resizes it and saves it to file (of any format).
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>iJPEGQuality<FN></C> <C>Specify the <A TIOParams.JPEG_Quality> if sOutFilename is a JPEG</C> </R>
|
|
<R> <C><FC>iMaxX, iMaxY<FN></C> <C>The maximum size of the new image (as the aspect ratio is maintained, one of the dimensions is likely to be less than the specified value)</C> </R>
|
|
<R> <C><FC>bCanStretch<FN></C> <C>Set to false to avoid images smaller than iMaxX x iMaxY from being made larger</C> </R>
|
|
<R> <C><FC>QualityFilter<FN></C> <C>Specify the quality that is used for rescaling the image</C> </R>
|
|
<R> <C><FC>bAutoAdjustOrientation<FN></C> <C>Sets <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images</C> </R>
|
|
<R> <C><FC>bStripMetaData<FN></C> <C>If enabled <A TIOParams.ResetInfo> is used to strip meta-data from the image and make it smaller</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Resize MyImage.jpeg to the screen dimensions and save to MyImage_Screen.jpeg
|
|
IEResampleImageFile('D:\MyImage.jpeg', 'D:\MyImage_Screen.jpeg', 90, Screen.Width, Screen.Height, False);
|
|
!!}
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IEResampleImageFile(const sInFilename, sOutFilename: string;
|
|
iJpegQuality: Integer;
|
|
iMaxX: Integer;
|
|
iMaxY: Integer;
|
|
bCanStretch: Boolean = False;
|
|
QualityFilter: TResampleFilter = rfLanczos3;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
bStripMetaData: Boolean = False
|
|
): Boolean;
|
|
var
|
|
ABitmap : TBitmap;
|
|
io: TImageEnIO;
|
|
ASize: TPoint;
|
|
SaveCursor: TCursor;
|
|
begin
|
|
result := true;
|
|
saveCursor := Screen.Cursor;
|
|
try
|
|
Screen.Cursor := crHourGlass;
|
|
ABitmap := TBitmap.create;
|
|
io := TImageEnIO.CreateFromBitmap(ABitmap);
|
|
try
|
|
// Load full size for best quality (and avoid size discrepency if we are auto-rotating)
|
|
if io.LoadFromFileFast(sInFilename, -1, -1, bAutoAdjustOrientation) = False then
|
|
raise EIEException.create('Load error');
|
|
|
|
if bCanStretch or (ABitmap.width > iMaxX) or (ABitmap.height > iMaxY) then
|
|
begin
|
|
// Resize the image
|
|
ASize := GetImageSizeWithinArea(ABitmap.width, ABitmap.height, iMaxX, iMaxY);
|
|
ABitmap.IEResample(ASize.X, ASize.Y, QualityFilter);
|
|
end;
|
|
|
|
if bStripMetaData then
|
|
io.Params.ResetInfo();
|
|
|
|
if not io.SaveToFileEx(sOutFilename, iJpegQuality) then
|
|
raise EIEException.create('Save Error');
|
|
|
|
finally
|
|
io.Free;
|
|
ABitmap.free;
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{!!
|
|
<FS>IEConvertImageFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IEConvertImageFile(const sInFilename, sOutFilename: string;
|
|
iJpegQuality: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Change the format of a file (e.g. from BMP to JPEG). Specify the <A TIOParams.JPEG_Quality> if sOutFilename is a JPEG. Returns False if an error was encountered.
|
|
|
|
<FM>Example<FC>
|
|
// Convert MyImage.jpeg to a BMP file
|
|
IEConvertImageFile('D:\MyImage.jpeg', 'D:\MyImage.bmp', 90);
|
|
!!}
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IEConvertImageFile(const sInFilename, sOutFilename: string;
|
|
iJpegQuality: Integer;
|
|
bAutoAdjustOrientation: Boolean = False
|
|
): Boolean;
|
|
var
|
|
ABitmap: TIEBitmap;
|
|
io: TImageEnIO;
|
|
SaveCursor: TCursor;
|
|
begin
|
|
Result := True;
|
|
if sInFilename = sOutFilename then
|
|
exit;
|
|
|
|
saveCursor := Screen.Cursor;
|
|
try
|
|
Screen.Cursor := crHourGlass;
|
|
ABitmap := TIEBitmap.create;
|
|
io := TImageEnIO.CreateFromBitmap(ABitmap);
|
|
try
|
|
if io.LoadFromFileFast(sInFilename, -1, -1, bAutoAdjustOrientation) = False then
|
|
raise EIEException.create('Load error');
|
|
|
|
if bAutoAdjustOrientation then
|
|
io.params.EXIF_Orientation := _exoCorrectOrientation;
|
|
|
|
if io.SaveToFileEx(sOutFilename, iJpegQuality) = False then
|
|
raise EIEException.create('Save error');
|
|
|
|
finally
|
|
io.Free;
|
|
ABitmap.free;
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{!!
|
|
<FS>IECreateThumbnailFromFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IECreateThumbnailFromFile(const sInFilename: string;
|
|
const sOutFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
iJPEGQuality: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter : <A TResampleFilter> = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Creates a thumbnail from an image.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>iMaxX, iMaxY<FN></C> <C>The maximum size of the new image (as the aspect ratio is maintained, one of the dimensions is likely to be less than the specified value)</C> </R>
|
|
<R> <C><FC>bCanStretch<FN></C> <C>Set to false to avoid images smaller than iMaxX x iMaxY from being made larger</C> </R>
|
|
<R> <C><FC>bAutoAdjustOrientation<FN></C> <C>Sets <A TIOParams.EnableAdjustOrientation> to automatically re-orient JPEG camera images</C> </R>
|
|
<R> <C><FC>QualityFilter<FN></C> <C>Specify the quality that is used for rescaling the image</C> </R>
|
|
<R> <C><FC>bAddBorder<FN></C> <C>Set to true to add a 1 pixel border to the thumbnail</C> </R>
|
|
<R> <C><FC>cBorderColor<FN></C> <C>The color of the added border</C> </R>
|
|
<R> <C><FC>bAddShadow<FN></C> <C>Add a solid or soft shadow to the image</C> </R>
|
|
<R> <C><FC>iBlurRadius<FN></C> <C>Set to 0 to add a solid shadow or any other value for the width of the <L TImageEnProc.AddSoftShadow>Soft Shadow</L></C> </R>
|
|
<R> <C><FC>iShadowOffset<FN></C> <C>The <L TImageEnProc.AddSoftShadow>offset</L> of the shadow from the image</C> </R>
|
|
<R> <C><FC>cShadowColor<FN></C> <C>The shadow color</C> </R>
|
|
<R> <C><FC>cBGColor<FN></C> <C>The color of the image behind the shadow</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Create a thumbnail of MyImage.jpeg at size 160x120 and save to MyImage_Thumb.jpeg
|
|
IECreateThumbnailFromFile('D:\MyImage.jpeg', 'D:\MyImage_Thumb.jpeg', 160, 120, False, 75)
|
|
!!}
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IECreateThumbnailFromFile(const sInFilename: string;
|
|
const sOutFilename: string;
|
|
iMaxX, iMaxY: integer;
|
|
bCanStretch: Boolean;
|
|
iJPEGQuality: integer;
|
|
bAutoAdjustOrientation: Boolean = False;
|
|
QualityFilter : TResampleFilter = rfLanczos3;
|
|
|
|
bAddBorder: Boolean = False;
|
|
cBorderColor: TColor = clBlack;
|
|
|
|
bAddShadow: Boolean = False;
|
|
iBlurRadius : Integer = 4;
|
|
iShadowOffset : Integer = 4;
|
|
cShadowColor: TColor = clBlack;
|
|
cBGColor: TColor = clWhite
|
|
): Boolean;
|
|
var
|
|
ABitmap: TBitmap;
|
|
SaveCursor: TCursor;
|
|
begin
|
|
result := True;
|
|
saveCursor := Screen.Cursor;
|
|
try
|
|
Screen.Cursor := crHourGlass;
|
|
ABitmap := TBitmap.create;
|
|
try
|
|
if ABitmap.IELoadAsThumbnail(sInFilename,
|
|
iMaxX, iMaxY, bCanStretch,
|
|
bAutoAdjustOrientation, QualityFilter,
|
|
bAddBorder, cBorderColor,
|
|
bAddShadow, iBlurRadius, iShadowOffset, cShadowColor, cBGColor) = False then
|
|
raise EIEException.create('Thumb creation error');
|
|
|
|
if not ABitmap.IESaveToFile(sOutFilename, iJpegQuality) then
|
|
raise EIEException.create('Save Error');
|
|
finally
|
|
ABitmap.free;
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
{!!
|
|
<FS>GetImageDetails
|
|
|
|
<FM>Declaration<FC>
|
|
function GetImageDetails(const sFilename: string;
|
|
out iWidth: Integer;
|
|
out iHeight: Integer;
|
|
out iBitsPerPixel: Integer
|
|
): Boolean; overload;
|
|
function GetImageDetails(const sFilename: string): TPoint; overload;
|
|
|
|
|
|
<FM>Description<FN>
|
|
Return the size and color depth of an image. Result is false if a load error occurs.
|
|
The second overload only returns only the width and height (which will be -1,-1 if a load error is encountered).
|
|
|
|
Note: Color depth is TImageEnIO.Params.BitsPerSample * TImageEnIO.Params.SamplesPerPixel.
|
|
|
|
See also: <A BitsPerPixelToStr>
|
|
|
|
<FM>Example<FC>
|
|
if GetImageDetails('D:\MyImage.jpeg', iWidth, iHeight, iBitsPerPixel) then
|
|
begin
|
|
lblWidth.Caption := IntToStr(iWidth);
|
|
lblHeight.Caption := IntToStr(iHeight);
|
|
lblColorDepth.Caption := BitsPerPixelToStr(iBitsPerPixel);
|
|
end;
|
|
!!}
|
|
|
|
function GetImageDetails(const sFilename: string;
|
|
out iWidth: Integer;
|
|
out iHeight: Integer;
|
|
out iBitsPerPixel: Integer
|
|
): Boolean;
|
|
var
|
|
io: TImageEnIO;
|
|
begin
|
|
result := False;
|
|
iWidth := 0;
|
|
iHeight := 0;
|
|
iBitsPerPixel := 0;
|
|
try
|
|
io := TImageEnIO.Create(nil);
|
|
try
|
|
io.ParamsFromFile(sFilename);
|
|
if (io.Aborting = False) and (io.params.Width > 0) then
|
|
begin
|
|
result := True;
|
|
iWidth := io.params.Width;
|
|
iHeight := io.params.Height;
|
|
iBitsPerPixel := io.Params.BitsPerSample * io.Params.SamplesPerPixel;
|
|
end;
|
|
finally
|
|
io.free;
|
|
end;
|
|
except
|
|
// LOAD ERROR
|
|
end;
|
|
end;
|
|
|
|
|
|
function GetImageDetails(const sFilename: string): TPoint;
|
|
var
|
|
iWidth: Integer;
|
|
iHeight: Integer;
|
|
iBitsPerPixel: Integer;
|
|
begin
|
|
Result.x := -1;
|
|
Result.y := -1;
|
|
if GetImageDetails(sFilename, iWidth, iHeight, iBitsPerPixel) then
|
|
begin
|
|
Result.x := iWidth;
|
|
Result.y := iHeight;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>GetExifOrFileCreationDate
|
|
|
|
<FM>Declaration<FC>
|
|
function GetExifOrFileCreationDate(const sFilename: string;
|
|
bReturnCreateDate: Boolean = true
|
|
): TDateTime;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TIOParams.EXIF_DateTimeOriginal> to retrieve the creation date specified in a camera image. If the image does not contain a date, you can optionally return the Windows File Creation Date.
|
|
|
|
<FM>Example<FC>
|
|
// Get digital camera date for for MyImage.jpeg
|
|
aCreateDate := GetExifOrFileCreationDate('D:\MyImage.jpeg', True);
|
|
!!}
|
|
function GetExifOrFileCreationDate(const sFilename: string;
|
|
bReturnCreateDate: Boolean = true {if true then the create date is returned if there is no exif date}
|
|
): TDateTime;
|
|
var
|
|
iFileSizeBytes: Int64;
|
|
dtModifiedDate: TDateTime;
|
|
io: TImageEnIO;
|
|
begin
|
|
result := 0;
|
|
try
|
|
if IEFileIsOfFormat(sFilename, ioJPEG) then
|
|
try
|
|
io := TImageEnIO.Create(nil);
|
|
try
|
|
io.ParamsFromFile(sFilename);
|
|
if (io.Aborting = False) and (io.params.EXIF_HasEXIFData) then
|
|
Result := EXIFDateToDateTime(string(io.params.EXIF_DateTimeOriginal));
|
|
finally
|
|
io.free;
|
|
end;
|
|
except
|
|
// LOAD ERROR
|
|
end;
|
|
|
|
if (Result < 1) and bReturnCreateDate then
|
|
IEGetFileDetails(sFilename, iFileSizeBytes, Result, dtModifiedDate);
|
|
|
|
except
|
|
// GetFileDateTime Error
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>JPEGLosslessRotateFile
|
|
|
|
<FM>Declaration<FC>
|
|
function JPEGLosslessRotateFile(const sInFilename : WideString; const sOutFilename : WideString; iRotateAngle : integer) : Boolean; overload;
|
|
function JPEGLosslessRotateFile(const sFilename : WideString; iRotateAngle : integer) : Boolean; overload;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A JpegLosslessTransform> or <A JpegLosslessTransform2> to losslessly rotate a JPEG image, but allows you to specify a rotation angle that matches the <A TImageEnProc.Rotate> Angle parameter.
|
|
|
|
Note: All comments and markers are copied and the EXIF orientation and thumbnail are updated. All values other than -90, 90, 180, -180, 270 and -270 are ignored
|
|
|
|
<FM>Example<FC>
|
|
// Rotate MyImage.jpeg 90 deg. counter-clockwise and save to MyImage_ROT.jpeg
|
|
JPEGLosslessRotateFile('D:\MyImage.jpeg', 'D:\MyImage_ROT.jpeg', 90);
|
|
!!}
|
|
function JPEGLosslessRotateFile(const sInFilename : WideString; const sOutFilename : WideString; iRotateAngle : integer) : Boolean;
|
|
const
|
|
Update_EXIF_On_Transform = True; // write updated orientation detail and rotate thumbnail
|
|
var
|
|
SaveCursor: TCursor;
|
|
RotType: TIEJpegTransform;
|
|
begin
|
|
// Note: ImageEn Rotation is the opposite of JpegLosslessTransform
|
|
case iRotateAngle of
|
|
270, -90 : RotType := jtRotate90;
|
|
180, -180 : RotType := jtRotate180;
|
|
90, -270 : RotType := jtRotate270;
|
|
else {90}
|
|
raise EIEException.create('Unsupported lossless rotation angle');
|
|
end;
|
|
|
|
saveCursor := Screen.Cursor;
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
if (sOutFilename = '') or SameText(sInFilename, sOutFilename) then
|
|
result := JpegLosslessTransform2(sInFilename, RotType, false, jcCopyAll, rect(0, 0, 0, 0), Update_EXIF_On_Transform)
|
|
else
|
|
result := JpegLosslessTransform(sInFilename, sOutFilename, RotType, false, jcCopyAll, rect(0, 0, 0, 0), Update_EXIF_On_Transform);
|
|
finally
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
end;
|
|
|
|
|
|
function JPEGLosslessRotateFile(const sFilename : WideString; iRotateAngle : integer) : Boolean;
|
|
begin
|
|
Result := JPEGLosslessRotateFile(sFilename, '', iRotateAngle);
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>JPEGLosslessFlipFile
|
|
|
|
<FM>Declaration<FC>
|
|
function JPEGLosslessFlipFile(const sInFilename : WideString; const sOutFilename : WideString; Direction: TFlipDir) : Boolean; overload;
|
|
function JPEGLosslessFlipFile(const sFilename : WideString; Direction: TFlipDir) : Boolean; overload;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A JpegLosslessTransform> or <A JpegLosslessTransform2> to losslessly flip a JPEG image.
|
|
|
|
Note: All comments and markers are copied and the EXIF orientation and thumbnail are updated.
|
|
|
|
<FM>Example<FC>
|
|
// Flip MyImage.jpeg horizontally
|
|
JPEGLosslessRotateFile('D:\MyImage.jpeg', fdHorizontal);
|
|
!!}
|
|
function JPEGLosslessFlipFile(const sInFilename : WideString; const sOutFilename : WideString; Direction: TFlipDir) : Boolean;
|
|
const
|
|
Update_EXIF_On_Transform = True; // write updated orientation detail and rotate thumbnail
|
|
var
|
|
SaveCursor: TCursor;
|
|
RotType: TIEJpegTransform;
|
|
begin
|
|
saveCursor := Screen.Cursor;
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
if Direction = fdVertical then
|
|
RotType := jtVertFlip
|
|
else
|
|
RotType := jtHorizFlip;
|
|
|
|
if (sOutFilename = '') or SameText(sInFilename, sOutFilename) then
|
|
result := JpegLosslessTransform2(sInFilename, RotType, false, jcCopyAll, rect(0, 0, 0, 0), Update_EXIF_On_Transform)
|
|
else
|
|
result := JpegLosslessTransform(sInFilename, sOutFilename, RotType, false, jcCopyAll, rect(0, 0, 0, 0), Update_EXIF_On_Transform);
|
|
finally
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
end;
|
|
|
|
|
|
function JPEGLosslessFlipFile(const sFilename : WideString; Direction: TFlipDir) : Boolean;
|
|
begin
|
|
Result := JPEGLosslessFlipFile(sFilename, '', Direction);
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>IERotateImageFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IERotateImageFile(const sFilename : string;
|
|
iJpegQuality : integer;
|
|
iRotateAngle : integer;
|
|
AntiAliasMode: TIEAntialiasMode = ierFast;
|
|
bCanUseLossless: Boolean = true;
|
|
cBackgroundColor: TColor = clWhite): Boolean; overload;
|
|
function IERotateImageFile(const sInFilename, sOutFilename : string;
|
|
iJpegQuality : integer;
|
|
iRotateAngle : integer;
|
|
AntiAliasMode: TIEAntialiasMode = ierFast;
|
|
bCanUseLossless: Boolean = true;
|
|
cBackgroundColor: TColor = clWhite): Boolean; overload;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TIEBitmap.Rotate> to rotate an image file and resave it (optionally to an alternative file). if bCanUseLossless is specified then <A JpegLosslessTransform2> is used where possible for JPEG files.
|
|
|
|
See also: <A AngleToImageEnRotateAngle>
|
|
|
|
<FM>Example<FC>
|
|
// This will result in a lossless rotation
|
|
IERotateImageFile('D:\MyImage.jpg', 90, ierFast, True);
|
|
|
|
// This will be a lossy rotation
|
|
IERotateImageFile('D:\MyImage.jpg', 45, ierFast, True, clBlack);
|
|
!!}
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IERotateImageFile(const sInFilename, sOutFilename : string;
|
|
iJpegQuality : integer;
|
|
iRotateAngle : integer;
|
|
AntiAliasMode: TIEAntialiasMode = ierFast;
|
|
bCanUseLossless: Boolean = true; // if true then a lossless Flip is used for JPEG images
|
|
cBackgroundColor: TColor = clWhite): Boolean;
|
|
var
|
|
ABitmap: TIEBitmap;
|
|
io: TImageEnIO;
|
|
saveCursor : TCursor;
|
|
begin
|
|
result := True;
|
|
|
|
if iRotateAngle = 0 then
|
|
begin
|
|
// Result will not be valid (exist) if we we are outputting a different file
|
|
Result := SameText(sInFilename, sOutFilename);
|
|
exit;
|
|
end;
|
|
|
|
// can we rotate it losslessly?
|
|
if bCanUseLossless and
|
|
IEFileIsOfFormat(sInFilename, ioJPEG) and
|
|
IEFileIsOfFormat(sOutFilename, ioJPEG) and
|
|
(iRotateAngle mod 90 = 0 {i.e. =90, 180 or 270}) then
|
|
begin
|
|
// rotate the image losslessly
|
|
Result := JPEGLosslessRotateFile(sInFilename, sOutFilename, iRotateAngle);
|
|
exit;
|
|
end;
|
|
|
|
try
|
|
saveCursor := Screen.Cursor;
|
|
ABitmap := TIEBitmap.create;
|
|
io := TImageEnIO.CreateFromBitmap(ABitmap);
|
|
try
|
|
Screen.Cursor := crHourGlass;
|
|
if io.LoadFromFileEx(sInFilename, False) = False then
|
|
raise EIEException.create('Load Error');
|
|
|
|
ABitmap.Rotate(iRotateAngle, AntialiasMode, cBackgroundColor);
|
|
|
|
if io.SaveToFileEx(sOutFilename, iJpegQuality) = False then
|
|
raise EIEException.create('Save Error');
|
|
finally
|
|
io.free;
|
|
ABitmap.free;
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
function IERotateImageFile(const sFilename : string;
|
|
iJpegQuality : integer;
|
|
iRotateAngle : integer;
|
|
AntiAliasMode: TIEAntialiasMode = ierFast;
|
|
bCanUseLossless: Boolean = true; // if true then a lossless Flip is used for JPEG images
|
|
cBackgroundColor: TColor = clWhite): Boolean;
|
|
begin
|
|
Result := IERotateImageFile(sFilename, sFilename, iJpegQuality, iRotateAngle, AntiAliasMode, bCanUseLossless, cBackgroundColor);
|
|
end;
|
|
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>IEFlipImageFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IEFlipImageFile(const sFilename : string;
|
|
iJpegQuality : integer;
|
|
Direction: TFlipDir;
|
|
bCanUseLossless: Boolean = true
|
|
): Boolean; overload;
|
|
function IEFlipImageFile(const sInFilename, sOutFilename : string;
|
|
iJpegQuality : integer;
|
|
Direction: TFlipDir;
|
|
bCanUseLossless: Boolean = true
|
|
): Boolean; overload;
|
|
|
|
<FM>Description<FN>
|
|
Calls <A TIEBitmap.Flip> to Flip an image file and resave it (optionally to an alternative file). if bCanUseLossless is specified then <A JpegLosslessTransform2> is used where possible for JPEG files.
|
|
|
|
<FM>Example<FC>
|
|
// Flip an image horizontally and save to a JPEG
|
|
IEFlipImageFile('D:\Source.bmp', 'D:\MyImage.jpg', 90, fdHorizontal);
|
|
|
|
// Flip an image vertically. This will be lossless as source and destination are JPEG
|
|
IEFlipImageFile('D:\MyJPEG.jpg', 90, fdVertical);
|
|
!!}
|
|
{$IFDEF Delphi2005orNewer}
|
|
function IEFlipImageFile(const sInFilename, sOutFilename : string;
|
|
iJpegQuality : integer;
|
|
Direction: TFlipDir;
|
|
bCanUseLossless: Boolean = true
|
|
): Boolean;
|
|
var
|
|
ABitmap: TIEBitmap;
|
|
io: TImageEnIO;
|
|
saveCursor : TCursor;
|
|
begin
|
|
result := True;
|
|
|
|
// can we Flip it losslessly?
|
|
if bCanUseLossless and
|
|
IEFileIsOfFormat(sInFilename, ioJPEG) and
|
|
IEFileIsOfFormat(sOutFilename, ioJPEG) then
|
|
begin
|
|
// Flip the image losslessly
|
|
Result := JPEGLosslessFlipFile(sInFilename, sOutFilename, Direction);
|
|
exit;
|
|
end;
|
|
|
|
try
|
|
saveCursor := Screen.Cursor;
|
|
ABitmap := TIEBitmap.create;
|
|
io := TImageEnIO.CreateFromBitmap(ABitmap);
|
|
try
|
|
Screen.Cursor := crHourGlass;
|
|
if io.LoadFromFileEx(sInFilename, False) = False then
|
|
raise EIEException.create('Load Error');
|
|
|
|
ABitmap.Flip(Direction);
|
|
|
|
if io.SaveToFileEx(sOutFilename, iJpegQuality) = False then
|
|
raise EIEException.create('Save Error');
|
|
finally
|
|
io.free;
|
|
ABitmap.free;
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
except
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
function IEFlipImageFile(const sFilename : string;
|
|
iJpegQuality : integer;
|
|
Direction: TFlipDir;
|
|
bCanUseLossless: Boolean = true
|
|
): Boolean; overload;
|
|
begin
|
|
Result := IEFlipImageFile(sFilename, sFilename, iJpegQuality, Direction, bCanUseLossless);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
|
|
|
|
{!!
|
|
<FS>IEReadCorrectOrientationOfImageFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IEReadCorrectOrientationOfImageFile(const sFilename : string; bConservativeChecking : Boolean = True) : Integer;
|
|
|
|
<FM>Description<FN>
|
|
Upmarket digital cameras will automatically store the correct orientation of an image when the camera is rotated to take a portrait photo. This function calls <A TIOParams.EXIF_Orientation> to retrieve the desired orientation for a JPEG camera image.
|
|
If bConservativeChecking is true it performs some further checking to ensure the returned value is accurate (e.g. to avoid problems where the photo has already been rotated in another program).
|
|
|
|
<FM>Example<FC>
|
|
iBestOrientation := IEReadCorrectOrientationOfImageFile('D:\MyImage.jpeg', True);
|
|
!!}
|
|
|
|
// checks the EXIF orientation flag of the image to see whether it needs rotating
|
|
{
|
|
For a file returns:
|
|
-1 : Error
|
|
0 : Is not a JPEG
|
|
_exoCorrectOrientation : Doesn't need rotating
|
|
Or: _exoNeeds90RotateCW, _exoNeeds180Rotate, _exoNeeds270RotateCW
|
|
|
|
Here is an explanation of EXIF Rotate Values:
|
|
|
|
1 2 3 4 5 6 7 8
|
|
|
|
888888 888888 88 88 8888888888 88 88 8888888888
|
|
88 88 88 88 88 88 88 88 88 88 88 88
|
|
8888 8888 8888 8888 88 8888888888 8888888888 88
|
|
88 88 88 88
|
|
88 88 888888 888888
|
|
}
|
|
|
|
function IEReadCorrectOrientationOfImageFile(const sFilename : string; bConservativeChecking : Boolean = True) : Integer;
|
|
var
|
|
io: TImageEnIO;
|
|
SaveCursor: TCursor;
|
|
bIsPortraitImage: Boolean;
|
|
bSizeMatchesFields: Boolean;
|
|
begin
|
|
Result := 0;
|
|
|
|
// if it is not a JPEG then it can't be processed
|
|
if IEFileIsOfFormat(sFilename, ioJPEG) = False then
|
|
exit;
|
|
|
|
try
|
|
saveCursor := Screen.Cursor;
|
|
io := TImageEnIO.Create(nil);
|
|
try
|
|
Screen.Cursor := crHourGlass;
|
|
io.ParamsFromFile(sFilename);
|
|
if io.Aborting then
|
|
raise EIEException.create('Load Error');
|
|
|
|
if io.params.EXIF_HasEXIFData then
|
|
begin
|
|
Result := io.params.EXIF_Orientation;
|
|
|
|
// check to see if hte image dimensions match those in the EXIF data
|
|
if (bConservativeChecking) and (Result <> _exoCorrectOrientation) then
|
|
begin
|
|
bIsPortraitImage := io.params.Height > io.params.Width;
|
|
bSizeMatchesFields := (io.params.EXIF_EXIFImageWidth = io.params.width) and (io.params.EXIF_EXIFImageHeight = io.params.Height);
|
|
|
|
if (Result in [_exoNeeds90RotateCW, _exoNeeds270RotateCW]) and bIsPortraitImage then
|
|
// camera photos are already landscape so it looks like this one is already rotated
|
|
result := _exoCorrectOrientation
|
|
else
|
|
if bSizeMatchesFields = False then
|
|
result := _exoCorrectOrientation;
|
|
end;
|
|
|
|
// The following are not used by cameras so just report as correct
|
|
if result in [_exoNeedsHorizontalFlip, _exoNeedsVerticalFlip, _exoNeedsHorzAndVertFlip, _exoNeedsFlipHorzAnd90Rotate] then
|
|
result := _exoCorrectOrientation;
|
|
end;
|
|
finally
|
|
io.free;
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
except
|
|
Result := -1;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>IEAutomaticallyRotateImageFile
|
|
|
|
<FM>Declaration<FC>
|
|
function IEAutomaticallyRotateImageFile(const sFilename : string) : Integer;
|
|
|
|
<FM>Description<FN>
|
|
Upmarket digital cameras will automatically store the correct orientation of an image when the camera is rotated to take a portrait photo. This function calls <A TIOParams.EXIF_Orientation> to retrieve the desired orientation for a JPEG camera image and then calls <A JpegLosslessTransform2> to losslessly rotate it.
|
|
If bConservativeChecking is true it performs some further checking to ensure the orientation data is accurate (e.g. to avoid problems where the photo has already been rotated in another program).
|
|
|
|
<FM>Example<FC>
|
|
// Rotate MyImage.jpeg if it is not correctly oriented
|
|
IEAutomaticallyRotateImageFile('D:\MyImage.jpeg', True);
|
|
!!}
|
|
function IEAutomaticallyRotateImageFile(const sFilename : string; bConservativeChecking : Boolean = True) : Integer;
|
|
var
|
|
SaveCursor: TCursor;
|
|
RotType: TIEJpegTransform;
|
|
begin
|
|
saveCursor := Screen.Cursor;
|
|
try
|
|
Screen.Cursor := crHourGlass;
|
|
Result := IEReadCorrectOrientationOfImageFile(sFilename, bConservativeChecking);
|
|
|
|
// Needs rotation?
|
|
if Result in [_exoNeeds90RotateCW, _exoNeeds180Rotate, _exoNeeds270RotateCW] then
|
|
begin
|
|
// Note: ImageEn Rotation is the opposite of JpegLosslessTransform
|
|
case Result of
|
|
_exoNeeds90RotateCW : RotType := jtRotate90;
|
|
_exoNeeds180Rotate : RotType := jtRotate180;
|
|
_exoNeeds270RotateCW : RotType := jtRotate270;
|
|
else exit; // avoid compiler warning
|
|
end;
|
|
|
|
if JpegLosslessTransform2(sFilename, RotType, false, jcCopyAll, rect(0, 0, 0, 0), True) = False then
|
|
Result := -1;
|
|
end;
|
|
finally
|
|
Screen.Cursor := saveCursor;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>BitsPerPixelToStr
|
|
|
|
<FM>Declaration<FC>
|
|
function BitsPerPixelToStr(iBitsPerPixel: Integer) : string;
|
|
|
|
<FM>Description<FN>
|
|
Provides a suitable textual representation of a Bits per Sample value (i.e. BitsPerSample * SamplesPerPixel). Example outputs: Monochrome, 128 colors, 24 bit color, etc.
|
|
|
|
<FM>Example<FC>
|
|
// Display the color depth of the currently displayed image
|
|
lblColorDepth.Caption := BitsPerPixelToStr(ImageEnView1.IO.Params.BitsPerSample * ImageEnView1.IO.Params.SamplesPerPixel);
|
|
!!}
|
|
function BitsPerPixelToStr(iBitsPerPixel: Integer) : string;
|
|
var
|
|
iColors: Integer;
|
|
begin
|
|
if iBitsPerPixel < 1 then
|
|
result := ''
|
|
else
|
|
if iBitsPerPixel = 1 then
|
|
result := 'Monochrome'
|
|
else
|
|
if iBitsPerPixel <= 8 then
|
|
begin
|
|
iColors := Trunc(Power(2, iBitsPerPixel));
|
|
result := format('%d colors', [iColors])
|
|
end
|
|
else
|
|
if iBitsPerPixel = 12 then
|
|
result := '4,096 colors'
|
|
else
|
|
if (iBitsPerPixel = 15) or
|
|
(iBitsPerPixel = 16) then
|
|
result := '65,536 colors' // Note: Generally true, but there are exceptions
|
|
else {24, 32, etc}
|
|
result := format('%d bit color', [iBitsPerPixel]);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>QualityToZoomFilter
|
|
|
|
<FM>Declaration<FC>
|
|
function QualityToZoomFilter(Quality: <A TIEQuality>): <A TResampleFilter>;
|
|
|
|
<FM>Description<FN>
|
|
Provide quick access to the most common zoom filters
|
|
ieLow : Returns rfNone, no quality filtering is used
|
|
ieMedium : Returns rfFastLinear, a good quality but very fast filter
|
|
ieHigh : Returns rfLanczos3, a very high quality filter
|
|
|
|
<FM>Example<FC>
|
|
// Set Quality filter to ComboBox selection (which contains values: Low, Medium and High)
|
|
frmMain.ImageEnView1.ZoomFilter := QualityToZoomFilter( cmbQuality.ItemIndex );
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnView.ZoomFilter>
|
|
!!}
|
|
function QualityToZoomFilter(Quality: TIEQuality): TResampleFilter;
|
|
const
|
|
High_Quality_Filter = rfLanczos3;
|
|
Medium_Quality_Filter = rfFastLinear;
|
|
Low_Quality_Filter = rfNone;
|
|
begin
|
|
case Quality of
|
|
ieHigh : result := HIGH_QUALITY_FILTER;
|
|
ieMedium : result := MEDIUM_QUALITY_FILTER;
|
|
else {ieLow} result := LOW_QUALITY_FILTER;
|
|
end;
|
|
end;
|
|
|
|
|
|
type
|
|
HourglassHandler = class(TInterfacedObject)
|
|
private
|
|
fOldCursor: TCursor;
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
{ HourglassHandler }
|
|
|
|
constructor HourglassHandler.Create;
|
|
begin
|
|
fOldCursor := Screen.Cursor;
|
|
Screen.Cursor := crHourGlass;
|
|
end;
|
|
|
|
destructor HourglassHandler.Destroy;
|
|
begin
|
|
Screen.Cursor := fOldCursor;
|
|
inherited;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>ShowTempHourglass
|
|
|
|
<FM>Declaration<FC>
|
|
function ShowTempHourglass: IUnknown;
|
|
|
|
<FM>Description<FN>
|
|
Change the cursor to an hourglass during the current procedure (i.e. will revert to the previous cursor once we go out of scope)
|
|
|
|
<FM>Example<FC>
|
|
Load an image when a button is clicked. Show hourglass during loading
|
|
procedure TMain.Button1Click(Sender: TObject);
|
|
begin
|
|
ShowTempHourglass;
|
|
ImageEnView1.IO.LoadFromFile('C:\MyImage.jpg');
|
|
end;
|
|
!!}
|
|
function ShowTempHourglass: IUnknown;
|
|
begin
|
|
result := HourglassHandler.Create
|
|
end;
|
|
|
|
{!!
|
|
<FS>iexHelperFunctions
|
|
|
|
<FN>iexHelperFunctions.pas provides helper functions for <A TImageEnIO>, TBitmap and <A TIEBitmap>, plus a variety of file functions. These methods provide quicker access to some ImageEn functionality for common tasks.
|
|
|
|
Simply add iexHelperFunctions to your uses clause to access the new methods
|
|
|
|
<FM>IMAGEENIO HELPER FUNCTIONS<FN>
|
|
Adds shortcut methods to the <A TImageEnIO> class:
|
|
<TABLE2>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.CreatePDFFromFileList></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.CreatePSFromFileList></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromBlob></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromBlobFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileAutoEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileJPEGFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromFileRawFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.LoadFromStreamJPEGFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.Reload></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToBlob></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToFileEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnIO.SaveToStreamEx></C> </R>
|
|
</TABLE>
|
|
|
|
<FM>BITMAP HELPER FUNCTIONS<FN>
|
|
Adds more functionality to the TBitmap class:
|
|
<TABLE2>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IEInitialize></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IELoadFromFile></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IELoadFromFileFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IELoadFromStream></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IELoadFromStreamFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.LoadFromURL></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IESaveToFile></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IESaveToStream></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IERotate></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IEFlip></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IEResample></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IELoadAsThumbnail></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IEConvertToThumbnail></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.IEAddSoftShadow></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TBitmap.PrintImage></C> </R>
|
|
</TABLE>
|
|
|
|
<FM>IEBITMAP HELPER FUNCTIONS<FN>
|
|
Adds more functionality to the <A TIEBitmap> class:
|
|
<TABLE2>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IEInitialize></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IELoadFromFile></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IELoadFromFileFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IELoadFromStream></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IELoadFromStreamFast></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.LoadFromURL></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IESaveToFile></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IESaveToStream></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IELoadAsThumbnail></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IEConvertToThumbnail></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.IEAddSoftShadow> </C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.PrintImage></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TIEBitmap.WicRead></C> </R>
|
|
</TABLE>
|
|
|
|
<FM>FILE FUNCTIONS<FN>
|
|
Perform image manipulation functions without direct use of ImageEn components:
|
|
<TABLE2>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IEResampleImageFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IEConvertImageFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IECreateThumbnailFromFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A GetImageDetails></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A GetExifOrFileCreationDate></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A JPEGLosslessRotateFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A JPEGLosslessFlipFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IERotateImageFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IEFlipImageFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IEReadCorrectOrientationOfImageFile></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IEAutomaticallyRotateImageFile></C> </R>
|
|
</TABLE>
|
|
|
|
<FM>CANVAS FUNCTIONS<FN>
|
|
Functions to output custom shapes and wallpaper to a TCanvas or TBitmap
|
|
<TABLE2>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IEDrawShape></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A IECreateShapeRegion></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A CreateWallpaperBitmap></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A TileBitmapOntoCanvas></C> </R>
|
|
</TABLE>
|
|
|
|
<FM>OTHER FUNCTIONS<FN>
|
|
Other functions that may be useful with ImageEn:
|
|
<TABLE2>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A BitsPerPixelToStr></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A QualityToZoomFilter></C> </R>
|
|
<R> <C_IMG_GLOBMETHOD> <C><A ShowTempHourglass></C> </R>
|
|
</TABLE>
|
|
|
|
* Note: Delphi/C++ 2005 or newer is required to use helper classes
|
|
|
|
!!}
|
|
|
|
end.
|
|
|