ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Clearing/Blanking Out a TImageEnVect

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
Elemental Posted - Mar 26 2014 : 15:46:17
I have a TImageEnMView "connected" to a TImageEnVect component. When the user goes to various pages, I call the following method, where Number is an Integer and has already been checked for a valid range:


ImageEnVect1.SetExternalBitmap( ImageEnMView1.GetTIEBitmap( Number ) );
ImageEnVect1.Fit;


The problem is that there is no method I can call which blanks out the TImageEnVect component. I've tried Blank, Clear, Update, Refresh, Invalidate, Assign(nil), SetExternalBitmap(nil), IO.Update, Paint, etc. and all of them either leave the image as it was OR result in an Exception. If I stretch the form just a bit, then the last image finally goes away, but I don't want to require my users to do that. They must believe that the image is gone.

Here is a test form unit:

THE DFM

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 645
  ClientWidth = 527
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  DesignSize = (
    527
    645)
  PixelsPerInch = 96
  TextHeight = 13
  object ImageEnVect1: TImageEnVect
    Left = 8
    Top = 167
    Width = 511
    Height = 470
    Background = clBtnFace
    ParentCtl3D = False
    MouseInteract = [miSelectZoom]
    Anchors = [akLeft, akTop, akRight, akBottom]
    EnableInteractionHints = True
    TabOrder = 0
  end
  object ImageEnMView1: TImageEnMView
    Left = 6
    Top = 39
    Width = 513
    Height = 122
    Background = clBtnFace
    ParentCtl3D = False
    StoreType = ietNormal
    ThumbWidth = 100
    ThumbHeight = 100
    HorizBorder = 4
    VertBorder = 4
    TextMargin = 0
    OnImageSelect = ImageEnMView1ImageSelect
    GridWidth = 0
    Style = iemsACD
    ThumbnailsBackground = clBtnFace
    ThumbnailsBackgroundSelected = clBtnFace
    MultiSelectionOptions = []
    ThumbnailsBorderWidth = 0
    TabOrder = 1
  end
  object Button1: TButton
    Left = 8
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Load'
    TabOrder = 2
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 88
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Flip Image'
    TabOrder = 3
    OnClick = Button2Click
  end
  object Button3: TButton
    Left = 168
    Top = 8
    Width = 75
    Height = 25
    Caption = 'Clear'
    TabOrder = 4
    OnClick = Button3Click
  end
end


THE PAS
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, iemview, imageenview, ieview, ievect;

type
  TForm1 = class(TForm)
    ImageEnVect1: TImageEnVect;
    ImageEnMView1: TImageEnMView;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure ImageEnMView1ImageSelect(Sender: TObject; idx: Integer);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  hyiedefs;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ImageEnMView1.MIO.LoadFromFileTIFF( 'D:\Pictures\Scans\300dpi\Papers Type 9_15.tif' );
  ImageEnMView1.SelectedImage := 0;
  ImageEnMView1ImageSelect( ImageEnMView1, 0 );
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ImageEnVect1.Proc.Flip( fdHorizontal );
  ImageEnMView1.UpdateImage( ImageEnMView1.SelectedImage );
end;

procedure TForm1.Button3Click(Sender: TObject);
//var
//  EmptyPic: TBitmap;
begin
  ImageEnMView1.Clear;
//  None of the following methods actually blank out the control without an error
//  ImageEnVect1.Blank;
  ImageEnVect1.Clear;
//  ImageEnVect1.Update;
//  ImageEnVect1.Refresh;
//  ImageEnVect1.Invalidate;
//  ImageEnVect1.IO.Update;
//  ImageEnVect1.Paint;
//  EmptyPic := TBitmap.Create;
//  try
//    EmptyPic.Height := 1;
//    EmptyPic.Width := 1;
//    ImageEnVect1.Assign( Bitmap );
//    ImageEnVect1.Update;
//  finally
//    EmptyPic.Free;
//  end;
end;

procedure TForm1.ImageEnMView1ImageSelect(Sender: TObject; idx: Integer);
begin
  ImageEnVect1.SetExternalBitmap( ImageEnMView1.GetTIEBitmap( idx ) );
  ImageEnVect1.Fit;
