Dirk Vollmar
Dirk Vollmar

Reputation: 176239

How to convert IPictureDisp to System.Drawing.Image

From a COM library (Microsoft Office Document Imaging aka MODI) I receive an image as an IPictureDisp which I would like to convert to a System.Drawing.Image object.

What would be the best way to do that?

Currently I'm using the code below, which however throws an NotImplementedException.

internal sealed class IPictureDispHost : AxHost
{
    /// <summary>
    /// Default Constructor, required by the framework.
    /// </summary>
    private IPictureDispHost() : base(string.Empty) { }
    /// <summary>
    /// Convert the image to an ipicturedisp.
    /// </summary>
    /// <param name="image">The image instance</param>
    /// <returns>The picture dispatch object.</returns>
    public new static object GetIPictureDispFromPicture(Image image)
    {
        return AxHost.GetIPictureDispFromPicture(image);
    }
    /// <summary>
    /// Convert the dispatch interface into an image object.
    /// </summary>
    /// <param name="picture">The picture interface</param>
    /// <returns>An image instance.</returns>
    public new static Image GetPictureFromIPicture(object picture)
    {
        return AxHost.GetPictureFromIPicture(picture);
    }
}

...

// somewhere later the conversion gets called
Image image = IPictureDispHost.GetPictureFromIPicture(picture);

This is the exception stack trace:

System.NotImplementedException: The method or operation is not implemented.
   at System.Windows.Forms.UnsafeNativeMethods.IPicture.GetHandle()
   at System.Windows.Forms.AxHost.GetPictureFromIPicture(Object picture)
   at DocumentViewer.IPictureDispHost.GetPictureFromIPicture(Object picture)

I have references to stdole, System.Windows.Forms and System.Drawing in my project. Am I missing something?

Upvotes: 5

Views: 14925

Answers (5)

Ama
Ama

Reputation: 1575

Function GetImage(MyIPicture As stdole.IPictureDisp) As Drawing.Image
    If CType(MyIPicture.Type, Integer) <> 1 then Throw New ArgumentException("Image not supported")
    Return Drawing.Image.FromHbitmap(MyIPicture.Handle, MyIPicture.hPal)
End Function

Inspired from this post in the MSDN Forum. No idea why the CType(MyIPicture.Type, Integer) = 1 is required, but it works..

Upvotes: 3

petr k.
petr k.

Reputation: 8110

Check out this article.

It describes three different options to take, just pick the one you find easiest or "cleanest" for your purposes (including the one you claim not to be working for you).


Olivier Jacot-Descombes: The link above is broken. I've added the corresponding link from the Internet Archive WayBackMachine:

Converting between IPictureDisp and System.Drawing.Image (MSDN Blogs > Andrew Whitechapel).

Upvotes: 5

George
George

Reputation:

Microsoft.VisualBasic.Compatibility.VB6.Support.IPictureDispToImage is not guaranteed to always be included in future updates. So... taking the example from http://support.microsoft.com/kb/555417 I came up with the following

Example

Public Class ImageToPictureDispConverter

Inherits System.Windows.Forms.AxHost

Public Sub New()
    MyBase.New("{63109182-966B-4e3c-A8B2-8BC4A88D221C}")
End Sub

Public Function GetImageFromIPictureDisp(ByVal objImage As stdole.IPictureDisp) As System.Drawing.Image
    Dim objPicture As System.Drawing.Image
    objPicture = CType(MyBase.GetPictureFromIPicture(objImage), System.Drawing.Image)

    Return objPicture
End Function

End Class

I see in your constructor that you pass an empty string. I ended up having to pass the following string "{63109182-966B-4e3c-A8B2-8BC4A88D221C}". If I passed an empty string I received a system.formatexception error. It looks like you have everything I have except for this string in your call to base.

Hope this helps.

Upvotes: 0

Dirk Vollmar
Dirk Vollmar

Reputation: 176239

As it seems the picture obtained from the Microsoft Office Document Imaging COM components is not a valid IPictureDisp object and there seems no way to convert it.

Upvotes: 2

John K&#228;ll&#233;n
John K&#228;ll&#233;n

Reputation: 7973

Have you tried:

picture1.image = Microsoft.VisualBasic.Compatibility.VB6.Support.IPictureDispToImage(pict)

Upvotes: 0

Related Questions