3063 lines
102 KiB
Plaintext
3063 lines
102 KiB
Plaintext
(* ImageEn Build 7.0.0.06.2637 @ 7-4-17 14:58:42.679 *)
|
||
(*
|
||
Copyright (c) 1998-2017 by Carlotta Calandra. All rights reserved.
|
||
Copyright (c) 2011-2017 by Xequte Software.
|
||
|
||
This software comes without express or implied warranty.
|
||
In no case shall the author be liable for any damage or unwanted behavior of any
|
||
computer hardware and/or software.
|
||
|
||
Author grants you the right to include the component
|
||
in your application, whether COMMERCIAL, SHAREWARE, or FREEWARE.
|
||
|
||
ImageEn, IEvolution and ImageEn ActiveX may not be included in any
|
||
commercial, shareware or freeware libraries or components.
|
||
|
||
www.ImageEn.com
|
||
*)
|
||
|
||
(*
|
||
File version 1002
|
||
*)
|
||
|
||
unit iexDBBitmaps;
|
||
|
||
{$R-}
|
||
{$Q-}
|
||
|
||
{$I ie.inc}
|
||
|
||
|
||
{$IFDEF IEINCLUDEDB}
|
||
|
||
|
||
interface
|
||
|
||
uses
|
||
Windows, Messages, classes, Graphics, Db, ImageEnView, ImageEnio, hyiedefs, iexBitmaps, hyieutils, ExtCtrls;
|
||
|
||
type
|
||
|
||
TIEDataLink = class(TDataLink)
|
||
private
|
||
fModified: Boolean;
|
||
fOnDataChanged: TNotifyEvent;
|
||
fOnEditingChanged: TNotifyEvent;
|
||
fOnDataUpdated: TNotifyEvent;
|
||
fOnActiveChanged: TNotifyEvent;
|
||
fOnRecordChanged: TFieldNotifyEvent;
|
||
fOnScrolled: TNotifyEvent;
|
||
fInternalScroll: Boolean;
|
||
protected
|
||
procedure ActiveChanged; override;
|
||
procedure DataSetChanged; override;
|
||
procedure DataSetScrolled(Distance: Integer); override;
|
||
procedure EditingChanged; override;
|
||
procedure RecordChanged(Field: TField); override;
|
||
procedure UpdateData; override;
|
||
public
|
||
constructor Create();
|
||
destructor Destroy; override;
|
||
procedure Modified;
|
||
procedure MoveToRecord(idx: Integer; bSilent: Boolean = True);
|
||
|
||
property OnDataChanged: TNotifyEvent read fOnDataChanged write fOnDataChanged;
|
||
property OnEditingChanged: TNotifyEvent read fOnEditingChanged write fOnEditingChanged;
|
||
property OnDataUpdated: TNotifyEvent read fOnDataUpdated write fOnDataUpdated;
|
||
property OnActiveChanged: TNotifyEvent read fOnActiveChanged write fOnActiveChanged;
|
||
property OnRecordChanged: TFieldNotifyEvent read fOnRecordChanged write fOnRecordChanged;
|
||
property OnScrolled: TNotifyEvent read fOnScrolled write fOnScrolled;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEImageStorageMode
|
||
|
||
<FM>Declaration<FC>
|
||
type TIEImageStorageMode = (isEmbeddedBlob, isLinkedFile);
|
||
|
||
<FM>Description<FN>
|
||
The method that images are stored or referenced by the database.
|
||
|
||
<TABLE>
|
||
<R> <H>Value</H> <H>Description</H> </R>
|
||
<R> <C>isEmbeddedBlob</C> <C>The image is embedded within a blob field</C> </R>
|
||
<R> <C>isLinkedFile</C> <C>A string field points to the filename of a local file</C> </R>
|
||
</TABLE>
|
||
!!}
|
||
TIEImageStorageMode = (isEmbeddedBlob, isLinkedFile);
|
||
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap
|
||
|
||
<FM>Description<FN>
|
||
TIEDBBitmap is a descendant of <A TIEBitmap>, but it links to a datasource to provide access to images stored in a database table.
|
||
TIEDBBitmap supports both images stored within the database as a blob (by setting <A TIEDBBitmap.ImageBlobField>) or images stored locally and referenced by a filename field (by setting only <A TIEDBBitmap.FilenameField>). You will need to set <A TIEDBBitmap.DataSource>.
|
||
|
||
There are two ways you can use TIEDBBitmap:
|
||
|
||
<FB><3E> Connected to a TTable<FN>
|
||
|
||
By setting the <A TIEDBBitmap.DataSource> and <A TIEDBBitmap.ImageBlobField> or <A TIEDBBitmap.FilenameField>, the TIEDBBitmap will be connected to the database and the content will update with the movement and changes on the table, either automatically (<A TIEDBBitmap.AutoLoad> is true) or manually (by calling <A TIEDBBitmap.LoadImage>). This is generally used to create a data-aware <A TImageEnView> by setting the <L TImageEnView.SetExternalBitmap>external bitmap</L> to a TIEDBBitmap.
|
||
<FC>
|
||
// Create DB Aware TImageEnView
|
||
procedure TMainForm.FormCreate(Sender: TObject);
|
||
begin
|
||
... Open a database table ...
|
||
|
||
fDBBitmap := TIEDBBitmap.create( DataSource1, 'Image', 'Name' );
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
end;
|
||
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBBitmap );
|
||
end;
|
||
|
||
|
||
<FB><3E> As an adhoc Bitmap with database access<FN>
|
||
|
||
Use TIEDBBitmap to retrieve images embedded in a database blob field using the data-aware overload of <A TIEDBBitmap.Read>.
|
||
<FC>
|
||
// Extract an image from a database and save it
|
||
MyBMP := TIEDBBitmap.Create();
|
||
MyBMP.Read( MyTableImageBlob );
|
||
MyBmp.Write( 'D:\MyBlobImage.jpeg' );
|
||
MyBmp.Free;
|
||
|
||
|
||
<FM>Methods and Properties<FN>
|
||
<FI>General<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.AdjustmentsMask></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Allocate></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.BitAlignment></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.BitCount></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Clear></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Contrast></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBBitmap.Create> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CreateDIB></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CreateROIBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CreateROICanvas></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Destroy></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.FreeImage></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.FixChannelOffset></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.FixContrast></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Height></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.IsEmpty></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.IsVirtual></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Location></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.MemoryAllocator></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.MinFileSize></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Origin></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.PixelFormat></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Resize></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.VclBitmap></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Width></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Database<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.DataSource> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.AutoLoad> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.FilenameField> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.ImageBlobField> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.ImageFormat> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.ImagePath> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.ImageStorageMode> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.JpegQuality> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBBitmap.UseMemoryStream> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBBitmap.Read> (Load from blob/file/stream) <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBBitmap.Write> (Save to blob/file/stream) <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBBitmap.LoadImage> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBBitmap.UpdateDatabaseImage> <IMG help_images\Star.gif></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Assignment between Objects<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Assign></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.AssignImage></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyAndConvertFormat></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyFromDIB></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyFromMemory></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyFromTBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyFromTDibBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyFromTIEMask></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyRectTo></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyToTBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyToTDibBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyToTIEMask></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyWithMask1></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyWithMask2></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.DrawToTIEBitmap></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.EncapsulatedFromMemory></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.EncapsulatedFromTBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.EncapsulateMemory></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.EncapsulateTBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.MergeFromTDibBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RenderToTBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RenderToTBitmapEx></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RenderToTIEBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RenderToTIEBitmapEx></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RestoreState></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.SaveState></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.StretchRectTo></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.SwitchTo></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.UpdateFromTBitmap></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>File I/O<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBaseBitmap.Access> (inherited from <A TIEBaseBitmap>)</C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CalcRAWSize></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.GetHash></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.LoadFromResource></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.LoadRAWFromBufferOrStream></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.ParamsEnabled></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Params></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.SaveRAWToBufferOrStream></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Canvas Access<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.IECanvas></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Canvas></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.DrawToCanvas></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Fill></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.FillRect></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.MoveRegion></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RenderToCanvas></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Alpha Channel (Transparency)<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Alpha></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.AlphaChannel></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.AlphaChannelOpt></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.CanvasCurrentAlpha></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.DrawToCanvasWithAlpha></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.FeatherAlphaEdges></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.HasAlphaChannel></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.IsAlpha></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.MergeAlphaRectTo></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.MergeWithAlpha></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RemoveAlphaChannel></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.RenderToCanvasWithAlpha></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.SynchronizeRGBA></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Pixel Access<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.FreeRow></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.GetRow></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.GetSegment></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Memory></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ie16g></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ie1g></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ie24RGB></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ie32f></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ie32RGB></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ie48RGB></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ie8></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ieCIELab></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels_ieCMYK></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Pixels></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.PPixels_ie24RGB></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.PPixels_ie32RGB></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.PPixels_ie48RGB></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Rowlen></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.ScanLine></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.TBitmapScanlines></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.VirtualBitmapProvider></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Palette and Color<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBaseBitmap.Palette> (inherited from <A TIEBaseBitmap>)</C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBaseBitmap.PaletteLength> (inherited from <A TIEBaseBitmap>)</C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBaseBitmap.PaletteUsed> (inherited from <A TIEBaseBitmap>)</C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.AutoCalcBWValues></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.BlackValue></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.ChannelCount></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.ChannelOffset></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.ColorProfile></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.CopyPaletteTo></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.DefaultDitherMethod></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.Full></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.IsAllBlack></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.IsGrayScale></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.StretchValues></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.SyncFull></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEBitmap.WhiteValue></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Image Manipulation<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Flip></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Resample></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.Rotate></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>IEVision related<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.GetIEVisionImage></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEBitmap.AssignIEVisionImage></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Events<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_EVENT> <C><A TIEBitmap.OnRenderVirtualPixel></C> </R>
|
||
</TABLE>
|
||
|
||
<IMG help_images\Star.gif> Unique functionality to TIEDBBitmap
|
||
!!}
|
||
|
||
TIEDBBitmap = class(TIEBitmap)
|
||
private
|
||
fDataLink: TIEDataLink;
|
||
fImageFormat: TIOFileType;
|
||
fLastImageFormat: TIOFileType;
|
||
fImagePath: string;
|
||
fUseMemoryStream: boolean;
|
||
fAutoLoad : boolean;
|
||
fFilenameFieldName: string;
|
||
fFilenameField: TField;
|
||
fImageBlobFieldName: string;
|
||
fImageBlobField: TField;
|
||
fJPEGQuality: Integer;
|
||
fImageLoaded: Boolean;
|
||
fAutoLoadTimer: TTimer;
|
||
|
||
function GetDataSource: TDataSource;
|
||
procedure SetDataSource(Value: TDataSource);
|
||
procedure SetImagePath(const v: string);
|
||
procedure ActiveChanged(Sender: TObject);
|
||
procedure SetFilenameFieldName(const Value: string);
|
||
procedure SetImageBlobFieldName(const Value: string);
|
||
procedure SetAutoLoad(Value: Boolean);
|
||
function GetImageStorageMode: TIEImageStorageMode;
|
||
procedure DatabaseEvent(Sender: TObject);
|
||
procedure UpdateImage(bDelayed: Boolean);
|
||
procedure AutoLoadTimerEvent(Sender: TObject);
|
||
|
||
protected
|
||
public
|
||
constructor Create(); override;
|
||
constructor Create(aDataSource: TDataSource; const sImageBlobField, sFilenameField: string); overload;
|
||
destructor Destroy; override;
|
||
|
||
function LoadImage(): boolean;
|
||
procedure UpdateDatabaseImage();
|
||
|
||
function Read(): boolean; overload;
|
||
function Read(aBlobField: TBlobField; FileType: TIOFileType = 0; IOParams: TIOParams = nil): boolean; overload;
|
||
function Write(): boolean; overload;
|
||
function Write(aBlobField: TBlobField; FileType: TIOFileType; IOParams: TIOParams = nil): boolean; overload;
|
||
|
||
property ImagePath: string read fImagePath write SetImagePath;
|
||
|
||
property DataSource: TDataSource read GetDataSource write SetDataSource;
|
||
|
||
property ImageStorageMode: TIEImageStorageMode read GetImageStorageMode;
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.ImageFormat
|
||
|
||
<FM>Declaration<FC>
|
||
property ImageFormat: <A TIOFileType>;
|
||
|
||
<FM>Description<FN>
|
||
Specifies the format that images are read and written to the database.
|
||
If images are stored in a database blob field (<A TIEDBBitmap.ImageStorageMode> = <FC>isEmbeddedBlob<FN>) <FC>ImageFormat<FN> specifies their image type. The format will be used when loading, and images will be saved to the database in this format.
|
||
For images referenced locally (<A TIEDBBitmap.ImageStorageMode> = <FC>isLinkedFile<FN>) the <FC>ImageFormat<FN> is used only when saving image changes.
|
||
If <FC>ImageFormat<FN> is <FC>ioUnknown<FN> then the file content is analyzed to determine the format when loading, and the last detected file type is used when saving.
|
||
|
||
Default: ioUnknown
|
||
|
||
!!}
|
||
property ImageFormat: TIOFileType read fImageFormat write fImageFormat default ioUnknown;
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.JpegQuality
|
||
|
||
<FM>Declaration<FC>
|
||
property JpegQuality: integer;
|
||
|
||
<FM>Description<FN>
|
||
If database images are <L TIEDBBitmap.ImageFormat>saved to JPEG</L> then <FC>JpegQuality<FN> specifies the save quality (Range: 1 to 100. Higher is better quality, but larger).
|
||
This property updates <A TIEBitmap.Params>.<A TIOParams.JPEG_Quality>.
|
||
|
||
Default: 80
|
||
|
||
!!}
|
||
property JpegQuality: integer read fJpegQuality write fJpegQuality default 80;
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.UseMemoryStream
|
||
|
||
<FM>Declaration<FC>
|
||
property UseMemoryStream: boolean
|
||
|
||
<FM>Description<FN>
|
||
If True, TIEDBBitmap will use a temporary memory stream to retrieve data from blob stream. Otherwise CreateBlobStream is used.
|
||
|
||
Default: True
|
||
!!}
|
||
property UseMemoryStream: boolean read fUseMemoryStream write fUseMemoryStream default true;
|
||
|
||
property AutoLoad: boolean read fAutoLoad write SetAutoLoad default False;
|
||
|
||
property FilenameField: string read fFilenameFieldName write SetFilenameFieldName;
|
||
property ImageBlobField: string read fImageBlobFieldName write SetImageBlobFieldName;
|
||
|
||
end;
|
||
|
||
|
||
|
||
{$IFDEF IEINCLUDEMULTIVIEW}
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap
|
||
|
||
<FM>Description<FN>
|
||
TIEDBMultiBitmap is a descendant of <A TIECustomMultiBitmap>, but unlike <A TIEMultiBitmap> it links to a datasource to provide access to images stored in a database table.
|
||
Generally a TIEDBMultiBitmap is <L TImageEnMView.SetExternalMBitmap>attached</L> to a <A TImageEnMView> to make it DB aware.
|
||
|
||
TIEDBMultiBitmap supports both images stored within the database as a blob (by setting <A TIEDBMultiBitmap.ImageBlobField>) or images stored locally and referenced by a filename field (by setting only <A TIEDBMultiBitmap.FilenameField>). You will also need to set <A TIEDBMultiBitmap.DataSource>.
|
||
|
||
<FM>Demo<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_DEMO> <C>Demos\Database\DBMultiBitmap\DBMultiBitmap.dpr </C> </R>
|
||
</TABLE>
|
||
|
||
<FM>Example<FC>
|
||
// Create DB Aware TImageEnMView
|
||
procedure TMainForm.FormCreate(Sender: TObject);
|
||
begin
|
||
... Open a database table ...
|
||
|
||
fDBMBitmap := TIEDBMultiBitmap.create( DataSource1, 'Image', 'Name' );
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
end;
|
||
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBMBitmap );
|
||
end;
|
||
|
||
<FM>Methods and Properties<FN>
|
||
<FI>General<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.Create> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.Destroy></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.Count></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIECustomMultiBitmap.LockUpdate></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIECustomMultiBitmap.LockUpdateCount></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIECustomMultiBitmap.UnLockUpdate></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Database<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.DataSource> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.FollowDBCursor> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.FilenameField> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.FilenameFieldIsUnique> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.ImageBlobField> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.ImageFormat> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.ImagePath> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.ImageStorageMode> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.MaxDisplayRecords> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.Update> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.UseMemoryStream> <IMG help_images\Star.gif></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Database Editing<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.AppendImage> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.DefaultFilename> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.DeleteImage> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.InsertImage> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.JpegQuality> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEDBMultiBitmap.ReadOnly> <IMG help_images\Star.gif></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Image Access<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEMultiBitmap.CopyToIEBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEMultiBitmap.GetBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.GetTIEBitmap></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.ReleaseBitmap> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.SetImage> <IMG help_images\Star.gif></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Image Information<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageBitCount></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageFilename></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageHeight></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageTag></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageUserPointer></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageWidth></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Input/Output<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageCacheSize></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ImageCacheUseDisk></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEMultiBitmap.GetImageToFile></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEMultiBitmap.GetImageToStream></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Input/Output Parameters (Meta-Data)<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.ParamsEnabled></C> </R>
|
||
<R> <C_IMG_PROPERTY> <C><A TIEMultiBitmap.Params></C> </R>
|
||
</TABLE>
|
||
|
||
<FI>Image Manipulation<FN>
|
||
<TABLE2>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.Flip> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.Resample> <IMG help_images\Star.gif></C> </R>
|
||
<R> <C_IMG_METHOD> <C><A TIEDBMultiBitmap.Rotate> <IMG help_images\Star.gif></C> </R>
|
||
</TABLE>
|
||
|
||
<IMG help_images\Star.gif> Unique functionality to TIEDBMultiBitmap
|
||
!!}
|
||
|
||
TIEDBMultiBitmap = class(TIECustomMultiBitmap)
|
||
procedure UpdateActive;
|
||
private
|
||
fDataLink: TIEDataLink;
|
||
fMaxDisplayRecords: Integer;
|
||
fImageFormat: TIOFileType;
|
||
fLastImageFormat: TIOFileType;
|
||
fImagePath: string;
|
||
fUseMemoryStream: boolean;
|
||
fFollowDBCursor : boolean;
|
||
fFilenameFieldName: string;
|
||
fFilenameField: TField;
|
||
fImageBlobFieldName: string;
|
||
fImageBlobField: TField;
|
||
fBlobBitmap: TIEBitmap;
|
||
fDefaultFilename: string;
|
||
fJPEGQuality: Integer;
|
||
fUpdatePendingIsFull : Boolean; // True if the pending update should also clear the cache (See TIECustomMultiBitmap.fUpdatePending)
|
||
fFilenameFieldIsUnique: Boolean;
|
||
|
||
function GetDataSource: TDataSource;
|
||
function GetReadOnly: Boolean;
|
||
procedure SetDataSource(Value: TDataSource);
|
||
procedure SetReadOnly(Value: Boolean);
|
||
procedure SetImagePath(const v: string);
|
||
procedure ActiveChanged(Sender: TObject);
|
||
procedure DataChanged(Sender: TObject);
|
||
procedure DataUpdated(Sender: TObject);
|
||
procedure Scrolled(Sender: TObject);
|
||
procedure RecordChanged(Field: TField);
|
||
procedure SetFilenameFieldName(const Value: string);
|
||
procedure SetImageBlobFieldName(const Value: string);
|
||
procedure SetFollowDBCursor(Value: Boolean);
|
||
procedure SetMaxDisplayRecords(Value: Integer);
|
||
procedure InsertOrAppend(idx: integer);
|
||
function GetImageStorageMode: TIEImageStorageMode;
|
||
|
||
protected
|
||
procedure CheckAllocated(idx: integer); override;
|
||
|
||
public
|
||
constructor Create(); override;
|
||
constructor Create(aDataSource: TDataSource; const sImageBlobField, sFilenameField: string; bFilenameFieldIsUnique: Boolean = False); overload;
|
||
destructor Destroy; override;
|
||
|
||
|
||
function AppendImage(): integer; overload; override;
|
||
function AppendImage(Stream: TStream): integer; overload; override;
|
||
function AppendImage(Bitmap: TIEBitmap): integer; overload; override;
|
||
function AppendImage(MBitmap: TIECustomMultiBitmap): integer; overload; override;
|
||
function AppendImage(Bitmap : TBitmap): integer; overload; override;
|
||
function AppendImage(Width, Height: Integer; PixelFormat: TIEPixelFormat = ie24RGB): Integer; overload; override;
|
||
function AppendImage(const FileName: String): integer; overload; override;
|
||
|
||
procedure InsertImage(Idx : integer); overload; override;
|
||
procedure InsertImage(Idx : integer; Stream : TStream); overload; override;
|
||
procedure InsertImage(Idx : integer; Bitmap : TIEBitmap); overload; override;
|
||
procedure InsertImage(Idx : integer; MBitmap : TIECustomMultiBitmap); overload; override;
|
||
procedure InsertImage(Idx : integer; Bitmap : TBitmap); overload; override;
|
||
procedure InsertImage(Idx : integer; Width, Height : integer; PixelFormat : TIEPixelFormat = ie24RGB); overload; override;
|
||
procedure InsertImage(Idx : integer; const FileName : string); overload; override;
|
||
|
||
// Internal use only
|
||
procedure SetActiveImage(idx: integer); override;
|
||
|
||
property ImagePath: string read fImagePath write SetImagePath;
|
||
|
||
|
||
procedure Update; override;
|
||
procedure UpdateEx(bFullUpdate: Boolean = true); override;
|
||
|
||
property DataSource: TDataSource read GetDataSource write SetDataSource;
|
||
property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
|
||
|
||
property ImageStorageMode: TIEImageStorageMode read GetImageStorageMode;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.FilenameFieldIsUnique
|
||
|
||
<FM>Declaration<FC>
|
||
property FilenameFieldIsUnique: Boolean;
|
||
|
||
<FM>Description<FN>
|
||
If the specified filename field, <A TIEDBMultiBitmap.FilenameField>, is guaranteed to be unique (i.e. each record has a different name specified) then set <FC>FilenameFieldIsUnique<FN> to true. This will improve performance and caching.
|
||
Also, if you are using <A TIEDBMultiBitmap.ImageStorageMode> = <FC>isLinkedFile<FN> and your filename field contains a full path (<A TIEDBMultiBitmap.ImagePath> = '') you can set this to true.
|
||
|
||
Default: False
|
||
|
||
!!}
|
||
property FilenameFieldIsUnique: Boolean read fFilenameFieldIsUnique write fFilenameFieldIsUnique;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.DefaultFilename
|
||
|
||
<FM>Declaration<FC>
|
||
property DefaultFilename: string;
|
||
|
||
<FM>Description<FN>
|
||
Specifies a filename to use when an image needs to be saved (if the file already exists a numbered filename will be generated).
|
||
If images are stored as local files (<A TIEDBMultiBitmap.ImageStorageMode> = <FC>isLinkedFile<FN>) then when <L TIEDBMultiBitmap.AppendImage>appending</L> bitmaps a file will be saved and then referenced by the database.
|
||
For images referenced locally using only <A TIEDBMultiBitmap.FilenameField> the is useful only if images do not have a file extension.
|
||
If you have set an <A TIEDBMultiBitmap.ImagePath> then <FC>DefaultFilename<FN> need only be a name, such as "Image". Otherwise a full path must be set, e.g. "C:\My Image Folder\Image"
|
||
|
||
Default: 'Image'
|
||
|
||
!!}
|
||
property DefaultFilename: string read fDefaultFilename write fDefaultFilename;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.ImageFormat
|
||
|
||
<FM>Declaration<FC>
|
||
property ImageFormat: <A TIOFileType>;
|
||
|
||
<FM>Description<FN>
|
||
Specifies the format that images are read and written to the database.
|
||
If images are stored in a database blob field (<A TIEDBMultiBitmap.ImageStorageMode> = <FC>isEmbeddedBlob<FN>) <FC>ImageFormat<FN> specifies their image type. The format will be used when loading, and images will be saved to the database in this format.
|
||
For images referenced locally (<A TIEDBMultiBitmap.ImageStorageMode> = <FC>isLinkedFile<FN>) the <FC>ImageFormat<FN> is used only when saving image changes.
|
||
If <FC>ImageFormat<FN> is <FC>ioUnknown<FN> (Default) then the file content is analyzed to determine the format when loading, and the last detected file type is used when saving.
|
||
|
||
Default: ioUnknown
|
||
|
||
!!}
|
||
property ImageFormat: TIOFileType read fImageFormat write fImageFormat default ioUnknown;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.JpegQuality
|
||
|
||
<FM>Declaration<FC>
|
||
property JpegQuality: integer;
|
||
|
||
<FM>Description<FN>
|
||
If database images are <L TIEDBMultiBitmap.ImageFormat>saved to JPEG</L> then <FC>JpegQuality<FN> specifies the save quality (Range: 1 to 100. Higher is better quality, but larger).
|
||
This property updates <A TIEMultiBitmap.Params>.<A TIOParams.JPEG_Quality>.
|
||
|
||
Default: 80
|
||
|
||
!!}
|
||
property JpegQuality: integer read fJpegQuality write fJpegQuality default 80;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.UseMemoryStream
|
||
|
||
<FM>Declaration<FC>
|
||
property UseMemoryStream: boolean
|
||
|
||
<FM>Description<FN>
|
||
If True, TIEDBMultiBitmap will use a temporary memory stream to retrieve data from blob stream. Otherwise CreateBlobStream is used.
|
||
|
||
Default: True
|
||
!!}
|
||
property UseMemoryStream: boolean read fUseMemoryStream write fUseMemoryStream default true;
|
||
|
||
property FollowDBCursor: boolean read fFollowDBCursor write SetFollowDBCursor default False;
|
||
|
||
property MaxDisplayRecords: Integer read fMaxDisplayRecords write SetMaxDisplayRecords default 10000;
|
||
|
||
property FilenameField: string read fFilenameFieldName write SetFilenameFieldName;
|
||
property ImageBlobField: string read fImageBlobFieldName write SetImageBlobFieldName;
|
||
|
||
procedure DeleteImage(idx: integer); override;
|
||
|
||
procedure SetImage(idx: Integer; srcImage: TBitmap); overload; override;
|
||
procedure SetImage(idx: integer; srcImage: TIEBaseBitmap); overload; override;
|
||
procedure SetImage(idx: Integer; width, height: Integer; PixelFormat: TIEPixelFormat); overload; override;
|
||
function SetImage(idx: integer; const FileName: WideString; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean; overload; override;
|
||
function SetImage(idx: integer; Stream: TStream; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean; overload; override;
|
||
|
||
// Public, but not exposed in documentation
|
||
procedure SetCurrentImage(srcImage: TIEBaseBitmap; const sDisplayName: string; bCanOverwriteExisting: Boolean = False);
|
||
|
||
procedure Flip(idx: integer; Dir: TFlipDir); override;
|
||
procedure Rotate(idx: integer; Angle: double; AntialiasMode: TIEAntialiasMode = ierFast; BackgroundColor: TColor = clWhite); override;
|
||
procedure Resample(idx: integer; ScaleBy: Double; FilterType: TResampleFilter = rfNone); override;
|
||
|
||
procedure ReleaseBitmap(idx: Integer; SaveChanges: Boolean); override;
|
||
|
||
// Internal use only
|
||
function SetImageFromStreamOrFile(idx: integer; Stream: TStream; const FileName: WideString; SourceImageIndex: Integer; FileFormat: TIOFileType; MIO: TObject = nil): Boolean; override;
|
||
function InternalLoadImageByID_Assigned(): Boolean; override;
|
||
procedure InternalLoadImageByID(Sender: TObject; Index, ID: Integer; var Bitmap: TIEBitmap; var IOParams: TIOParams); override;
|
||
|
||
end;
|
||
{$endif}
|
||
|
||
{$IFDEF UNITTESTING}
|
||
var
|
||
gUnitTesting_ImagesPath: string;
|
||
{$ENDIF}
|
||
|
||
implementation
|
||
|
||
uses
|
||
controls, sysutils, iemview, iesettings;
|
||
|
||
{$R-}
|
||
const
|
||
Cannot_Respotion_Error_Str = 'TIEDBMultiBitmap.SetImage cannot reposition table';
|
||
|
||
|
||
|
||
{ TIEDataLink }
|
||
|
||
constructor TIEDataLink.Create();
|
||
begin
|
||
inherited Create;
|
||
VisualControl := True;
|
||
fInternalScroll := False;
|
||
end;
|
||
|
||
destructor TIEDataLink.Destroy;
|
||
begin
|
||
//
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TIEDataLink.ActiveChanged;
|
||
begin
|
||
if assigned( fOnActiveChanged ) then
|
||
fOnActiveChanged( Self );
|
||
fModified := False;
|
||
end;
|
||
|
||
procedure TIEDataLink.Modified;
|
||
begin
|
||
fModified := True;
|
||
end;
|
||
|
||
procedure TIEDataLink.DataSetChanged;
|
||
begin
|
||
if assigned( fOnDataChanged ) then
|
||
fOnDataChanged( Self );
|
||
fModified := False;
|
||
end;
|
||
|
||
procedure TIEDataLink.DataSetScrolled(Distance: Integer);
|
||
begin
|
||
if ( fInternalScroll = False ) and assigned( fOnScrolled ) then
|
||
fOnScrolled( Self );
|
||
end;
|
||
|
||
procedure TIEDataLink.EditingChanged;
|
||
begin
|
||
if assigned( fOnEditingChanged ) then
|
||
fOnEditingChanged( Self );
|
||
end;
|
||
|
||
procedure TIEDataLink.RecordChanged(Field: TField);
|
||
begin
|
||
if assigned( fOnRecordChanged ) and ( Dataset.State <> dsEdit ) then
|
||
fOnRecordChanged( Field );
|
||
fModified := False;
|
||
end;
|
||
|
||
procedure TIEDataLink.UpdateData;
|
||
begin
|
||
if fModified and assigned( fOnDataUpdated ) then
|
||
fOnDataUpdated( Self );
|
||
fModified := False;
|
||
end;
|
||
|
||
// if bSilent then OnScrolled event is not called
|
||
procedure TIEDataLink.MoveToRecord(idx: Integer; bSilent: Boolean = True);
|
||
var
|
||
iMoveBy: Integer;
|
||
begin
|
||
if bSilent then
|
||
fInternalScroll := True;
|
||
try
|
||
iMoveBy := idx - ActiveRecord;
|
||
if iMoveBy <> 0 then
|
||
MoveBy( iMoveBy );
|
||
finally
|
||
fInternalScroll := False;
|
||
end;
|
||
end;
|
||
|
||
|
||
function HasAbsolutePath(const wFilename: WideString) : Boolean;
|
||
begin
|
||
Result := ( IECopy( AnsiString( wFilename ), 2, 2) = ':\' ) or // File path: D:\MyImage.jpg
|
||
( IECopy( AnsiString( wFilename ), 1, 2) = '\\' ); // UNC Path: \\SILVER_LAPTOP\D_On_E4440
|
||
end;
|
||
|
||
procedure IEBitmap_ReadFromBlob(Bitmap: TIEBitmap; var IOParams: TIOParams; BlobField: TBlobField; bUseMemoryStream: Boolean; out iFileFormat: TIOFileType);
|
||
var
|
||
aStream: TStream;
|
||
begin
|
||
if BlobField.BlobSize = 0 then
|
||
raise EIEException.create( 'Null Blob' );
|
||
|
||
aStream := nil;
|
||
try
|
||
if bUseMemoryStream then
|
||
begin
|
||
// Retrieve image via temporary memory stream
|
||
aStream := TMemoryStream.Create;
|
||
BlobField.SaveToStream( aStream );
|
||
aStream.Position := 0;
|
||
end
|
||
else
|
||
begin
|
||
// Directly retrieve the image
|
||
aStream := BlobField.DataSet.CreateBlobStream( BlobField, bmRead );
|
||
end;
|
||
|
||
if iFileFormat = ioUnknown then
|
||
iFileFormat := FindStreamFormat( aStream );
|
||
if Bitmap.Read( aStream, iFileFormat, IOParams ) = False then
|
||
raise EIEException.create( 'Read Error' );
|
||
|
||
finally
|
||
aStream.Free();
|
||
end;
|
||
end;
|
||
|
||
// DataSet can be nil
|
||
procedure IEBitmap_WriteToBlob(Bitmap: TIEBitmap; var IOParams: TIOParams; BlobField: TBlobField; bUseMemoryStream: Boolean; iFileFormat: TIOFileType);
|
||
var
|
||
aMemStream: TMemoryStream;
|
||
aBlobStream: TStream;
|
||
begin
|
||
if bUseMemoryStream then
|
||
begin
|
||
// SAVE BITMAP TO BLOB (MEM STREAM)
|
||
|
||
aMemStream := TMemoryStream.Create;
|
||
try
|
||
if Bitmap.Write( aMemStream, iFileFormat, IOParams ) = False then
|
||
raise EIEException.create( 'Write Error' );
|
||
aMemStream.Position := 0;
|
||
// Transfer from the memory stream to the blobstream
|
||
aBlobStream := BlobField.DataSet.CreateBlobStream( BlobField, bmWrite );
|
||
try
|
||
aMemStream.SaveToStream( aBlobStream );
|
||
finally
|
||
aBlobStream.Free;
|
||
end;
|
||
finally
|
||
aMemStream.free;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
// SAVE BITMAP TO BLOB (DIRECT)
|
||
|
||
aBlobStream := BlobField.DataSet.CreateBlobStream( BlobField, bmWrite );
|
||
try
|
||
if Bitmap.Write( aBlobStream, iFileFormat, IOParams ) = False then
|
||
raise EIEException.create( 'Write Error' );
|
||
finally
|
||
aBlobStream.Free;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
|
||
|
||
{ TIEDBBitmap }
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.Create
|
||
|
||
<FM>Declaration<FC>
|
||
constructor Create(); overload;
|
||
constructor Create(aDataSource: TDataSource; const sImageBlobField, sFilenameField: string); overload;
|
||
|
||
<FM>Description<FN>
|
||
Create a new TIEDBBitmap object.
|
||
Second overload creates the bitmap and sets <A TIEDBBitmap.DataSource>, <A TIEDBBitmap.ImageBlobField> and <A TIEDBBitmap.FilenameField>.
|
||
|
||
<FM>Examples<FC>
|
||
// Create DB Aware TImageEnView
|
||
procedure TMainForm.FormCreate(Sender: TObject);
|
||
begin
|
||
... Open a database table ...
|
||
|
||
fDBBitmap := TIEDBBitmap.create( DataSource1, 'Image', 'Name' );
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
end;
|
||
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBBitmap );
|
||
end;
|
||
|
||
// Extract an image from a database and save it
|
||
MyBMP := TIEDBBitmap.Create();
|
||
MyBMP.Read( MyTableImageBlob );
|
||
MyBmp.Write( 'D:\MyBlobImage.jpeg' );
|
||
MyBmp.Free;
|
||
|
||
!!}
|
||
constructor TIEDBBitmap.Create();
|
||
begin
|
||
inherited Create();
|
||
|
||
fDataLink := TIEDataLink.Create();
|
||
fDataLink.OnDataChanged := DatabaseEvent;
|
||
fDataLink.OnDataUpdated := DatabaseEvent;
|
||
fDataLink.OnScrolled := DatabaseEvent;
|
||
fDataLink.OnActiveChanged := ActiveChanged;
|
||
|
||
fAutoLoadTimer := nil;
|
||
fImagePath := '';
|
||
fImageFormat := ioUnknown;
|
||
fJpegQuality := 80;
|
||
fUseMemoryStream := true;
|
||
fAutoLoad := True;
|
||
fLastImageFormat := ioJPEG;
|
||
fImageLoaded := False;
|
||
end;
|
||
|
||
constructor TIEDBBitmap.Create(aDataSource: TDataSource; const sImageBlobField, sFilenameField: string);
|
||
begin
|
||
Create();
|
||
|
||
fDataLink.DataSource := aDataSource;
|
||
fFilenameFieldName := sFilenameField;
|
||
fImageBlobFieldName := sImageBlobField;
|
||
|
||
ActiveChanged( nil );
|
||
Modified := False;
|
||
end;
|
||
|
||
destructor TIEDBBitmap.Destroy;
|
||
begin
|
||
FreeAndNil( fAutoLoadTimer );
|
||
FreeAndNil( fDataLink );
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.DataSource
|
||
|
||
<FM>Declaration<FC>
|
||
property DataSource: TDataSource;
|
||
|
||
<FM>Description<FN>
|
||
Link the bitmap with a dataset. You will also need to set <A TIEDBBitmap.FilenameField> or <A TIEDBBitmap.ImageBlobField>.
|
||
|
||
If <A TIEDBBitmap.AutoLoad> is enabled the content will automatically update as the attached table changes. Otherwise you can call <A TIEDBBitmap.LoadImage>.
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a blob field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a blob field and name of image is stored in "ImageName" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.FilenameField := 'ImageName';
|
||
fDBBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBBitmap.FilenameField := 'ImageName';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBBitmap );
|
||
end;
|
||
|
||
!!}
|
||
function TIEDBBitmap.GetDataSource: TDataSource;
|
||
begin
|
||
Result := fDataLink.DataSource;
|
||
end;
|
||
|
||
procedure TIEDBBitmap.SetDataSource(Value: TDataSource);
|
||
begin
|
||
if Value <> fDataLink.Datasource then
|
||
begin
|
||
fDataLink.DataSource := Value;
|
||
ActiveChanged( nil );
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.ImageStorageMode
|
||
|
||
<FM>Declaration<FC>
|
||
property ImageStorageMode: <A TIEImageStorageMode>; (Read-Only)
|
||
|
||
<FM>Description<FN>
|
||
Returns the method that images are stored or referenced by the database.
|
||
If you have set <A TIEDBBitmap.ImageBlobField> then ImageStorageMode will return <FC>isEmbeddedBlob<FN>. Otherwise it will return <FC>isLinkedFile<FN>.
|
||
Setting <A TIEDBBitmap.FilenameField> has no effect on <FC>ImageStorageMode<FN>, because it can optionally provide a display name for an image stored in a blob field.
|
||
|
||
<TABLE>
|
||
<R> <H>Value</H> <H>Description</H> </R>
|
||
<R> <C>isEmbeddedBlob</C> <C>The image is embedded within a blob field</C> </R>
|
||
<R> <C>isLinkedFile</C> <C>A string field points to the filename of a local file</C> </R>
|
||
</TABLE>
|
||
!!}
|
||
function TIEDBBitmap.GetImageStorageMode: TIEImageStorageMode;
|
||
begin
|
||
Result := isLinkedFile;
|
||
if fImageBlobField <> nil then
|
||
Result := isEmbeddedBlob;
|
||
end;
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.ImagePath
|
||
|
||
<FM>Declaration<FC>
|
||
property ImagePath: string;
|
||
|
||
<FM>Description<FN>
|
||
If your database table references images that are stored locally as files (i.e. <A TIEDBBitmap.ImageStorageMode> = <FC>isLinkedFile<FN>) then you can use <FC>ImagePath<FN> to specify the folder where the files are located, i.e. the load path is specified by <FC>ImagePath<FN> + "Filename Field content".
|
||
|
||
Example usage:
|
||
- If <A TIEDBBitmap.FilenameField> is the full path to a local file then set <FC>ImagePath<FN> to ''
|
||
- If <A TIEDBBitmap.FilenameField> is only a name or has an invalid path then set <FC>ImagePath<FN> to the image folder
|
||
|
||
<TABLE>
|
||
<R> <H>ImagePath Property Value</H> <H>Content of Filename Field</H> <H>Loads Image From...</H> </R>
|
||
<R> <C></C> <C>C:\Some Folder\MyImage.jpg</C> <C>C:\Some Folder\MyImage.jpg</C> </R>
|
||
<R> <C>C:\Some Folder\</C> <C>MyImage.jpg</C> <C>C:\Some Folder\MyImage.jpg</C> </R>
|
||
<R> <C>C:\Some Folder\</C> <C>..\MyImage.jpg</C> <C>C:\Some Folder\..\MyImage.jpg</C> </R>
|
||
<R> <C>C:\Some Folder\</C> <C>D:\FolderX\MyImage.jpg</C> <C>C:\Some Folder\MyImage.jpg</C> </R>
|
||
<R> <C>http://www.imageen.com/images/</C> <C>MyImage.jpg</C> <C>http://www.imageen.com/images/MyImage.jpg</C> </R>
|
||
<R> <C></C> <C>http://www.imageen.com/images/MyImage.jpg</C> <C>http://www.imageen.com/images/MyImage.jpg</C> </R>
|
||
</TABLE>
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBBitmap.FilenameField := 'ImageName';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBBitmap );
|
||
end;
|
||
!!}
|
||
procedure TIEDBBitmap.SetImagePath(const v: string);
|
||
begin
|
||
if fImagePath <> v then
|
||
begin
|
||
fImagePath := v;
|
||
UpdateImage( False );
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure TIEDBBitmap.ActiveChanged(Sender: TObject);
|
||
begin
|
||
if fDataLink.Active and ( fFilenameFieldName <> '' ) then
|
||
begin
|
||
fFilenameField := fDataLink.DataSet.FindField( fFilenameFieldName );
|
||
if ( fFilenameField <> nil ) and ( TStringField( fFilenameField ).Size < 13 ) then
|
||
raise EIEException.create( 'Invalid Field Size' );
|
||
end
|
||
else
|
||
fFilenameField := nil;
|
||
|
||
if fDataLink.Active and ( fImageBlobFieldName <> '' ) then
|
||
fImageBlobField := fDataLink.DataSet.FindField( fImageBlobFieldName )
|
||
else
|
||
fImageBlobField := nil;
|
||
|
||
UpdateImage( False );
|
||
end;
|
||
|
||
|
||
// Handles: OnScrolled, OnDataChanged and OnDataUpdated
|
||
procedure TIEDBBitmap.DatabaseEvent(Sender: TObject);
|
||
begin
|
||
UpdateImage( True );
|
||
end;
|
||
|
||
|
||
procedure TIEDBBitmap.UpdateImage(bDelayed: Boolean);
|
||
begin
|
||
{$IFDEF UNITTESTING}
|
||
bDelayed := false;
|
||
{$ENDIF}
|
||
|
||
fImageLoaded := False;
|
||
if fAutoLoad then
|
||
begin
|
||
if bDelayed = False then
|
||
LoadImage
|
||
else
|
||
begin
|
||
// Delayed load
|
||
if not assigned(fAutoLoadTimer) then
|
||
begin
|
||
fAutoLoadTimer := TTimer.Create(nil);
|
||
fAutoLoadTimer.Interval := 210;
|
||
fAutoLoadTimer.OnTimer := AutoLoadTimerEvent;
|
||
end;
|
||
fAutoLoadTimer.enabled := False;
|
||
fAutoLoadTimer.enabled := True;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure TIEDBBitmap.AutoLoadTimerEvent(Sender: TObject);
|
||
begin
|
||
LoadImage;
|
||
end;
|
||
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.FilenameField
|
||
|
||
<FM>Declaration<FC>
|
||
property FilenameField : string;
|
||
|
||
<FM>Description<FN>
|
||
Specifies the database field that contains the name or filename of the image. It must be the name of a TStringField.
|
||
|
||
TIEDBBitmap can be used in two ways:
|
||
- Reading images directly from a database blob field, by setting <A TIEDBBitmap.ImageBlobField> to a valid field. In this situation <FC>FilenameField<FN> specifies a display name for the image (and is optional).
|
||
- Reading files stored in a local folder and referenced by a database string field, by setting <A TIEDBBitmap.ImageBlobField> to ''. In this case <FC>FilenameField<FN> should either be a full path to a local file, or a name only with the folder specified by <A TIEDBBitmap.ImagePath>
|
||
|
||
Note: Either <A TIEDBBitmap.ImageBlobField> or <A TIEDBBitmap.FilenameField> must be set (or both).
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a blob field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a blob field and name of image is stored in "ImageName" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.FilenameField := 'ImageName';
|
||
fDBBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBBitmap.FilenameField := 'ImageName';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBBitmap );
|
||
end;
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBBitmap.ImagePath>
|
||
- <A TIEDBBitmap.ImageBlobField>
|
||
- <A TIEDBBitmap.ImageStorageMode>
|
||
!!}
|
||
procedure TIEDBBitmap.SetFilenameFieldName(const Value: string);
|
||
begin
|
||
if fFilenameFieldName <> Value then
|
||
begin
|
||
fFilenameFieldName := Value;
|
||
ActiveChanged( nil );
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.ImageBlobField
|
||
|
||
<FM>Declaration<FC>
|
||
property ImageBlobField : string;
|
||
|
||
<FM>Description<FN>
|
||
Specifies the database blob field that embeds image files. It must be the name of a TBlobField.
|
||
|
||
TIEDBBitmap can be used in two ways:
|
||
- Reading images directly from a database blob field
|
||
- Reading files stored in a local folder and referenced by a database string field
|
||
|
||
If <A TIEDBBitmap.ImageBlobField> is not set then images will be loaded locally (using <A TIEDBBitmap.FilenameField>)
|
||
If <A TIEDBBitmap.ImageBlobField> is a valid field, then images will be read from the embedded blob field. The file format will be determined using <A TIEDBBitmap.ImageFormat>. You can optionally set <A TIEDBBitmap.FilenameField> to specify a field with a display name for the image.
|
||
|
||
Note: Either <A TIEDBBitmap.ImageBlobField> or <A TIEDBBitmap.FilenameField> must be set (or both).
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a blob field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a blob field and name of image is stored in "ImageName" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.FilenameField := 'ImageName';
|
||
fDBBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBBitmap := TIEDBBitmap.create();
|
||
fDBBitmap.DataSource := DataSource1;
|
||
fDBBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBBitmap.FilenameField := 'ImageName';
|
||
ImageEnView1.SetExternalBitmap( fDBBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBBitmap );
|
||
end;
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBBitmap.ImageFormat>
|
||
- <A TIEDBBitmap.FilenameField>
|
||
- <A TIEDBBitmap.ImageStorageMode>
|
||
|
||
!!}
|
||
procedure TIEDBBitmap.SetImageBlobFieldName(const Value: string);
|
||
begin
|
||
if fImageBlobFieldName <> Value then
|
||
begin
|
||
fImageBlobFieldName := Value;
|
||
ActiveChanged( nil );
|
||
end;
|
||
end;
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.AutoLoad
|
||
|
||
<FM>Declaration<FC>
|
||
property AutoLoad: boolean;
|
||
|
||
<FM>Description<FN>
|
||
If True and the TIEDBBitmap is attached to a <A TImageEnView> then changes to the database table cursor will be reflected in the TImageEnView. In other words, navigating the table will change the selected image in the TImageEnView.
|
||
If <FC>AutoLoad<FN> is false, you will need to call <A TIEDBBitmap.LoadImage> to refresh the image when the database cursor changes position.
|
||
|
||
Default: True
|
||
!!}
|
||
procedure TIEDBBitmap.SetAutoLoad(Value: Boolean);
|
||
begin
|
||
if fAutoLoad <> Value then
|
||
begin
|
||
fAutoLoad := Value;
|
||
UpdateImage( False );
|
||
end;
|
||
end;
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.LoadImage
|
||
|
||
<FM>Declaration<FC>
|
||
function LoadImage(): boolean;
|
||
|
||
<FM>Description<FN>
|
||
Loads the image at the current database position into the bitmap (if it has changed). If you have enabled <A TIEDBBitmap.AutoLoad> then you do not need to call <FC>LoadImage<FN>.
|
||
Returns <FC>False<FN> on failure.
|
||
|
||
Notes:
|
||
- This will only work if you have set <A TIEDBBitmap.DataSource> and <A TIEDBBitmap.ImageBlobField> (images stored in database table) or <A TIEDBBitmap.FilenameField> (images stored locally and referenced by the database table).
|
||
- This is the same as calling Read() except that loading is skipped if content has not changed
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBBitmap.AutoLoad>
|
||
- <A TIEDBBitmap.Read>
|
||
!!}
|
||
function TIEDBBitmap.LoadImage(): boolean;
|
||
begin
|
||
Result := True;
|
||
if fImageLoaded then
|
||
exit;
|
||
Result := Read();
|
||
fImageLoaded := True;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.UpdateDatabaseImage
|
||
|
||
<FM>Declaration<FC>
|
||
procedure UpdateDatabaseImage();
|
||
|
||
<FM>Description<FN>
|
||
Writes any changes to the image back to the blob field of the database table (at the current cursor position). Your current settings for <A TIEDBBitmap.DataSource>, <A TIEDBBitmap.ImageBlobField>, <A TIEDBBitmap.ImageStorageMode> and <A TIEDBBitmap.JpegQuality> are used.
|
||
This method has no effect if images are not stored within the database (i.e. <A TIEDBBitmap.ImageStorageMode> must be <FC>isEmbeddedBlob<FN>).
|
||
Raises exception on failure.
|
||
|
||
Note: This is the same as calling:<FC>
|
||
MyTable.Edit;
|
||
MyDBBitmap.Write();
|
||
MyTable.Post;
|
||
|
||
<FM>Example<FC>
|
||
// Rotate the current image and update the database
|
||
MyDBBitmap.Rotate( -90 );
|
||
MyDBBitmap.UpdateDatabaseImage();
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBBitmap.Write>
|
||
!!}
|
||
procedure TIEDBBitmap.UpdateDatabaseImage();
|
||
begin
|
||
try
|
||
fDataLink.DataSet.Edit;
|
||
if not Write then
|
||
raise EIEException.create('Unable to write image to file');
|
||
fDataLink.DataSet.Post;
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
Raise;
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.Read
|
||
|
||
<FM>Declaration<FC>
|
||
function Read(): boolean; overload;
|
||
function Read(aBlobField: TBlobField; FileType: <A TIOFileType> = 0; IOParams: <A TIOParams> = nil): boolean; overload;
|
||
function Read(const FileName: string; IOParams: <A TIOParams> = nil): boolean; overload;
|
||
function Read(Stream: TStream; FileType: <A TIOFileType> = ioUnknown; IOParams: <A TIOParams> = nil): boolean; overload;
|
||
function Read(Buffer: pointer; BufferSize: integer; FileType: <A TIOFileType> = ioUnknown; IOParams: <A TIOParams> = nil): boolean;
|
||
|
||
<FM>Description<FN>
|
||
Load an image from a blob field, file or stream. This method supports all formats supported by <A TImageEnIO> class.
|
||
The Read(); overload reads the image at the current database position using the properties of <A TIEDBBitmap.DataSource>, <A TIEDBBitmap.ImageBlobField> and/or <A TIEDBBitmap.FilenameField>.
|
||
When reading from a blob or stream you can optionally specify the <L TIOFileType>Format</L>. If it is not specified ImageEn will determine the file type automatically.
|
||
You can optionally pass an <A TIOParams> object for the I/O parameters of the file (see also <A TIEBitmap.ParamsEnabled>).
|
||
Returns <FC>False<FN> on failure.
|
||
|
||
<FM>Examples<FC>
|
||
// Extract an image from a database and save it
|
||
MyBMP := TIEDBBitmap.Create();
|
||
MyBMP.Read( MyTableImageBlob );
|
||
MyBmp.Write( 'D:\MyBlobImage.jpeg' );
|
||
MyBmp.Free;
|
||
|
||
// Reduce the size of an image in the database
|
||
MyBMP := TIEDBBitmap.Create();
|
||
MyBMP.Read( MyTableImageBlobField );
|
||
MyBmp.Resample( 800, 600, rfLanczos3, true);
|
||
MyBmp.JpegQuality := 75;
|
||
MyBmp.Write( MyTableImageBlobField, ioJPEG );
|
||
MyBmp.Free;
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBBitmap.LoadImage>
|
||
- <A TIEDBBitmap.Write>
|
||
!!}
|
||
function TIEDBBitmap.Read(): boolean;
|
||
var
|
||
IOParams: TIOParams;
|
||
wFilename: Widestring;
|
||
begin
|
||
IOParams := nil;
|
||
if ( fOwner <> nil ) and ( fOwner is TImageEnView ) then
|
||
IOParams := TImageEnView( fOwner ).IO.Params;
|
||
|
||
// Read Filename field
|
||
wFilename := '';
|
||
if fFilenameField <> nil then
|
||
wFilename := WideString( TStringField( fFilenameField ).Value );
|
||
{$IFDEF UNITTESTING}
|
||
if Pos( Widestring( 'XXX\' ), wFilename ) = 1 then
|
||
wFilename := StringReplace( wFilename, 'XXX\', IEAddBackSlash( gUnitTesting_ImagesPath ), []);
|
||
{$ENDIF}
|
||
|
||
if wFilename <> '' then
|
||
begin
|
||
if ( fImagePath <> '' ) and HasAbsolutePath( wFilename ) then
|
||
wFilename := ExtractFileName( wFilename );
|
||
wFilename := IEAddBackSlash( fImagePath ) + wFilename;
|
||
end;
|
||
|
||
// Load Image
|
||
if ImageStorageMode = isLinkedFile then
|
||
begin
|
||
if wFilename = '' then
|
||
Result := False
|
||
else
|
||
Result := Read( wFilename, IOParams );
|
||
end
|
||
else
|
||
// ImageStorageMode = isEmbeddedBlob
|
||
begin
|
||
Result := Read( TBlobField( fImageBlobField ), fImageFormat, IOParams );
|
||
if Result and ( wFilename <> '' ) then
|
||
begin
|
||
Filename := wFilename;
|
||
if IOParams <> nil then
|
||
IOParams.FileName := wFilename;
|
||
if ParamsEnabled then
|
||
fIOParams.FileName := wFilename;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TIEDBBitmap.Read(aBlobField: TBlobField; FileType: TIOFileType = 0; IOParams: TIOParams = nil): boolean;
|
||
var
|
||
bFreeParams: Boolean;
|
||
iFileFormat: TIOFileType;
|
||
begin
|
||
Result := True;
|
||
bFreeParams := False;
|
||
try
|
||
if ( IOParams = nil ) and ParamsEnabled then
|
||
begin
|
||
bFreeParams := True;
|
||
IOParams := TIOParams.Create;
|
||
IOParams.Assign( fIOParams );
|
||
end;
|
||
|
||
try
|
||
iFileFormat := FileType;
|
||
IEBitmap_ReadFromBlob( Self, IOParams, aBlobField, fUseMemoryStream, iFileFormat );
|
||
if iFileFormat > 0 then
|
||
fLastImageFormat := iFileFormat;
|
||
if ParamsEnabled then
|
||
fIOParams.Assign( IOParams );
|
||
Modified := False;
|
||
except
|
||
// Read error
|
||
Result := False;
|
||
end;
|
||
|
||
finally
|
||
if bFreeParams then
|
||
FreeAndNil( IOParams );
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBBitmap.Write
|
||
|
||
<FM>Declaration<FC>
|
||
function Write(): boolean; overload;
|
||
function Write(aBlobField: TBlobField; FileType: <A TIOFileType>; IOParams: <A TIOParams> = nil): boolean; overload;
|
||
function Write(const FileName: string; IOParams: <A TIOParams> = nil): boolean; overload;
|
||
function Write(Stream: TStream; FileType: <A TIOFileType>; IOParams: <A TIOParams> = nil): boolean; overload;
|
||
|
||
<FM>Description<FN>
|
||
Writes image to a blob field, file or stream. This method supports all formats supported by <A TImageEnIO> class
|
||
The Write(); overload sets the image at the current database position using the properties of <A TIEDBBitmap.DataSource>, <A TIEDBBitmap.ImageBlobField> and/or <A TIEDBBitmap.FilenameField>..
|
||
If saving to a blob or stream you must specify the <L TIOFileType>FileType</L>
|
||
You can optionally specify an <A TIOParams> object containing the I/O parameters of the file (see also <A TIEBitmap.ParamsEnabled>).
|
||
Returns true on success.
|
||
|
||
<FM>Examples<FC>
|
||
// Rotate the current image in the database (assumes you have set <A TIEDBBitmap.DataSource> and <A TIEDBBitmap.ImageBlobField>)
|
||
fDBBitmap.Rotate( -90 );
|
||
MyTable.Edit;
|
||
MyTableName.AsString := 'Rotated 90';
|
||
fDBBitmap.Write( MyTableImageBlob, ioJPEG );
|
||
MyTable.Post;
|
||
|
||
|
||
// Append an image to the database
|
||
MyBMP := TIEDBBitmap.Create();
|
||
MyBMP.Read( 'D:\MyBlobImage.jpeg' );
|
||
|
||
MyTable.Append;
|
||
MyTableName.AsString := 'My Cool Image';
|
||
MyBmp.Write( MyTableImageBlob, ioJPEG );
|
||
MyTable.Post;
|
||
MyBmp.Free;
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBBitmap.UpdateDatabaseImage>
|
||
- <A TIEDBBitmap.Read>
|
||
!!}
|
||
function TIEDBBitmap.Write(): boolean;
|
||
var
|
||
IOParams: TIOParams;
|
||
bFreeParams: Boolean;
|
||
begin
|
||
bFreeParams := False;
|
||
IOParams := nil;
|
||
try
|
||
if ParamsEnabled then
|
||
IOParams := fIOParams
|
||
else
|
||
if ( fOwner <> nil ) and ( fOwner is TImageEnView ) then
|
||
IOParams := TImageEnView( fOwner ).IO.Params
|
||
else
|
||
begin
|
||
IOParams := TIOParams.Create;
|
||
bFreeParams := True;
|
||
end;
|
||
IOParams.JPEG_Quality := fJPEGQuality;
|
||
|
||
if fImageFormat <> ioUnknown then
|
||
fLastImageFormat := fImageFormat;
|
||
|
||
// Load Image
|
||
if ImageStorageMode = isLinkedFile then
|
||
begin
|
||
if IOParams.Filename = '' then
|
||
Result := False
|
||
else
|
||
Result := Write( IOParams.Filename, IOParams );
|
||
end
|
||
else
|
||
// ImageStorageMode = isEmbeddedBlob
|
||
begin
|
||
Result := Write( TBlobField( fImageBlobField ), fLastImageFormat, IOParams );
|
||
end;
|
||
finally
|
||
if bFreeParams then
|
||
FreeAndNil( IOParams );
|
||
end;
|
||
|
||
// Note: Update will be called automatically due to db changes
|
||
end;
|
||
|
||
|
||
function TIEDBBitmap.Write(aBlobField: TBlobField; FileType: TIOFileType; IOParams: TIOParams = nil): boolean;
|
||
begin
|
||
Result := True;
|
||
try
|
||
if ( IOParams = nil ) and ParamsEnabled then
|
||
IOParams := fIOParams;
|
||
IEBitmap_WriteToBlob( Self, IOParams, aBlobField, fUseMemoryStream, FileType );
|
||
except
|
||
// Write error
|
||
Result := False;
|
||
end;
|
||
end;
|
||
|
||
|
||
|
||
|
||
{$IFDEF IEINCLUDEMULTIVIEW}
|
||
|
||
{ TIEDBMultiBitmap }
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.Create
|
||
|
||
<FM>Declaration<FC>
|
||
constructor Create(); overload;
|
||
constructor Create(aDataSource: TDataSource; const sImageBlobField, sFilenameField: string; bFilenameFieldIsUnique: Boolean = False); overload;
|
||
|
||
<FM>Description<FN>
|
||
Create a new TIEDBMultiBitmap object.
|
||
Second overload creates the bitmap and sets <A TIEDBMultiBitmap.DataSource>, <A TIEDBMultiBitmap.ImageBlobField>, <A TIEDBMultiBitmap.FilenameField> and <A TIEDBMultiBitmap.FilenameFieldIsUnique>.
|
||
|
||
<FM>Example<FC>
|
||
// Create DB Aware TImageEnMView
|
||
procedure TMainForm.FormCreate(Sender: TObject);
|
||
begin
|
||
... Open a database table ...
|
||
|
||
fDBMBitmap := TIEDBMultiBitmap.create( DataSource1, 'Image', 'Name' );
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
end;
|
||
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBMBitmap );
|
||
end;
|
||
!!}
|
||
constructor TIEDBMultiBitmap.Create();
|
||
begin
|
||
inherited Create();
|
||
|
||
fDataLink := TIEDataLink.Create();
|
||
fDataLink.OnDataChanged := DataChanged;
|
||
fDataLink.OnDataUpdated := DataUpdated;
|
||
fDataLink.OnActiveChanged := ActiveChanged;
|
||
fDataLink.OnRecordChanged := RecordChanged;
|
||
fDataLink.OnScrolled := Scrolled;
|
||
|
||
fImagePath := '';
|
||
fImageFormat := ioUnknown;
|
||
fJpegQuality := 80;
|
||
fUseMemoryStream := true;
|
||
fFollowDBCursor := False;
|
||
fMaxDisplayRecords := 10000;
|
||
fLastImageFormat := ioJPEG;
|
||
fBlobBitmap := nil;
|
||
fDefaultFilename := 'Image';
|
||
fFilenameFieldIsUnique := False;
|
||
end;
|
||
|
||
constructor TIEDBMultiBitmap.Create(aDataSource: TDataSource; const sImageBlobField, sFilenameField: string; bFilenameFieldIsUnique: Boolean = False);
|
||
begin
|
||
Create();
|
||
LockUpdate;
|
||
try
|
||
fDataLink.DataSource := aDataSource;
|
||
fFilenameFieldName := sFilenameField;
|
||
fImageBlobFieldName := sImageBlobField;
|
||
fFilenameFieldIsUnique := bFilenameFieldIsUnique;
|
||
|
||
ActiveChanged( nil );
|
||
finally
|
||
UnlockUpdate;
|
||
end;
|
||
Modified := False;
|
||
end;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.Destroy
|
||
|
||
<FM>Declaration<FC>
|
||
destructor Destroy;
|
||
|
||
<FM>Description<FN>
|
||
Frees the object.
|
||
!!}
|
||
destructor TIEDBMultiBitmap.Destroy;
|
||
begin
|
||
FreeAndNil( fDataLink );
|
||
FreeAndNil( fBlobBitmap );
|
||
|
||
inherited Destroy;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.DataSource
|
||
|
||
<FM>Declaration<FC>
|
||
property DataSource: TDataSource;
|
||
|
||
<FM>Description<FN>
|
||
Link the multi-bitmap with a dataset. The content will automatically update as the attached table changes. You will also need to set <A TIEDBMultiBitmap.FilenameField> or <A TIEDBMultiBitmap.ImageBlobField>.
|
||
|
||
Note: The maximum images that will be loaded is specified by <A TIEDBMultiBitmap.MaxDisplayRecords>
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a blob field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a blob field and name of image is stored in "ImageName" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.FilenameField := 'ImageName';
|
||
fDBMBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBMBitmap.FilenameField := 'ImageName';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBMBitmap );
|
||
end;
|
||
|
||
!!}
|
||
function TIEDBMultiBitmap.GetDataSource: TDataSource;
|
||
begin
|
||
Result := fDataLink.DataSource;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.SetDataSource(Value: TDataSource);
|
||
begin
|
||
if Value <> fDataLink.Datasource then
|
||
begin
|
||
fDataLink.DataSource := Value;
|
||
ActiveChanged( nil );
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.ReadOnly
|
||
|
||
<FM>Declaration<FC>
|
||
property ReadOnly: Boolean;
|
||
|
||
<FM>Description<FN>
|
||
Determines whether the user can change the contents of the field using the image control.
|
||
|
||
!!}
|
||
function TIEDBMultiBitmap.GetReadOnly: Boolean;
|
||
begin
|
||
Result := fDataLink.ReadOnly;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.SetReadOnly(Value: Boolean);
|
||
begin
|
||
fDataLink.ReadOnly := Value;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.ImageStorageMode
|
||
|
||
<FM>Declaration<FC>
|
||
property ImageStorageMode: <A TIEImageStorageMode>; (Read-Only)
|
||
|
||
<FM>Description<FN>
|
||
Returns the method that images are stored or referenced by the database.
|
||
|
||
If you have set <A TIEDBMultiBitmap.ImageBlobField> then ImageStorageMode will return <FC>isEmbeddedBlob<FN>. Otherwise it will return <FC>isLinkedFile<FN>.
|
||
|
||
Setting <A TIEDBMultiBitmap.FilenameField> has no effect on <FC>ImageStorageMode<FN>, because it can optionally provide a display name for an image stored in a blob field.
|
||
|
||
<TABLE>
|
||
<R> <H>Value</H> <H>Description</H> </R>
|
||
<R> <C>isEmbeddedBlob</C> <C>The image is embedded within a blob field</C> </R>
|
||
<R> <C>isLinkedFile</C> <C>A string field points to the filename of a local file</C> </R>
|
||
</TABLE>
|
||
!!}
|
||
function TIEDBMultiBitmap.GetImageStorageMode: TIEImageStorageMode;
|
||
begin
|
||
Result := isLinkedFile;
|
||
if fImageBlobField <> nil then
|
||
Result := isEmbeddedBlob;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.ImagePath
|
||
|
||
<FM>Declaration<FC>
|
||
property ImagePath: string;
|
||
|
||
<FM>Description<FN>
|
||
If your database table references images that are stored locally as files (i.e. <A TIEDBMultiBitmap.ImageStorageMode> = <FC>isLinkedFile<FN>) then you can use <FC>ImagePath<FN> to specify the folder where the files are located, i.e. the load path is specified by <FC>ImagePath<FN> + "Filename Field content".
|
||
|
||
Example usage:
|
||
- If <A TIEDBMultiBitmap.FilenameField> is the full path to a local file then set <FC>ImagePath<FN> to ''
|
||
- If <A TIEDBMultiBitmap.FilenameField> is only a name or has an erroneous path then set <FC>ImagePath<FN> to the image folder
|
||
|
||
<TABLE>
|
||
<R> <H>ImagePath Property Value</H> <H>Content of Filename Field</H> <H>Loads Image From...</H> </R>
|
||
<R> <C></C> <C>C:\Some Folder\MyImage.jpg</C> <C>C:\Some Folder\MyImage.jpg</C> </R>
|
||
<R> <C>C:\Some Folder\</C> <C>MyImage.jpg</C> <C>C:\Some Folder\MyImage.jpg</C> </R>
|
||
<R> <C>C:\Some Folder\</C> <C>..\MyImage.jpg</C> <C>C:\Some Folder\..\MyImage.jpg</C> </R>
|
||
<R> <C>C:\Some Folder\</C> <C>D:\FolderX\MyImage.jpg</C> <C>C:\Some Folder\MyImage.jpg</C> </R>
|
||
<R> <C>http://www.imageen.com/images/</C> <C>MyImage.jpg</C> <C>http://www.imageen.com/images/MyImage.jpg</C> </R>
|
||
<R> <C></C> <C>http://www.imageen.com/images/MyImage.jpg</C> <C>http://www.imageen.com/images/MyImage.jpg</C> </R>
|
||
</TABLE>
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBMBitmap.FilenameField := 'ImageName';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBMBitmap );
|
||
end;
|
||
!!}
|
||
procedure TIEDBMultiBitmap.SetImagePath(const v: string);
|
||
begin
|
||
if fImagePath <> v then
|
||
begin
|
||
fImagePath := v;
|
||
UpdateEx( True );
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure TIEDBMultiBitmap.ActiveChanged(Sender: TObject);
|
||
begin
|
||
if fDataLink.Active and ( fFilenameFieldName <> '' ) then
|
||
begin
|
||
fFilenameField := fDataLink.DataSet.FindField( fFilenameFieldName );
|
||
if ( fFilenameField <> nil ) and ( TStringField( fFilenameField ).Size < 13 ) then
|
||
raise EIEException.create( 'Invalid Field Size' );
|
||
end
|
||
else
|
||
fFilenameField := nil;
|
||
|
||
if fDataLink.Active and ( fImageBlobFieldName <> '' ) then
|
||
fImageBlobField := fDataLink.DataSet.FindField( fImageBlobFieldName )
|
||
else
|
||
fImageBlobField := nil;
|
||
|
||
UpdateEx( True );
|
||
end;
|
||
|
||
|
||
procedure TIEDBMultiBitmap.DataChanged(Sender: TObject);
|
||
begin
|
||
UpdateEx( False );
|
||
end;
|
||
|
||
|
||
procedure TIEDBMultiBitmap.Scrolled(Sender: TObject);
|
||
begin
|
||
UpdateActive;
|
||
end;
|
||
|
||
|
||
procedure TIEDBMultiBitmap.RecordChanged(Field: TField);
|
||
var
|
||
bUpdate: Boolean;
|
||
begin
|
||
bUpdate := (( fFilenameField <> nil ) and ( Field = fFilenameField )) or
|
||
(( fImageBlobField<> nil ) and ( Field = fImageBlobField));
|
||
if bUpdate and assigned( fOwner ) and ( fOwner is TImageEnMView ) then
|
||
TImageEnMView( fOwner ).ClearImageCache( fDatalink.ActiveRecord );
|
||
end;
|
||
|
||
|
||
procedure TIEDBMultiBitmap.DataUpdated(Sender: TObject);
|
||
begin
|
||
UpdateEx( False );
|
||
end;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.Update
|
||
|
||
<FM>Declaration<FC>
|
||
procedure Update;
|
||
|
||
<FM>Description<FN>
|
||
Refresh the content of the TIEDBMultiBitmap from the database and update the <A TImageEnMView> if connected.
|
||
!!}
|
||
procedure TIEDBMultiBitmap.Update;
|
||
begin
|
||
UpdateEx( True );
|
||
end;
|
||
|
||
// if bFullUpdate then it clears the thumbnail cache too
|
||
procedure TIEDBMultiBitmap.UpdateEx(bFullUpdate: Boolean = true);
|
||
var
|
||
iRowCount: Integer;
|
||
begin
|
||
if LockUpdateCount > 0 then
|
||
begin
|
||
fUpdatePending := True;
|
||
if bFullUpdate then
|
||
fUpdatePendingIsFull := True;
|
||
exit;
|
||
end;
|
||
|
||
iRowCount := 0;
|
||
if fDataLink.Active and ( fDataLink.RecordCount > 0 ) then
|
||
begin
|
||
fDataLink.BufferCount := fMaxDisplayRecords;
|
||
iRowCount := fDataLink.RecordCount;
|
||
end;
|
||
AllocateVirtual( iRowCount );
|
||
fUpdatePending := False;
|
||
|
||
if assigned( fOwner ) and ( fOwner is TImageEnMView ) then
|
||
TImageEnMView( fOwner ).UpdateEx( bFullUpdate or fUpdatePendingIsFull, False );
|
||
fUpdatePendingIsFull := False;
|
||
|
||
UpdateActive;
|
||
end;
|
||
|
||
|
||
// Used to communicate changes in the selection of an owner control, TImageEnMView to underlying image sources, such as a database table
|
||
procedure TIEDBMultiBitmap.SetActiveImage(idx: integer);
|
||
begin
|
||
if Assigned( fDataLink ) and fDataLink.Active then
|
||
fDataLink.MoveToRecord( idx );
|
||
end;
|
||
|
||
|
||
// If this component has been filled "Virtually" then fImageInfo.Count has been set to the number of images available
|
||
// Without fImageInfo items being assigned. In this case it must be assigned in CheckAllocated()
|
||
procedure TIEDBMultiBitmap.CheckAllocated(idx: integer);
|
||
var
|
||
newinfo: TIEImageInfo;
|
||
wFilename: WideString;
|
||
OldActive: Integer;
|
||
begin
|
||
// Already allocated?
|
||
if fImageInfo[ idx ] <> nil then
|
||
exit;
|
||
|
||
// Have data source?
|
||
if not ( Assigned( fDataLink ) and fDataLink.Active ) then
|
||
Exit;
|
||
|
||
// Fields are valid? Need at least one
|
||
if ( fFilenameField = nil ) and
|
||
( fImageBlobField = nil ) then
|
||
raise EIEException.create( 'Valid image fields have not been specified for TIEDBMultiBitmap' );
|
||
|
||
if assigned( fOwner ) and ( fOwner is TImageEnMView ) then
|
||
begin
|
||
if fFilenameFieldIsUnique then
|
||
TImageEnMView( fOwner ).ImageCacheReusage := iecrLoose
|
||
else
|
||
TImageEnMView( fOwner ).ImageCacheReusage := iecrStrict;
|
||
end;
|
||
|
||
OldActive := fDataLink.ActiveRecord;
|
||
try
|
||
fDataLink.ActiveRecord := idx;
|
||
|
||
NewInfo := TIEImageInfo.Create(self);
|
||
NewInfo.Background := fBackground;
|
||
|
||
// Read Filename field
|
||
wFilename := '';
|
||
if fFilenameField <> nil then
|
||
wFilename := WideString( TStringField( fFilenameField ).Value );
|
||
{$IFDEF UNITTESTING}
|
||
if Pos( Widestring( 'XXX\' ), wFilename ) = 1 then
|
||
wFilename := StringReplace( wFilename, 'XXX\', IEAddBackSlash( gUnitTesting_ImagesPath ), []);
|
||
{$ENDIF}
|
||
|
||
if wFilename <> '' then
|
||
begin
|
||
if ( fImagePath <> '' ) and HasAbsolutePath( wFilename ) then
|
||
wFilename := ExtractFileName( wFilename );
|
||
wFilename := IEAddBackSlash( fImagePath ) + wFilename;
|
||
NewInfo.Filename := wFilename;
|
||
end;
|
||
|
||
if ImageStorageMode = isEmbeddedBlob then
|
||
NewInfo.ID := Idx;
|
||
|
||
if assigned( fOwner ) and ( fOwner is TImageEnMView ) then
|
||
NewInfo.cacheImage := TImageEnMView( fOwner ).FindImageInCache( idx, wFilename );
|
||
|
||
fImageInfo[ idx ] := NewInfo;
|
||
|
||
finally
|
||
fDataLink.ActiveRecord := OldActive;
|
||
end;
|
||
end;
|
||
|
||
// If descendent classes need to load images by ID on demand, then InternalLoadImageByID must be used and InternalLoadImageByID_Assigned returns true
|
||
function TIEDBMultiBitmap.InternalLoadImageByID_Assigned(): Boolean;
|
||
begin
|
||
Result := True;
|
||
end;
|
||
|
||
// If descendent classes need to load images by ID on demand, then InternalLoadImageByID must be used and InternalLoadImageByID_Assigned returns true
|
||
procedure TIEDBMultiBitmap.InternalLoadImageByID(Sender: TObject; Index, ID: Integer; var Bitmap: TIEBitmap; var IOParams: TIOParams);
|
||
var
|
||
OldActive: Integer;
|
||
iFileFormat: TIOFileType;
|
||
begin
|
||
OldActive := fDataLink.ActiveRecord;
|
||
try
|
||
fDataLink.ActiveRecord := ID;
|
||
|
||
if fBlobBitmap = nil then
|
||
fBlobBitmap := TIEBitmap.create;
|
||
|
||
// USED FOR BLOB LOADING ONLY
|
||
|
||
if ImageStorageMode <> isEmbeddedBlob then
|
||
raise EIEException.create('Unexpected error');
|
||
|
||
iFileFormat := fImageFormat;
|
||
// Exception raised on failure
|
||
IEBitmap_ReadFromBlob( fBlobBitmap, IOParams, TBlobField( fImageBlobField ), fUseMemoryStream, iFileFormat );
|
||
Bitmap := fBlobBitmap;
|
||
if iFileFormat > 0 then
|
||
fLastImageFormat := iFileFormat;
|
||
|
||
finally
|
||
fDataLink.ActiveRecord := OldActive;
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.FilenameField
|
||
|
||
<FM>Declaration<FC>
|
||
property FilenameField : string;
|
||
|
||
<FM>Description<FN>
|
||
Specifies the database field that contains the name or filename of the image. It must be the name of a TStringField.
|
||
|
||
TIEDBMultiBitmap can be used in two ways:
|
||
- Reading images directly from a database blob field, by setting <A TIEDBMultiBitmap.ImageBlobField> to a valid field. In this situation <FC>FilenameField<FN> specifies a display name for the image (and is optional). It will also improves performance, especially if the <L TIEDBMultiBitmap.FilenameFieldIsUnique>filename field is unique</L>.
|
||
- Reading files stored in a local folder and referenced by a database string field, by setting <A TIEDBMultiBitmap.ImageBlobField> to ''. In this case <FC>FilenameField<FN> should either be a full path to a local file, or a name only with the folder specified by <A TIEDBMultiBitmap.ImagePath>
|
||
|
||
Notes:
|
||
- Either <A TIEDBMultiBitmap.ImageBlobField> or <A TIEDBMultiBitmap.FilenameField> must be set (or both).
|
||
- You should set <A TIEDBMultiBitmap.FilenameFieldIsUnique> if the field is unique to improve performance
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBMultiBitmap.ImagePath>
|
||
- <A TIEDBMultiBitmap.FilenameFieldIsUnique>
|
||
- <A TIEDBMultiBitmap.ImageBlobField>
|
||
- <A TIEDBMultiBitmap.ImageStorageMode>
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a blob field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a blob field and name of image is stored in "ImageName" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.FilenameField := 'ImageName';
|
||
fDBMBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBMBitmap.FilenameField := 'ImageName';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBMBitmap );
|
||
end;
|
||
!!}
|
||
procedure TIEDBMultiBitmap.SetFilenameFieldName(const Value: string);
|
||
begin
|
||
if fFilenameFieldName <> Value then
|
||
begin
|
||
fFilenameFieldName := Value;
|
||
ActiveChanged( nil );
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.ImageBlobField
|
||
|
||
<FM>Declaration<FC>
|
||
property ImageBlobField : string;
|
||
|
||
<FM>Description<FN>
|
||
Specifies the database blob field that embeds image files. It must be the name of a TBlobField.
|
||
|
||
TIEDBMultiBitmap can be used in two ways:
|
||
- Reading images directly from a database blob field
|
||
- Reading files stored in a local folder and referenced by a database string field
|
||
|
||
If <A TIEDBMultiBitmap.ImageBlobField> is not set then images will be loaded locally (using <A TIEDBMultiBitmap.FilenameField>)
|
||
If <A TIEDBMultiBitmap.ImageBlobField> is a valid field, then images will be read from the embedded blob field. The file format will be determined using <A TIEDBMultiBitmap.ImageFormat>. You can optionally set <A TIEDBMultiBitmap.FilenameField> to specify a field with a display name for the image. Setting <A TIEDBMultiBitmap.FilenameField> will also improve performance, especially if the <L TIEDBMultiBitmap.FilenameFieldIsUnique>filename field is unique</L>.
|
||
|
||
Note: Either <A TIEDBMultiBitmap.ImageBlobField> or <A TIEDBMultiBitmap.FilenameField> must be set (or both).
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBMultiBitmap.ImageFormat>
|
||
- <A TIEDBMultiBitmap.FilenameField>
|
||
- <A TIEDBMultiBitmap.ImageStorageMode>
|
||
|
||
<FM>Examples<FC>
|
||
// Display content of a table where images are stored in a blob field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a blob field and name of image is stored in "ImageName" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.FilenameField := 'ImageName';
|
||
fDBMBitmap.ImageBlobField := 'ImageBlob';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder and their path and filename is referenced by the "ImageFilename" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.FilenameField := 'ImageFilename';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
// Display content of a table where images are stored in a folder named "My Folder" and their filename is referenced by the "ImageName" field
|
||
fDBMBitmap := TIEDBMultiBitmap.create();
|
||
fDBMBitmap.DataSource := DataSource1;
|
||
fDBMBitmap.ImagePath := 'C:\My Folder\';
|
||
fDBMBitmap.FilenameField := 'ImageName';
|
||
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
||
|
||
|
||
Note: Don't forget to free the object...
|
||
procedure TMainForm.FormDestroy(Sender: TObject);
|
||
begin
|
||
FreeAndNil( fDBMBitmap );
|
||
end;
|
||
!!}
|
||
procedure TIEDBMultiBitmap.SetImageBlobFieldName(const Value: string);
|
||
begin
|
||
if fImageBlobFieldName <> Value then
|
||
begin
|
||
fImageBlobFieldName := Value;
|
||
ActiveChanged( nil );
|
||
end;
|
||
end;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.MaxDisplayRecords
|
||
|
||
<FM>Declaration<FC>
|
||
property MaxDisplayRecords: Integer;
|
||
|
||
<FM>Description<FN>
|
||
TIEDBMultiBitmap will load all records of your database table into memory up to the maximum specified by <FC>MaxDisplayRecords<FN>. If your table contains more records than <FC>MaxDisplayRecords<FN> they will not be displayed, so you should use table filtering to ensure the record count does not become too large and affect performance.
|
||
Default: 10,000
|
||
!!}
|
||
procedure TIEDBMultiBitmap.SetMaxDisplayRecords(Value: Integer);
|
||
begin
|
||
if fMaxDisplayRecords <> Value then
|
||
begin
|
||
fMaxDisplayRecords := Value;
|
||
UpdateEx( True );
|
||
end;
|
||
end;
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.FollowDBCursor
|
||
|
||
<FM>Declaration<FC>
|
||
property FollowDBCursor: boolean;
|
||
|
||
<FM>Description<FN>
|
||
If True and the TIEDBMultiBitmap is attached to a <A TImageEnMView> then changes to the database table cursor will be reflected in the TImageEnMView. In other words, navigating the table will change the selected image in the TImageEnMView.
|
||
|
||
Default: false (the position of the database table cursor is ignored)
|
||
!!}
|
||
procedure TIEDBMultiBitmap.SetFollowDBCursor(Value: Boolean);
|
||
begin
|
||
if fFollowDBCursor <> Value then
|
||
begin
|
||
fFollowDBCursor := Value;
|
||
UpdateActive;
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure TIEDBMultiBitmap.UpdateActive;
|
||
begin
|
||
if fFollowDBCursor and
|
||
Assigned( fDataLink ) and
|
||
fDataLink.Active and
|
||
assigned( fOwner ) and
|
||
( fOwner is TImageEnMView ) then
|
||
TImageEnMView( fOwner ).SelectedImage := fDataLink.ActiveRecord;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.InsertImage
|
||
|
||
<FM>Declaration<FC>
|
||
procedure InsertImage(idx: integer); overload;
|
||
procedure InsertImage(Idx : integer; Stream : TStream); overload;
|
||
procedure InsertImage(Idx : integer; Bitmap : <A TIEBitmap>); overload;
|
||
procedure InsertImage(Idx : integer; Bitmap : TBitmap); overload;
|
||
procedure InsertImage(Idx : integer; MBitmap : <A TIECustomMultiBitmap>); overload;
|
||
procedure InsertImage(Idx : integer; Width, Height : integer; PixelFormat : <A TIEPixelFormat> = ie24RGB); overload;
|
||
procedure InsertImage(Idx : integer; const FileName : string); overload;
|
||
|
||
<FM>Description<FN>
|
||
Inserts a new image into the database at position, <FC>idx<FN> (0 is the first). The table will be positioned at the new record.
|
||
|
||
Note: TDataset.Insert and TDataset.Post will be called
|
||
|
||
<FM>Examples<FC>
|
||
// Prompt to insert a new image into the database after the selected record
|
||
if dlgOpenImage.Execute then
|
||
fDBMBitmap.InsertImage( ImageEnMView1.SelectedImage, dlgOpenImage.Filename );
|
||
|
||
// Compare the following...
|
||
ImageEnView1.IO.LoadFromFile('C:\000.tif');
|
||
MBitmap.InsertImage( 0 );
|
||
MyTable.Edit;
|
||
MBitmap.SetImage( -1, ImageEnView1.Bitmap );
|
||
MyTable.Post;
|
||
|
||
// Which is the same as...
|
||
MBitmap.InsertImage( 0, 'C:\000.tif' );
|
||
|
||
// Insert 256 x 256 bitmap
|
||
MBitmap.InsertImage(0, 256, 256, ie24RGB);
|
||
|
||
// Insert a file from the web
|
||
MBitmap.InsertImage( 0, 'http://www.imageen.com/graphics/imageen.gif' );
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBMultiBitmap.AppendImage>
|
||
- <A TIEDBMultiBitmap.SetImage>
|
||
!!}
|
||
|
||
procedure TIEDBMultiBitmap.InsertOrAppend(idx: integer);
|
||
begin
|
||
if idx >= fImageInfo.Count then
|
||
begin
|
||
// Append
|
||
fDataLink.DataSet.Append;
|
||
end
|
||
else
|
||
begin
|
||
// Insert
|
||
fDataLink.ActiveRecord := idx;
|
||
fDataLink.DataSet.Insert;
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure TIEDBMultiBitmap.InsertImage(idx: integer);
|
||
begin
|
||
LockUpdate;
|
||
try
|
||
try
|
||
InsertOrAppend( idx );
|
||
fDataLink.DataSet.Post;
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
raise;
|
||
end;
|
||
finally
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.InsertImage(Idx : integer; Stream : TStream);
|
||
begin
|
||
LockUpdate;
|
||
try
|
||
try
|
||
InsertOrAppend( idx );
|
||
SetImage( -1, Stream );
|
||
fDataLink.DataSet.Post;
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
raise;
|
||
end;
|
||
finally
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.InsertImage(Idx : integer; MBitmap : TIECustomMultiBitmap);
|
||
var
|
||
I: Integer;
|
||
bmp: TIEBitmap;
|
||
begin
|
||
LockUpdate;
|
||
try
|
||
for I := 0 to MBitmap.Count - 1 do
|
||
begin
|
||
bmp := MBitmap.GetTIEBitmap( I );
|
||
InsertImage( Idx + I, bmp );
|
||
MBitmap.ReleaseBitmap( I, False );
|
||
end;
|
||
finally
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.InsertImage(Idx : integer; Bitmap : TIEBitmap);
|
||
begin
|
||
LockUpdate;
|
||
try
|
||
try
|
||
InsertOrAppend( idx );
|
||
SetCurrentImage( Bitmap, '' );
|
||
fDataLink.DataSet.Post;
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
raise;
|
||
end;
|
||
finally
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.InsertImage(Idx : integer; Bitmap : TBitmap);
|
||
begin
|
||
LockUpdate;
|
||
try
|
||
try
|
||
InsertOrAppend( idx );
|
||
SetImage( -1, Bitmap );
|
||
fDataLink.DataSet.Post;
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
raise;
|
||
end;
|
||
finally
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.InsertImage(Idx : integer; Width, Height : integer; PixelFormat : TIEPixelFormat);
|
||
var
|
||
temp: TIEBitmap;
|
||
begin
|
||
LockUpdate;
|
||
temp := TIEBitmap.Create;
|
||
try
|
||
try
|
||
InsertOrAppend( idx );
|
||
temp.Allocate( Width, Height, PixelFormat );
|
||
temp.Fill( clBlack );
|
||
SetCurrentImage( temp, '' );
|
||
fDataLink.DataSet.Post;
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
raise;
|
||
end;
|
||
finally
|
||
temp.free;
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.InsertImage(Idx : integer; const FileName : string);
|
||
begin
|
||
LockUpdate;
|
||
try
|
||
try
|
||
InsertOrAppend( idx );
|
||
SetImage( -1, FileName );
|
||
fDataLink.DataSet.Post;
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
raise;
|
||
end;
|
||
finally
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.AppendImage
|
||
|
||
<FM>Declaration<FC>
|
||
function AppendImage: Integer;
|
||
function AppendImage(Stream: TStream): integer;
|
||
function AppendImage(Bitmap: <A TIEBitmap>): integer;
|
||
function AppendImage(Bitmap : TBitmap): integer;
|
||
function AppendImage(MBitmap : <A TIECustomMultiBitmap>);
|
||
function AppendImage(Width, Height: Integer; PixelFormat: <A TIEPixelFormat> = ie24RGB): Integer;
|
||
function AppendImage(const FileName: String): integer;
|
||
|
||
<FM>Description<FN>
|
||
Appends a new image at the end of the database and returns the new image position. The table will be positioned at the new record.
|
||
|
||
Note: TDataset.Append and TDataset.Post will be called.
|
||
|
||
<FM>Examples<FC>
|
||
if dlgOpenImage.Execute then
|
||
fDBMBitmap.AppendImage( dlgOpenImage.Filename );
|
||
|
||
// Compare the following...
|
||
ImageEnView1.IO.LoadFromFile('C:\000.tif');
|
||
MBitmap.AppendImage();
|
||
MyTable.Edit;
|
||
MBitmap.SetImage( -1, ImageEnView1.Bitmap );
|
||
MyTable.Post;
|
||
|
||
// Which is the same as...
|
||
MBitmap.AppendImage( 'C:\000.tif' );
|
||
|
||
// Append 256 x 256 bitmap
|
||
MBitmap.AppendImage( 256, 256, ie24RGB );
|
||
|
||
// Append a file from the web
|
||
MBitmap.AppendImage( 'http://www.imageen.com/graphics/imageen.gif' );
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBMultiBitmap.InsertImage>
|
||
- <A TIEDBMultiBitmap.SetImage>
|
||
!!}
|
||
function TIEDBMultiBitmap.AppendImage(): integer;
|
||
begin
|
||
result := fImageInfo.Count;
|
||
InsertImage( Result );
|
||
end;
|
||
|
||
function TIEDBMultiBitmap.AppendImage(Stream: TStream): integer;
|
||
begin
|
||
result := fImageInfo.Count;
|
||
InsertImage( Result, Stream );
|
||
end;
|
||
|
||
function TIEDBMultiBitmap.AppendImage(MBitmap: TIECustomMultiBitmap): integer;
|
||
begin
|
||
result := fImageInfo.Count;
|
||
InsertImage( Result, MBitmap );
|
||
end;
|
||
|
||
function TIEDBMultiBitmap.AppendImage(Bitmap: TIEBitmap): integer;
|
||
begin
|
||
result := fImageInfo.Count;
|
||
InsertImage( Result, Bitmap );
|
||
end;
|
||
|
||
function TIEDBMultiBitmap.AppendImage(Bitmap : TBitmap): integer;
|
||
begin
|
||
result := fImageInfo.Count;
|
||
InsertImage( Result, Bitmap );
|
||
end;
|
||
|
||
function TIEDBMultiBitmap.AppendImage(Width, Height: Integer; PixelFormat: TIEPixelFormat): Integer;
|
||
begin
|
||
result := fImageInfo.Count;
|
||
InsertImage( Result, Width, Height, PixelFormat );
|
||
end;
|
||
|
||
function TIEDBMultiBitmap.AppendImage(const FileName: String): integer;
|
||
begin
|
||
result := fImageInfo.Count;
|
||
InsertImage( Result, FileName );
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.DeleteImage
|
||
|
||
<FM>Declaration<FC>
|
||
procedure DeleteImage(idx: integer);
|
||
|
||
<FM>Description<FN>
|
||
Removes the image, <FC>idx<FN> from the database table.
|
||
|
||
<FM>Examples<FC>
|
||
// Delete the selected image in a TImageEnMView attached to a TIEDBMultiBitmap from the database
|
||
fDBMBitmap.DeleteImage( ImageEnMView1.SelectedImage );
|
||
!!}
|
||
procedure TIEDBMultiBitmap.DeleteImage(idx: integer);
|
||
var
|
||
OldActive: Integer;
|
||
begin
|
||
if ValidateIndex( idx ) = False then
|
||
exit;
|
||
|
||
OldActive := fDataLink.ActiveRecord;
|
||
try
|
||
fDataLink.ActiveRecord := idx;
|
||
fDatalink.DataSet.Delete;
|
||
finally
|
||
fDataLink.ActiveRecord := OldActive;
|
||
end;
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.SetImage
|
||
|
||
<FM>Declaration<FC>
|
||
procedure SetImage(idx: Integer; srcImage: <A TIEBaseBitmap>); overload;
|
||
procedure SetImage(idx: Integer; srcImage: TBitmap); overload;
|
||
procedure SetImage(idx: Integer; width, height: Integer; PixelFormat: <A TIEPixelFormat>); overload;
|
||
function SetImage(idx: integer; const FileName: WideString; SourceImageIndex: Integer = 0; FileFormat: <A TIOFileType> = ioUnknown): boolean; overload;
|
||
function SetImage(idx: Integer; Stream: TStream; SourceImageIndex: Integer = 0; FileFormat: <A TIOFileType> = ioUnknown): Boolean; overload
|
||
|
||
<FM>Description<FN>
|
||
Updates the current image in the database table. If images are stored in the database (i.e. <A TIEDBMultiBitmap.ImageBlobField> is set), the image will be updated in the blob. If images are stored as files referenced by the database (i.e. <A TIEDBMultiBitmap.ImageBlobField> is NOT set), the image changes will be saved to file (using <A TIEDBMultiBitmap.DefaultFilename> and <FB>without an overwrite warning<FN>).
|
||
|
||
NOTE: <FB>idx should be set to -1<FN>. Unlike TIEMultiBitmap.<A TIEMultiBitmap.SetImage>, <FC>TIEDBMultiBitmap.SetImage<FN> always works on the CURRENT database table record.
|
||
|
||
With overloads 2 and 3 the <FC>srcImage<FN> bitmap is copied internally; therefore you can free <FC>srcImage<FN> after calling SetImage.
|
||
With overload 4 the image can be a local file or web page based image.
|
||
With overloads 3 and 4 use SourceImageIndex to specify the image index if the source file is a multi-frame file (such as a TIFF or AVI). You can also specify the <FC>FileFormat<FN> if it cannot be determined by the file extension or content.
|
||
|
||
TDataset.Edit and TDataset.Post are NOT called (Unlike <A TIEDBMultiBitmap.AppendImage> and <A TIEDBMultiBitmap.InsertImage>)
|
||
|
||
<FM>Examples<FC>
|
||
ImageEnView1.IO.LoadFromFile('C:\000.tif');
|
||
MBitmap.InsertImage( 0 );
|
||
MyTable.Edit;
|
||
MBitmap.SetImage( -1, ImageEnView1.Bitmap );
|
||
MyTable.Post;
|
||
|
||
MyTable.Edit;
|
||
MyTableFilename.AsString := 'My Cool Image.jpg';
|
||
ImageEnMView1.SetImage( -1, stream );
|
||
MyTable.Post;
|
||
|
||
MyTable.Edit;
|
||
MyTableFilename.AsString := 'myfile.jpg';
|
||
ImageEnMView1.SetImage( -1, 'D:\myfile.jpg' );
|
||
MyTable.Post;
|
||
|
||
MyTable.Edit;
|
||
MyTableFilename.AsString := 'My Web Image';
|
||
ImageEnMView1.SetImage( -1, 'http://www.imageen.com/image.jpg' );
|
||
MyTable.Post;
|
||
|
||
<FM>See Also<FN>
|
||
- <A TIEDBMultiBitmap.InsertImage>
|
||
- <A TIEDBMultiBitmap.AppendImage>
|
||
- <A TIEDBMultiBitmap.DefaultFilename>
|
||
!!}
|
||
procedure TIEDBMultiBitmap.SetImage(idx: Integer; width, height: Integer; PixelFormat: TIEPixelFormat);
|
||
var
|
||
temp: TIEBitmap;
|
||
begin
|
||
if ( idx > -1 ) and ( idx <> fDataLink.ActiveRecord ) then
|
||
raise EIEException.create( Cannot_Respotion_Error_Str );
|
||
|
||
temp := TIEBitmap.Create(Width, Height, PixelFormat);
|
||
try
|
||
SetCurrentImage( temp, '' );
|
||
finally
|
||
temp.free;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.SetImage(idx: integer; srcImage: TBitmap);
|
||
var
|
||
tbmp: TIEBitmap;
|
||
begin
|
||
if ( idx > -1 ) and ( idx <> fDataLink.ActiveRecord ) then
|
||
raise EIEException.create( Cannot_Respotion_Error_Str );
|
||
|
||
if srcImage <> nil then
|
||
begin
|
||
tbmp := TIEBitmap.Create;
|
||
try
|
||
tbmp.EncapsulateTBitmap(srcImage, true);
|
||
SetCurrentImage( tbmp, '' );
|
||
finally
|
||
FreeAndNil(tbmp);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TIEDBMultiBitmap.SetImage(idx: integer; srcImage: TIEBaseBitmap);
|
||
begin
|
||
if ( idx > -1 ) and ( idx <> fDataLink.ActiveRecord ) then
|
||
raise EIEException.create( Cannot_Respotion_Error_Str );
|
||
|
||
SetCurrentImage( srcImage, '' );
|
||
end;
|
||
|
||
// Writes changes to the current image
|
||
// If images are stored in the database (i.e. TIEDBMultiBitmap.ImageBlob is set), the image will be updated in the blob.
|
||
// If images are stored as files referenced by the database (i.e. TIEDBMultiBitmap.ImageBlob is NOT set), the image changes will be saved to file (without an overwrite warning).
|
||
// sDisplayName is used as display name in the database and also a default save filename
|
||
// bCanOverwriteExisting is true only when we are updating an existing image and can replace it
|
||
procedure TIEDBMultiBitmap.SetCurrentImage(srcImage: TIEBaseBitmap; const sDisplayName: string; bCanOverwriteExisting: Boolean = False);
|
||
const
|
||
Number_Suffix_Length = 5; // a reasonable number of characters to allow for the number suffix when there are duplicate files
|
||
var
|
||
sDBFilename: string;
|
||
sSaveName: string;
|
||
sSavePath: string;
|
||
aParams: TIOParams;
|
||
sSaveFilename: String;
|
||
begin
|
||
if srcImage = nil then
|
||
exit;
|
||
|
||
aParams := nil;
|
||
try
|
||
if TIEBitmap( srcImage ).ParamsEnabled then
|
||
TIEBitmap( srcImage ).Params.JPEG_Quality := fJPEGQuality
|
||
else
|
||
begin
|
||
aParams := TIOParams.Create;
|
||
aParams.JPEG_Quality := fJPEGQuality;
|
||
end;
|
||
|
||
if fImageFormat <> ioUnknown then
|
||
fLastImageFormat := fImageFormat;
|
||
|
||
sDBFilename := '';
|
||
if fFilenameField <> nil then
|
||
sDBFilename := TStringField( fFilenameField ).AsString;
|
||
{$IFDEF UNITTESTING}
|
||
if Pos( 'XXX\', sDBFilename ) = 1 then
|
||
sDBFilename := StringReplace( sDBFilename, 'XXX\', IEAddBackSlash( gUnitTesting_ImagesPath ), []);
|
||
{$ENDIF}
|
||
|
||
// Get a name for the file
|
||
sSaveName := ExtractFilename( sDisplayName );
|
||
if sSaveName = '' then
|
||
sSaveName := ExtractFilename( sDBFilename );
|
||
if sSaveName = '' then
|
||
sSaveName := ExtractFilename( fDefaultFilename );
|
||
|
||
// And an extension
|
||
if IEFilenameToFileFormat( sSaveName ) <> fLastImageFormat then
|
||
sSaveName := ChangeFileExt( sSaveName, '.' + IEFileFormatGetInfo( fLastImageFormat ).SuitableExtension );
|
||
|
||
// Get a path
|
||
sSavePath := IEAddBackSlash( fImagePath );
|
||
if sSavePath = '' then
|
||
sSavePath := IEAddBackSlash( ExtractFilePath( fDefaultFilename ));
|
||
|
||
// Check for filenames that are too long for the field length
|
||
if ( fFilenameField <> nil ) and
|
||
(( ImageStorageMode <> isLinkedFile ) or ( fImagePath <> '' )) and // Not practical to do if we must store the full path
|
||
( Length( sSaveName ) > TStringField( fFilenameField ).Size - Number_Suffix_Length ) then
|
||
begin
|
||
sSaveName := IEExtractFilenameWithoutExt( sSaveName );
|
||
SetLength( sSaveName, TStringField( fFilenameField ).Size - Length( '.' + IEFileFormatGetInfo( fLastImageFormat ).SuitableExtension ) - Number_Suffix_Length );
|
||
sSaveName := sSaveName + '.' + IEFileFormatGetInfo( fLastImageFormat ).SuitableExtension;
|
||
end;
|
||
|
||
// Concat result
|
||
sSaveFilename := IEAddBackSlash( sSavePath ) + sSaveName;
|
||
|
||
|
||
if ImageStorageMode = isLinkedFile then
|
||
begin
|
||
// SAVE BITMAP TO FILE
|
||
|
||
if sSavePath = '' then
|
||
raise EIEException.create( 'No valid save folder' );
|
||
|
||
// Are we just updating the image???
|
||
if bCanOverwriteExisting and
|
||
( SameText( sDBFilename, sSaveFilename ) or
|
||
SameText( sDBFilename, sSaveName )) then
|
||
begin { OVERWRITE sSaveFilename } end
|
||
else
|
||
// Generate numbered filename
|
||
sSaveFilename := IEGetNewFilename( sSaveFilename );
|
||
|
||
TIEBitmap( srcImage ).Write( sSaveFilename, aParams );
|
||
end
|
||
else
|
||
begin
|
||
// BLOB
|
||
// Exception raised on error
|
||
IEBitmap_WriteToBlob( TIEBitmap( srcImage ), aParams, TBlobField( fImageBlobField ), fUseMemoryStream, fLastImageFormat );
|
||
end;
|
||
|
||
|
||
// WRITE OUR FILENAME
|
||
if fFilenameField <> nil then
|
||
begin
|
||
{$IFDEF UNITTESTING}
|
||
if ( ImageStorageMode = isLinkedFile ) and ( fImagePath = '' ) and
|
||
( pos( IEAddBackSlash( gUnitTesting_ImagesPath ), sSaveFilename ) = 1 ) then
|
||
TStringField( fFilenameField ).AsString := StringReplace( sSaveFilename, IEAddBackSlash( gUnitTesting_ImagesPath ), 'XXX\', [] )
|
||
else
|
||
{$ENDIF}
|
||
if ( ImageStorageMode = isLinkedFile ) and ( fImagePath = '' ) then
|
||
TStringField( fFilenameField ).AsString := sSaveFilename
|
||
else
|
||
TStringField( fFilenameField ).AsString := ExtractFileName( sSaveFilename );
|
||
end;
|
||
|
||
finally
|
||
FreeAndNil( aParams );
|
||
end;
|
||
|
||
// Note: Update will be called automatically due to db changes
|
||
end;
|
||
|
||
function TIEDBMultiBitmap.SetImage(idx: integer; const FileName: WideString; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean;
|
||
var
|
||
bFormatIsCorrect: Boolean;
|
||
begin
|
||
bFormatIsCorrect := True;
|
||
if fImageFormat <> ioUnknown then
|
||
bFormatIsCorrect := IEFilenameToFileFormat( FileName ) = fImageFormat;
|
||
if ( ImageStorageMode = isLinkedFile ) and // Linked images
|
||
( fImagePath <> '' ) and // Have a default save folder
|
||
SameText( IEAddBackSlash( ExtractFilePath( FileName )),
|
||
IEAddBackSlash( fImagePath )) and // Image is already in save folder
|
||
bFormatIsCorrect then // File type is as desired
|
||
begin
|
||
// File is already correct for our needs. Just update the file path in the db
|
||
if fImagePath = '' then
|
||
TStringField( fFilenameField ).AsString := FileName
|
||
else
|
||
TStringField( fFilenameField ).AsString := IEExtractFilenameW( FileName );
|
||
Result := True;
|
||
end
|
||
else
|
||
begin
|
||
// All other handling
|
||
result := SetImageFromStreamOrFile(idx, nil, FileName, SourceImageIndex, FileFormat);
|
||
end;
|
||
end;
|
||
|
||
|
||
function TIEDBMultiBitmap.SetImage(idx: integer; Stream: TStream; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean;
|
||
begin
|
||
result := SetImageFromStreamOrFile(idx, Stream, '', SourceImageIndex, FileFormat);
|
||
end;
|
||
|
||
|
||
// If loading is successful the result is the file type of the image. Othewise it returns -1 on error
|
||
function TIEDBMultiBitmap.SetImageFromStreamOrFile(idx: integer; Stream: TStream; const FileName: WideString; SourceImageIndex: Integer; FileFormat: TIOFileType; MIO: TObject = nil): Boolean;
|
||
var
|
||
bmp: TIEBitmap;
|
||
IO: TImageEnIO;
|
||
ms: TMemoryStream;
|
||
bAborting: Boolean;
|
||
FileExt: string;
|
||
begin
|
||
result := False;
|
||
if idx >= fImageInfo.Count then
|
||
exit;
|
||
if ( idx > -1 ) and ( idx <> fDataLink.ActiveRecord ) then
|
||
raise EIEException.create( Cannot_Respotion_Error_Str );
|
||
|
||
// URL HANDLING
|
||
if ( Stream = nil ) and ( IEGetURLTypeW(FileName) <> ieurlUNKNOWN ) then
|
||
begin
|
||
// LOAD FROM URL
|
||
ms := TMemoryStream.Create;
|
||
try
|
||
bAborting := False;
|
||
if IEGetFromURL(FileName, ms,
|
||
IEGlobalSettings().ProxyAddress,
|
||
IEGlobalSettings().ProxyUser,
|
||
IEGlobalSettings().ProxyPassword,
|
||
nil, nil, @bAborting, FileExt) then
|
||
begin
|
||
ms.Position := 0;
|
||
Result := SetImageFromStreamOrFile(Idx, ms, '', SourceImageIndex, FileFormat);
|
||
end;
|
||
finally
|
||
FreeAndNil(ms);
|
||
end;
|
||
exit;
|
||
end;
|
||
|
||
IO := TImageEnIO.Create( nil );
|
||
bmp := TIEBitmap.Create;
|
||
try
|
||
IO.AttachedIEBitmap := bmp;
|
||
IO.Params.ImageIndex := SourceImageIndex;
|
||
try
|
||
if Stream <> nil then
|
||
IO.LoadFromStream( Stream, FileFormat )
|
||
else
|
||
begin
|
||
if FileFormat = ioUnknown then
|
||
FileFormat := FindFileFormat( FileName, ffFallbackToExtension );
|
||
IO.LoadFromFile( FileName, FileFormat );
|
||
end;
|
||
except
|
||
IO.Aborting := true;
|
||
end;
|
||
|
||
if IO.Aborting then
|
||
exit;
|
||
|
||
// Disconnect from TImageEnIO and assign its meta-data - v6.3.1
|
||
IO.AttachedIEBitmap := nil;
|
||
bmp.ParamsEnabled := true;
|
||
bmp.Params.Assign( io.Params );
|
||
|
||
SetCurrentImage( bmp, FileName );
|
||
result := True;
|
||
|
||
finally
|
||
IO.attachediebitmap := nil;
|
||
FreeAndNil(bmp);
|
||
FreeAndNil(IO);
|
||
end;
|
||
end;
|
||
|
||
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.Flip
|
||
|
||
<FM>Declaration<FC>
|
||
procedure Flip(idx: integer; Dir: <A TFlipDir>);
|
||
|
||
<FM>Description<FN>
|
||
Flips (mirrors) a frame within the image across the horizontal or vertical axis and updates the image in the database.
|
||
|
||
<FM>Examples<FC>
|
||
// Rotate the selected image in a TImageEnMView attached to a TIEDBMultiBitmap
|
||
fDBMBitmap.Rotate( ImageEnMView1.SelectedImage, -90 );
|
||
!!}
|
||
procedure TIEDBMultiBitmap.Flip(idx: integer; Dir: TFlipDir);
|
||
var
|
||
bmp: TIEBitmap;
|
||
begin
|
||
bmp := GetTIEBitmap( idx );
|
||
bmp.Flip( Dir );
|
||
ReleaseBitmap( idx, True );
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.Rotate
|
||
|
||
<FM>Declaration<FC>
|
||
procedure Rotate(idx: integer; Angle: double; AntialiasMode: <A TIEAntialiasMode> = ierFast; BackgroundColor: TColor = clWhite);
|
||
|
||
<FM>Description<FN>
|
||
Rotates a frame of the current image by the specified angle (negative or positive degrees counter-clockwise) and updates it in the database.
|
||
|
||
<FC>AntialiasMode<FN> specifies the anti-aliasing algorithm that is used to improve rotation quality:
|
||
ierNone : No anti-aliasing (lowest quality)
|
||
ierFast : Fast but lower quality
|
||
ierBilinear : Bilinear, high quality
|
||
ierBicubic : Bicubic, highest quality
|
||
|
||
<FC>BackgroundColor<FN> specifies a background color to fill new regions (i.e. when not rotating at a 90 degree angle)
|
||
|
||
<FM>Examples<FC>
|
||
// Rotate the selected image in a TImageEnMView attached to a TIEDBMultiBitmap
|
||
fDBMBitmap.Rotate( ImageEnMView1.SelectedImage, -90 );
|
||
|
||
// Rotate the first frame of an image 45<34> clockwise at highest quality with a white background color
|
||
MBitmap.Rotate( 0, 315, ierBicubic, clWhite );
|
||
|
||
<FM>See Also<FN>
|
||
- <A AngleToImageEnRotateAngle>
|
||
!!}
|
||
procedure TIEDBMultiBitmap.Rotate(idx: integer; Angle: double; AntialiasMode: TIEAntialiasMode = ierFast; BackgroundColor: TColor = clWhite);
|
||
var
|
||
bmp: TIEBitmap;
|
||
begin
|
||
bmp := GetTIEBitmap( idx );
|
||
bmp.Rotate( Angle, AntialiasMode, BackgroundColor );
|
||
ReleaseBitmap( idx, True );
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.Resample
|
||
|
||
<FM>Declaration<FC>
|
||
procedure Resample(idx: integer; ScaleBy: Double; FilterType: <A TResampleFilter> = rfNone);
|
||
|
||
<FM>Description<FN>
|
||
Resizes a frame of the current image and updates the database. The content of the image changes (stretched to new size).
|
||
|
||
<TABLE>
|
||
<R> <H>Parameter</H> <H>Description</H> </R>
|
||
<R> <C><FC>ScaleBy<FN></C> <C>The amount to scale all images. E.g. 0.5 would halve the size of all images while respecting the proportions</C> </R>
|
||
<R> <C><FC>FilterType<FN></C> <C>Resampling interpolation algorithm</C> </R>
|
||
</TABLE>
|
||
|
||
<FM>Examples<FC>
|
||
// Halve the size of the first image in a TImageEnMView attached to a TIEDBMultiBitmap
|
||
fDBMBitmap.Resample( 0, 0.5, rfLanczos3 );
|
||
|
||
!!}
|
||
procedure TIEDBMultiBitmap.Resample(idx: integer; ScaleBy: Double; FilterType: TResampleFilter = rfNone);
|
||
var
|
||
bmp: TIEBitmap;
|
||
begin
|
||
bmp := GetTIEBitmap( idx );
|
||
bmp.Resample( ScaleBy, FilterType );
|
||
ReleaseBitmap( idx, True );
|
||
end;
|
||
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.GetTIEBitmap
|
||
|
||
<FM>Declaration<FC>
|
||
function GetTIEBitmap(idx: Integer): <A TIEBitmap>;
|
||
|
||
<FM>Description<FN>
|
||
Creates a <A TIEBitmap> object from the image at index, <FC>idx<FN>.
|
||
You will need to call <A TIEDBMultiBitmap.ReleaseBitmap> to free the <A TIEBitmap> object and optionally update the image in the database
|
||
|
||
Note: If <A TIEMultiBitmap.ParamsEnabled>=True then the returned TIEBitmap will have <A TIEBitmap.Params>.
|
||
|
||
<FM>Example<FC>
|
||
// Prompt the user to apply effects to a database image
|
||
var
|
||
bmp: TIEBitmap;
|
||
proc: TImageEnProc;
|
||
bChanged: Boolean;
|
||
begin
|
||
if ImageEnMView1.SelectedImage < 0 then
|
||
exit;
|
||
|
||
bmp := fDBMBitmap.GetTIEBitmap( ImageEnMView1.SelectedImage );
|
||
proc := TImageEnProc.CreateFromBitmap( bmp );
|
||
proc.PreviewsParams := proc.PreviewsParams + [ prppDefaultLockPreview ];
|
||
bChanged := proc.DoPreviews();
|
||
fDBMBitmap.ReleaseBitmap( ImageEnMView1.SelectedImage, bChanged );
|
||
FreeAndNil( proc );
|
||
end;
|
||
|
||
!!}
|
||
|
||
{!!
|
||
<FS>TIEDBMultiBitmap.ReleaseBitmap
|
||
|
||
<FM>Declaration<FC>
|
||
procedure ReleaseBitmap(idx: Integer; SaveChanges: Boolean);
|
||
|
||
<FM>Description<FN>
|
||
Releases the bitmap created with <A TIEMultiBitmap.GetBitmap> or <A TIEMultiBitmap.GetTIEBitmap> method.
|
||
|
||
If saveChanges then your modifications will be written to the database (TDataset.Edit/Post will be called).
|
||
|
||
<TABLE>
|
||
<R> <H>Parameter</H> <H>Description</H> </R>
|
||
<R> <C><FC>idx<FN></C> <C>The image index to release.</C> </R>
|
||
<R> <C><FC>saveChanges<FN></C> <C>If true (default), changes to the bitmap will be written to the database.</C> </R>
|
||
</TABLE>
|
||
|
||
<FM>Example<FC>
|
||
// Prompt the user to apply effects to a database image
|
||
var
|
||
bmp: TIEBitmap;
|
||
proc: TImageEnProc;
|
||
bChanged: Boolean;
|
||
begin
|
||
if ImageEnMView1.SelectedImage < 0 then
|
||
exit;
|
||
|
||
bmp := fDBMBitmap.GetTIEBitmap( ImageEnMView1.SelectedImage );
|
||
proc := TImageEnProc.CreateFromBitmap( bmp );
|
||
proc.PreviewsParams := proc.PreviewsParams + [ prppDefaultLockPreview ];
|
||
bChanged := proc.DoPreviews();
|
||
fDBMBitmap.ReleaseBitmap( ImageEnMView1.SelectedImage, bChanged );
|
||
FreeAndNil( proc );
|
||
end;
|
||
!!}
|
||
procedure TIEDBMultiBitmap.ReleaseBitmap(idx: Integer; SaveChanges: Boolean);
|
||
var
|
||
aBMP: TIEBitmap;
|
||
OldActive: Integer;
|
||
begin
|
||
OldActive := fDataLink.ActiveRecord;
|
||
LockUpdate;
|
||
try
|
||
try
|
||
if SaveChanges then
|
||
try
|
||
fDataLink.ActiveRecord := idx;
|
||
fDataLink.DataSet.Edit;
|
||
aBMP := fImageList.GetBitmap( GetImageInfo( idx ).image );
|
||
SetCurrentImage( aBMP, '', True );
|
||
fDataLink.DataSet.Post;
|
||
if assigned( fOwner ) and ( fOwner is TImageEnMView ) then
|
||
TImageEnMView( fOwner ).ClearImageCache( idx );
|
||
Changed( idx );
|
||
except
|
||
fDataLink.DataSet.Cancel;
|
||
Raise;
|
||
end;
|
||
finally
|
||
fImageList.ReleaseBitmapByImage( TIEImageInfo(fImageInfo[idx]).image, False );
|
||
end;
|
||
finally
|
||
fDataLink.ActiveRecord := OldActive;
|
||
UnlockUpdate;
|
||
end;
|
||
end;
|
||
|
||
|
||
|
||
{$endif}
|
||
|
||
|
||
{$ELSE} // {$ifdef IEINCLUDEDB}
|
||
|
||
interface
|
||
implementation
|
||
|
||
{$ENDIF}
|
||
|
||
end.
|
||
|
||
|
||
|
||
|
||
|
||
|