end;

end.


"Roj"
4   L A T E S T    R E P L I E S    (Newest First)
Elemental Posted - Mar 27 2014 : 11:08:04
William,

Thank you for your extended post. I appreciate the time and effort it took to verbalize what you know about the random questions I asked.

I've learned what kind of learner I am and the kind of learning that empowers me most is generally the most expensive. I don't learn as much by looking at demos, nor by reading the help file, or reading a book on the subject. I, personally, am a better learner when under the tutelage of an instructor, and in our Delphi world, those are just hard to come by and expensive to pay.

But like others, I learn a lot by trial and error, question and answer, so that's what I have to fall back on. But it's a better use of my time if I can be personally be taught by a teacher.

"Roj"
w2m Posted - Mar 27 2014 : 10:09:13
The way I learned ImageEn was by studying... not just reading the help file, trial and error, asking for help from the developer and by studying the source code in the demos.

Maybe I can help a little with some of your questions:

1. I don't know when to use a TBitmap or TIEBitmap?
The help file can assist you here... TIEBitmap is a replacement for the VCL TBitmap class. It has many methods and properties compatible with TBitmap and enhances it by supporting multi-threading, large images and a wide range of image formats.

TIEBitmap can store images in memory mapped files (for big images), in memory (fast access) or can encapsulate TBitmap objects (for canvas drawing and compatibility).

Generally speaking I always try to use TIEBitmap if possible, but sometimes you need to access the TBitmap, when it is needed for a function call for example. Use of TIEBitmap with a Win64 compile is the best way to minimize memory problems by using the extra memory available to ImageEn with 64-bit operating systems. More memory is available this way. Win32 applications can access only about 4GB of ram. Win64 can access memory above 4GB. Note: to compile as 64-bit, you need to add the ielib64.dll to the applications folder.

2. It would help to know more about the logical structure of the whole ImageEn system, in a graphical way and which methods are used to communicate between them.

I would not even know how to depict some of this graphically. There are some graphics in the help file... The help file and the comments in the source code are your best friend. I find that many of the questions asked in the forum can be answered from the help file... not all, but most. There is not a day that goes by when I do not use the help file... use it... especially before you ask a question in the forum.

3. With respect to Get and Set... study the help file.

4. With respect to SetExternalBitmap and SetNavigator... only call one time to share the image among two single frame components like TImageEnView and TImageEnVect. Do not use this with multi-frame components like TImageEnMView. Generally speaking I do not use these two methods based on my own style of coding except in special circumstances. I prefer to assign images from one component to another or to use streams for this so I have total control by code on what happens and when.

5. How is it possible to call ReleaseBitmap on a TImageEnMView, and yet the component still shows an image in that spot? Don't all viewing components display bitmaps and freeing them would cause it to go away?

Generally speaking you are correct. When you free and object it is destroyed and the image is not longer accessible from the destroyed object. But in the case of ImageEnMView GetTIEBitmap creates a temporary TIEBitmap to hold the image. When you call ReleaseBitmap the temporary TIEBitmap object is destroyed not the frame in the ImageEnMView. When you call ImageEnVect1.IEBitmap.Assign(ImageEnMView1.GetTIEBitmap(idx)) the image is assigned to the TImageEnVect, so when the TIEBitmap is destroyed it still is in memory in the TImageEnVect.

6. I use FastMM4...
While FastMM4 is better than nothing... try using MadExcept (Free for non commercial use) or EurekaLog (commercial, but inexpensive). I have both... These are much better than FAssMM4 and provide a lot more capability because they can take toy to the spot in your code where memory was leaked.

I hope this helps... good luck with ImageEn... The best vcl imaging system available for Delphi.


William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Custom ImageEn Development
Elemental Posted - Mar 27 2014 : 08:32:39
The code you posted works great! Thank you! No reply to this post is needed, but I do have some things to add as feedback.

