none
Image doesn't show anything

    Question

  • Hi, in my WPF application, there is a list of PDF documents. There is a FileSystemWatcher looking for new PDF documents appearing in a directory. When a new PDF file appears, a I generate a thumbnail and add a new item to the list. The problem is that I cannot make the image display the thumbnail. I tried two approaches:

    1. I use QuickPDFLibrary to extract a page as image and to save it to a file in PNG format. Then I read create a BitmapSource object that is returned from the method. It is set afterwards as the source of the list item's image.

    public BitmapSource preview(int pageNumber)
    {
      BitmapDecoder decoder;
      BitmapFrame bitmapSource = null;
      string thumbnailFile = Environment.GetEnvironmentVariable("TEMP") + "\\" + documentHandle.ToString() + ".png";
      FileStream fileStream = null;
    
      // save the page as a PNG to the thumbnailFile
      // .....
    
      // At this point, the image is saved in the file. When I open it, it looks fine. 
    
      // Following code section is taken from MSDN: http://msdn.microsoft.com/en-us/library/ms602497.aspx
      try
      {
        fileStream = new FileStream(thumbnailFile, FileMode.Open, FileAccess.Read, FileShare.Read);
        decoder = new PngBitmapDecoder(fileStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
        
        bitmapSource = decoder.Frames[0];
        return bitmapSource;
      }
      finally
      {
        if (fileStream != null)
        fileStream.Close();
      }
    }
    
    

    Everything is fine until the returned value is set as the image's source. At that moment, a COM exception is raised:

    System.Runtime.InteropServices.COMException was unhandled
      Message=The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))
      Source=PresentationCore
      ErrorCode=-2147024890
      StackTrace:
           at System.Windows.Media.Imaging.BitmapSource.get_DUCECompatibleMILPtr()
           at System.Windows.Media.Imaging.BitmapSource.UpdateBitmapSourceResource(Channel channel, Boolean skipOnChannelCheck)
           at System.Windows.Media.Imaging.BitmapSource.UpdateResource(Channel channel, Boolean skipOnChannelCheck)
           at System.Windows.Media.Imaging.BitmapSource.AddRefOnChannelCore(Channel channel)
           at System.Windows.Media.Imaging.BitmapSource.System.Windows.Media.Composition.DUCE.IResource.AddRefOnChannel(Channel channel)
           at System.Windows.Media.RenderData.System.Windows.Media.Composition.DUCE.IResource.AddRefOnChannel(Channel channel)
           at System.Windows.UIElement.RenderContent(RenderContext ctx, Boolean isOnChannel)
           at System.Windows.Media.Visual.UpdateContent(RenderContext ctx, VisualProxyFlags flags, Boolean isOnChannel)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)
           at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
           at System.Windows.Media.Visual.Render(RenderContext ctx, UInt32 childIndex)
           at System.Windows.Media.CompositionTarget.Compile(Channel channel)
           at System.Windows.Media.CompositionTarget.System.Windows.Media.ICompositionTarget.Render(Boolean inResize, Channel channel)
           at System.Windows.Media.MediaContext.Render(ICompositionTarget resizedCompositionTarget)
           at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
           at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
           at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
           at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
           at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
           at System.Windows.Threading.DispatcherOperation.InvokeImpl()
           at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
           at System.Threading.ExecutionContext.runTryCode(Object userData)
           at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Windows.Threading.DispatcherOperation.Invoke()
           at System.Windows.Threading.Dispatcher.ProcessQueue()
           at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
           at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
           at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
           at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
           at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
           at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
           at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
           at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
           at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
           at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
           at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
           at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
           at System.Windows.Threading.Dispatcher.Run()
           at System.Windows.Application.RunDispatcher(Object ignore)
           at System.Windows.Application.RunInternal(Window window)
           at System.Windows.Application.Run(Window window)
           at System.Windows.Application.Run()
           at Ubit.ScanBox.UI.App.Main() in D:\Workspace\Visual Studio\AfI\ScanBox\GUI\obj\Debug\App.g.cs:line 0
           at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
           at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
           at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
           at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
           at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
           at System.Activator.CreateInstance(ActivationContext activationContext)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException:

     

    2. I have also tried the following. No COM exception was raised, but it looks as if the image's source was set to null:

    string thumbnailFile = Environment.GetEnvironmentVariable("TEMP") + "\\" + documentHandle.ToString() + ".png";
    FileStream fileStream = null;
    Image pdfBitmap = null;
    MemoryStream pngStream = null;
    BitmapDecoder decoder = null;
    BitmapFrame bitmapSource = null;
    
    try
    {
      fileStream = new FileStream(thumbnailFile, FileMode.Open, FileAccess.Read);
      pdfBitmap = Image.FromStream(fileStream, true);
      pngStream = new MemoryStream();
      pdfBitmap.Save(pngStream, ImageFormat.Png);
      decoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
      bitmapSource = decoder.Frames[0];
    }
    finally
    {
      if (fileStream != null)
        fileStream.Close();
    
      if (pngStream!= null)
        pngStream.Close();
    }
    
    Does anybody know what's going on? Thanks in advance.

    Monday, September 27, 2010 10:28 AM

Answers

  • Hello,

    I think you don't need to do image decoding by yourself. We can use the build-in method to do that.

    BitmapImage bi = new BitmapImage();
    bi.BeginInit();
    bi.UriSource = new Uri(@"D:\path.jpg",UriKind.Absolute);
    bi.EndInit();
    return bi;

     

    Hope this helps.


    Yiling Lai. MVP (Visual C++ and Client App Dev)
    • Marked as answer by robinto Tuesday, September 28, 2010 7:09 AM
    Monday, September 27, 2010 11:09 AM

All replies

  • Hello,

    I think you don't need to do image decoding by yourself. We can use the build-in method to do that.

    BitmapImage bi = new BitmapImage();
    bi.BeginInit();
    bi.UriSource = new Uri(@"D:\path.jpg",UriKind.Absolute);
    bi.EndInit();
    return bi;

     

    Hope this helps.


    Yiling Lai. MVP (Visual C++ and Client App Dev)
    • Marked as answer by robinto Tuesday, September 28, 2010 7:09 AM
    Monday, September 27, 2010 11:09 AM
  • Hello again,

    the problem is that I don't want to store the images on disk. Recently, I've managed to avoid writing the image to a file and to send it to the decoder via a memory stream. By chance I found a way to avoid the error. I wanted to ensure that the ImageSource contains correct data, so after assigning the decoder.Frames[0] to it, I saved its contents to a file. Et voila, it works! I don't understand at all what's going on here - there are many threads, COM objects, etc., maybe this could have something to do with it. I tried to suspend the thread for a while or add some empty loops to the code to give the OS some time but nothing worked except writing the image data to the disk. I will appreciate any explanation.

    Thank you

    Monday, September 27, 2010 2:38 PM
  • If I remember correctly, the image isn't loaded directly into memory as soon as the object is created. So when you close the stream after creating the image, there is a chance that the underlying stream hadn't been read completely yet.

    Try unloading the bitmap while your form is closing, or when you replace tit with a new image, but not directly after loading it.

    Also I think that Yiling is correct in that you don't need to decode any further, you can just use Image.FromStream static method to load the image directly without having to specify a specific encoder or decoder and without having to save it again as a png. But in that part I'm guessing :).

    Monday, September 27, 2010 3:14 PM
  • Thanks guys, you helped me a lot.
    Tuesday, September 28, 2010 7:10 AM