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
 want to run nested loop in thread its running but

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
vivekhada Posted - Jan 16 2020 : 08:15:45
want to run nested loop in thread its running but when we will select multiple images its getting stucked and memory overload issue coming also sometime after application closed getting access voilation error


please help in below code

procedure test.Execute;

  var
  pathis,Selected,pathimodelname,pathi,path : string;
  topwid,tophid,iSelIndex,indexofmview,faf, i,j: Integer;
  selList: TIEArrayOfInteger;
  foldername: string;

begin


  Form1.ImageEnMView1.MultiSelectedImagesAutoSort := False;
  Form1.ImageEnMView2.MultiSelectedImagesAutoSort := False;
   Form1.ImageEnView1.ClearAll;
// ProgressBar1.Min := 0;
  //      ProgressBar1.Max := ListBox1.Items.Count - 1;
//        ProgressBar1.Position := 0;
  try
          begin
          try
          Form1.ProgressBar2.Min := i;
          Form1.ProgressBar2.Max := Form1.ImageEnMView2.ImageCount;
          Form1.ProgressBar2.Position := 0;
          Form1.ProgressBar2.Step := 1;
          finally

          end;
          end;

           begin
           try
          Form1.ProgressBar1.Min := j;
          Form1.ProgressBar1.Max := Form1.ImageEnMView1.ImageCount;
          Form1.ProgressBar1.Position := 0;
          Form1.ProgressBar1.Step := 1;
           finally

           end;
          end;



       begin

       for j := 0 to Form1.ImageEnMView1.ImageCount - 1 do

         if  Form1.ImageEnMView1.Checked[j] then
         begin
            Form1.ImageEnView1.ClearAll;
            //Form1.ImageEnView1.LayersInsert(0,Form1.ImageEnMView1.ImageFileName[j],0,0);
            Form1.ImageEnView1.Fit(True);
            Form1.ImageEnView1.Update;
  //ShowMessage(Form1.ImageEnMView1.ImageFileName[j]);

            begin

                  try
                  Form1.ImageEnView1.LayersInsert(0,Form1.ImageEnMView1.ImageFileName[j],0,0);
                  pathimodelname := ( TPath.GetFileNameWithoutExtension(Form1.ImageEnMView1.ImageFileName[j]));
                   begin
                   Form1.ProgressBar1.StepIt;
                   Form1.ProgressBar1.Update;
                   end;
        //ShowMessage(pathimodelname);
                  begin
                    if not TDirectory.Exists(Form1.edit2.Text+'\'+pathimodelname) then
                    TDirectory.CreateDirectory(Form1.edit2.Text+'\'+pathimodelname);
                    foldername := (Form1.edit2.Text+'\'+pathimodelname+'\');
        //ShowMessage('pathfoldername'+' '+foldername);
                  end;
                  topwid:= Form1.ImageEnView1.CurrentLayer.Width;
                  tophid:= Form1.ImageEnView1.CurrentLayer.Height;
                  Form1.ImageEnView1.CurrentLayer.Name := 'top';
                  Form1.ImageEnView1.Fit(True);
                  Form1.ImageEnView1.Update;
                  finally

                  end;

              begin
            for i := 0 to Form1.ImageEnMView2.ImageCount - 1 do

                   //if Form1.ImageEnMView1.IsSelected(i) then
                     if  Form1.ImageEnMView2.Checked[i] then
                     begin

                            //iSelIndex := Form1.ImageEnMView1.MultiSelectedImages[ i ];
                      //Form1.ImageEnView1.LayersInsert(0,Form1.ImageEnMView1.ImageFileName[i],0,0);
                      //Form1.ImageEnView1.LayersInsert(1,Form1.ImageEnMView2.ImageFileName[i],0,0);
                      //Form1.ImageEnView1.LayersRemove(1);
                      //Form1.ImageEnView1.IO.LoadFromFile(Form1.ImageEnMView2.ImageFileName[i]);
                      Form1.ImageEnView1.LayersAdd( Form1.ImageEnMView2.ImageFileName[i],0,0 );
                       Form1.ImageEnView1.CurrentLayer.Width := topwid;
                       Form1.ImageEnView1.CurrentLayer.Height := tophid;
                     pathi := ( TPath.GetFileNameWithoutExtension(Form1.ImageEnMView2.ImageFileName[i]));
          //ShowMessage(pathi);
                          {without folder name}
                         //pathis := ( Form1.edit2.Text+'\'+pathi+' '+pathimodelname+'.png');
                         {with folder name}
                         pathis := ( foldername+'\'+pathi+' '+pathimodelname+'.png');
          //ShowMessage(pathis);


         //ShowMessage(pathi);
                      //Form1.ImageEnView1.LayersInsert(1, Form1.ImageEnMView2.ImageFileName[i],0,0 );

                      Form1.ImageEnView1.LayersArrange( LYR_SELECTED_LAYERS, 0 );
                      begin
                       Form1.ImageEnView1.LayersSaveMergedTo(pathis);
                      {
                        Form1.SaveImageEnDialog1.FileNameW := pathi+pathimodelname;
                      if Form1.SaveImageEnDialog1.Execute then
                          begin
                          //Form1.ImageEnView1.LayersSaveMergedTo(Form1.SaveImageEnDialog1.FileName);
                          Form1.ImageEnView1.IO.SaveToFile(pathi,ioJPEG);
                          end;
                          }
                      end;



                      Form1.ImageEnView1.LayersRemove(LYR_SELECTED_LAYERS);
                      //Form1.ImageEnView1.IO.LoadFromFile(Form1.ImageEnMView2.ImageFileName[i]);
         //ShowMessage(Form1.ImageEnMView2.ImageFileName[i]);
                                  Form1.ImageEnView1.Update;

                        Form1.ImageEnView1.Fit(True);
                                    Form1.ImageEnView1.Update;


            //ShowMessage(Form1.ImageEnMView1.ImageFileName[j]);
                        Form1.ProgressBar2.StepIt;
                        Form1.ProgressBar2.Update;

                      end;
              end;
            end;
         //ShowMessage(Form1.ImageEnMView2.ImageFileName[j]);


        end;

       end;
  finally

          begin
          try
            ShowFolder( Form1.edit2.Text);
            test.Sleep(0);
            test.SpinWait(0);



          finally
                Free;
           Form1.ProgressBar1.Free;
           Form1.ProgressBar2.Free;

          end;
          end;
  end;



             Free;

  end;




//above is thread procedure


/////////////////////////////

mentioned after

  private
    { Private declarations }
    
  public
    { Public declarations }
    
  end;


test = class (TThread)
     protected
      procedure Execute; override;
      end;



//////////////////////////



with test.Create do
FreeOnTerminate := True;


3   L A T E S T    R E P L I E S    (Newest First)
whisper1980 Posted - Jan 20 2020 : 21:53:43
I had the same access violation and list index -1 issue in my for loop in a thread, which creates and populates thumbnails, and closing the application or terminating the thread prematurely.

To fix, within the for loop and just before I used the loop variable "i" I made this check where fReportImageList is a local thread variable referencing the actual image list in the main form:
if (fReportImageList = nil) or (i > fReportImageList.Count-1) then exit;

The main form can free up the image list before the thread fully terminates or the terminated property was set after I checked for it in the loop. It was easy to reproduce by forcing a terminate and restart of the thread over and over. This one check mentioned above fixed it... there may be a more elegant way to do it though.

My full loop looks like this. I use Synchronize since I am referencing VCL controls that are in use in the main form as well and not thread safe. It might be a bit confusing since I cache four different thumbnail sizes. And once I load a local variable with the image of the size I want, I make sure it didn't suddenly become nil. The property to get a particular Thumbnail size image will also create the thumbnail in the getter not shown here, so this loop is pretty much just populating an image list in the main form. I don't use ImageEn's image list controls for this because of some usability things that didn't fit what I needed it to do, so instead I populate a TImageList and TListView. Maybe this example will help in some way.

procedure TImagePanelThread.LoadImages();
var
  i, iListIndex: Integer;
  vListItem: TListItem;
  vThumbnailImage: TMemoryStream;
begin
  Synchronize(
    procedure
    begin
      fListView.Clear;
      fImageList.Clear;
    end
  );

  for i := 0 to fReportImageList.Count-1 do
  begin
    if Self.Terminated then exit;
    try
      Synchronize(
        procedure
        begin
          if (fReportImageList = nil) or (i > fReportImageList.Count-1) then exit;
          case fImageList.Width of
            Integer(tsSmall):   vThumbnailImage := fReportImageList[i].Thumbnail.ThumbSmall;
            Integer(tsMedium):  vThumbnailImage := fReportImageList[i].Thumbnail.ThumbMedium;
            Integer(tsLarge):   vThumbnailImage := fReportImageList[i].Thumbnail.ThumbLarge;
            Integer(tsXLarge):  vThumbnailImage := fReportImageList[i].Thumbnail.ThumbXLarge;
          else
            exit;
          end;
        end
      );
    except
      if Self.Terminated then exit;
      continue;
    end;
    if (vThumbnailImage = nil) or (vThumbnailImage.Size = 0) then exit;

    if Self.Terminated then exit;
    try
      Synchronize(
        procedure
        var
          vBitmap, vThumbnail: TBitmap;
        begin
          vBitmap := TBitmap.Create;
          try
            vBitmap.LoadFromStream(vThumbnailImage);
            vThumbnailImage.Position := 0;
            vThumbnail := TBitmap.Create;
            try
              vThumbnail.Width := fImageList.Width;
              vThumbnail.Height := fImageList.Height;
              vThumbnail.Canvas.Brush.Style := bsSolid;
              vThumbnail.Canvas.Brush.Color := fListView.Color;
              vThumbnail.Canvas.FillRect(Rect(0, 0, vThumbnail.Width, vThumbnail.Height));
              vThumbnail.Canvas.Draw(0, (fImageList.Height - vBitmap.Height) div 2, vBitmap);
              iListIndex := fImageList.Add(vThumbnail, nil);
            finally
              FreeAndNil(vThumbnail);
            end;
          finally
            FreeAndNil(vBitmap);
          end;
        end
      );
    except
      if Self.Terminated then exit;
      continue;
    end;

    if Self.Terminated then exit;
    try
      Synchronize(
        procedure
        begin
          vListItem := fListView.Items.Add;
          vListItem.Caption := fReportImageList[i].Name;
          vListItem.ImageIndex := iListIndex;
        end
      );
    except
      if Self.Terminated then exit;
      continue;
    end;

    if Self.Terminated then exit;
  end;
end;


Eric
vivekhada Posted - Jan 17 2020 : 03:53:37
access voilation error after closing application
and list index -1 error sometime during run application

i am rendering images to create image watermark in nested loop

like watermark from imageenmview1


and images from imagenmview 2

like this want to fit images (imagenmview 2) below to watermark ( imageenmview1) in nested loop with thread
xequte Posted - Jan 16 2020 : 15:51:43
Hi

I can't see anything particular in the code that might be causing an error. Does the error only occur when it is run in a thread? Are you able to eliminate code till you find the cause?

Nigel
Xequte Software
www.imageen.com