As a client developer of these components, it has been a most difficult task finding the right properties to perform activities across multiple ImageEn components. I don't know when to use a Bitmap or IEBitmap property, or when to use a TBitmap or TIEBitMap object. I don't know when to use a Set* method of an object, or the Assign procedure of an object. When I create an object and send it to an ImageEn method, I don't know if the components become the owner or if I must free it myself. It would help to know more about the logical structure of the whole ImageEn system, in a graphical way and which methods are used to communicate between them. Even though I bought the source code, it's still difficult to graphically picture how things fit together. Like, how is it possible to call ReleaseBitmap on a TImageEnMView, and yet the component still shows an image in that spot? Don't all viewing components display bitmaps and freeing them would cause it to go away?

Using the SetIEBitmap procedure was a surprise to me, since an example in the FAQ shows using the Assign procedure between two ImageEn components (a TImageEnMView and a TImageEnView).

My project also uses FastMM4 as the first unit in the .dpr, and it never complained that I didn't free objects of type TBitmap, TIEBitmap, or any other classes for that matter, even though I was calling GetTIEBitmap several times.

Anyway, I still think it's a great product and have enjoyed playing with it while I make my application.

"Roj"
w2m Posted - Mar 26 2014 : 16:47:16
There are quite a few problems with your application. You are doing a few things incorrectly with respect to getting an image from ImageEnMView and displaying the selected image in ImageEnVect. Also SetExternalBitmap should not be used with ImageEnMView. Also by not calling ReleaseBitmap after calling ImageEnMView1.GetTIEBitmap(idx) there is large a memory leak each time you select an image.

SetExternalBitmap allows you to connect one TImageEnView component to another one and share the same bitmap. This is useful to view the same image with multiple TImageEnView components, but loading the image only once. It is generally called in FormCreate one time. ... you are calling it a number of times each time an image is selected in TImageEnMView.

To display the selected image in ImageEnVect you should call TImageEnMView.GetTIEBitmap and assign the TIEBitmap to TImageEnVect and then free the TIEBitmap with TImageEnMView.ReleaseBitmap.
procedure TForm1.ImageEnMView1ImageSelect(Sender: TObject; idx: Integer);
{ Get the selected image in TImageEnMView and display it in TImageEnVect; }
begin
  { Create a TIEBitmap object from the image at index and assign it to TImageEnVect }
  ImageEnVect1.IEBitmap.Assign(ImageEnMView1.GetTIEBitmap(idx));
  ImageEnVect1.Update;
  { Release the bitmap created with TImageEnMView.GetTIEBitmap }
  ImageEnMView1.ReleaseBitmap(idx);
  { If you do not release the bitmap after calling GetTIEBitmap there will be a
    large memory leak. }
  ImageEnVect1.Fit;
end;

To load TImageEnMView and select the first image and display it in TImageEnVect
procedure TForm1.Load1Click(Sender: TObject);
{ Load a file into TImageEnMView, select the first image and display the
  selected image in TImageEnVect. }
begin
  if OpenPictureDialog1.Execute then
  begin
    ImageEnMView1.MIO.LoadFromFile(OpenPictureDialog1.FileName);
    ImageEnMView1.SelectedImage := 0;
    ImageEnVect1.IEBitmap.Assign(ImageEnMView1.GetTIEBitmap(0));
    ImageEnVect1.Update;
    ImageEnMView1.ReleaseBitmap(0);
  end;
end;

To update a image in TImageEnMView after modifying it in TImageEnVect...
procedure TForm1.FlipImage1Click(Sender: TObject);
{ Flip the image and replace the TImageEnMView selected image with the flipped
  image. }
begin
  ImageEnVect1.Proc.Flip(fdHorizontal);
  ImageEnMView1.SetIEBitmap(ImageEnMView1.SelectedImage, ImageEnVect1.IEBitmap);
  ImageEnMView1.UpdateImage(ImageEnMView1.SelectedImage);
end;

To clear just call clear with out using SetExternalBitmap:
procedure TForm1.Clear1Click(Sender: TObject);
begin
  ImageEnMView1.Clear;
  ImageEnVect1.Clear;
end;

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Custom ImageEn Development