Daniel Halfoni
Daniel Halfoni

Reputation: 507

Why i'm getting invalid parameter exception when trying to manipulate image file ?

private void DownloadCompletedCallback(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                //... download cancelled...
            }
            else if (e.Error != null)
            {
                //... download failed...
                Logger.Write("Error: " + e.Error);
            }
            ActiveDownloadJob adJob = e.UserState as ActiveDownloadJob;
            ProgressBar pb = (adJob != null) ? adJob.ProgressBar : null;

            Image img = new Bitmap(adJob.DownloadData.TargetPath);
            Image[] frames = GetFramesFromAnimatedGIF(img);
            foreach(Image frame in frames)
            {
                frame.Save(@"c:\temp\tempframes\");
            }

            lock (_downloadQueue)
            {
                if (_downloadQueue.Count == 0)
                {
                    if (pb != null)
                    {
                        pb.Tag = null;
                        timer2.Stop();
                        timer3.Start();
                        label8.ForeColor = Color.Green;
                        label8.Text = "Process Finished";
                        mapsToolStripMenuItem.Enabled = true;
                        changeOutputDirectoryToolStripMenuItem.Enabled = true;
                        beginOperationToolStripMenuItem.Enabled = false;
                        viewDownloadedFilesToolStripMenuItem.Enabled = true;
                        Options_DB.Set_OperationLastTime(DateTime.Now.ToString());
                        playImages();
                        for (int i = 0; i < progressbars.Length; i++)
                        {
                            progressbars[i].Value = 0;
                        }
                        for (int x = 0; x < pbs.Length; x++)
                        {
                            if (x >= file_array.Length && pbs[x].Image == null)
                            {
                                pbs[x].Image = Properties.Resources.Weather_Michmoret;
                                pbs[x].Enabled = false;
                            }
                        }
                        for (int i = 0; i < file_array.Length; i++)
                        {
                            pbs[i].Animate(file_array[i]);
                            pbs[i].Enabled = true;
                            if (i == 7)
                                break;
                        }
                    }
                }
                else
                {
                    DownloadImages.DownloadData dd = _downloadQueue.Dequeue();
                    StartDownloadWithProgressBar(dd, pb);
                }
            }
        }

This is the part where i'm trying to save each frame out of animated gif:

Image img = new Bitmap(adJob.DownloadData.TargetPath);
Image[] frames = GetFramesFromAnimatedGIF(img);
foreach(Image frame in frames)
{
  frame.Save(@"c:\temp\tempframes\");
}

The first line using a breakpoint is passed fine.

Then it's getting into the method GetFramesFromAnimatedGIF

public static Image[] GetFramesFromAnimatedGIF(Image IMG)
        {
            List<Image> IMGs = new List<Image>();
            int Length = IMG.GetFrameCount(FrameDimension.Time);

            for (int i = 0; i < Length; i++)
            {
                IMG.SelectActiveFrame(FrameDimension.Time, i);
                IMGs.Add(new Bitmap(IMG));
                IMG.Dispose();
            }

            return IMGs.ToArray();
        }

I put a breakpoint on the return line: return IMGs.ToArray();

But it's not getting there in some point it's throwing exception:

System.Reflection.TargetInvocationException was unhandled
  HResult=-2146232828
  Message=Exception has been thrown by the target of an invocation.
  Source=mscorlib
  StackTrace:
       at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
       at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
       at System.Delegate.DynamicInvokeImpl(Object[] args)
       at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
       at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
       at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at WeatherMaps.Program.Main() in D:\C-Sharp\WeatherMaps\WeatherMaps\WeatherMaps\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
       HResult=-2147024809
       Message=Parameter is not valid.
       Source=System.Drawing
       StackTrace:
            at System.Drawing.Image.SelectActiveFrame(FrameDimension dimension, Int32 frameIndex)
            at WeatherMaps.Form1.GetFramesFromAnimatedGIF(Image IMG) in Form1.cs:line 904
            at WeatherMaps.Form1.DownloadCompletedCallback(Object sender, AsyncCompletedEventArgs e) in Form1.cs:line 375
            at System.Net.WebClient.OnDownloadFileCompleted(AsyncCompletedEventArgs e)
            at System.Net.WebClient.DownloadFileOperationCompleted(Object arg)
       InnerException:

Form1 line 904 is:

IMG.SelectActiveFrame(FrameDimension.Time, i);

And line 375 is:

Image[] frames = GetFramesFromAnimatedGIF(img);

I can see in the loop in the method that Length value is 10 (10 frames).

Upvotes: 0

Views: 870

Answers (1)

alexandros300
alexandros300

Reputation: 34

Have you checked the value of IMG after the first dispose call? Your dispose of the image may be the cause of it, attempting an invocation of a now invalid object (not an expert on the FrameDimension class, though I am assuming it is created based on the IMG object, since I do not see an explicit instance of it being created after a very quick skim)

Upvotes: 1

Related Questions