DwgThumbnail

DwgThumbnail

Jedimaster
Collaborator Collaborator
6,549 Views
11 Replies
Message 1 of 12

DwgThumbnail

Jedimaster
Collaborator
Collaborator

I am using MSVS 2012 Pro with ObjectArx 2015, I am trying to convert a VBA routine to VB .NET. I have Windows form with the AutoCAD Dwg Thumbnail Control. When I compile I get an error "error BC30203: Identifier expected.  COM Reference 'DWGTHUMBNAILLib' is the interop assembly for ActiveX control 'AxDWGTHUMBNAILLib' but was marked to be linked by the compiler with the /link flag. This COM reference will be treated as a reference and will not be linked."

 

Thanks in advace for any help or insight.

0 Likes
Accepted solutions (1)
6,550 Views
11 Replies
Replies (11)
Message 2 of 12

norman.yuan
Mentor
Mentor

It is almost certain that the DwgThumbnail control you used is a 32-bit component, which you cannot use it in 64-bit AutoCAD (I assume you use 64-bit AutoCAD 2015, but if you still use 32-bit AutoCAD, then that control should have worked for you).

 

Whether you use 32 or 64 bit AutoCAD, though, you can forget the old DwgThumbnail control. There is easy way to access the thumbnail as long as your AutoCAD version is not too old (acad2010 or newer).

 

If your are doing AutoCAD add-in with .NET API, you can access drawing thumbnail by Database.ThumbnailBitMap property.

 

If you are instested to get drawing thumbnail without opening AutoCAD, then you can look at code sample here:

 

http://www.theswamp.org/index.php?topic=26621.0;all

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 12

Jedimaster
Collaborator
Collaborator
Yes I am running 64 bit. How do I get Database.ThumbnailBitMap on the Window Form?
0 Likes
Message 4 of 12

norman.yuan
Mentor
Mentor

On the Win Form, you'd have a Picture Control, right? Then you retrieve the Thumbnail as System.Drawing.Image from an opened drawing (or, you can read a drawing as side Database, so that you can get the Thumbnail).

 

Ideally, you'd have a helper class to get the image, something like:

 

public class CadHelper

{

    public static System.Drawing.Image GetThumbnail(Document dwg)

    {

        //Retrieve thumbnail froom already opened drawing document

    }

 

    public static System.Drawing.Image GetThumbnail(string dwgFileName)

    {

       //oepn a drawing file as side database and retrieve the Thumbnail

    }

}

 

Then you can do this in the form's code behind:

 

MyPictureControl.Image=CadHelper.getThumbnail(...);

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 5 of 12

Jedimaster
Collaborator
Collaborator

Under Window Form ToolBox am I still selecting AutoCAD DwgThumbnail Control? Because it is erroring on compiling the for with only boiler plate programing attached to it.

0 Likes
Message 6 of 12

norman.yuan
Mentor
Mentor

You DO NOT use DwgThumbnail control, because it is 32 bit and your AutoCAD is 64-bit.

 

If you read my previous reply carefully, you'd have seen that I said to use Win Form's PICTURE control.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 7 of 12

Jedimaster
Collaborator
Collaborator

No Pictrure control. I do have Picturebox. System.Drawing.Image.GetThumbnail does not appear.

System.Drawing.Image.GetThumbnailImageAbort but does appear but is boolean.

0 Likes
Message 8 of 12

norman.yuan
Mentor
Mentor

Well,

 

public static System.Drawing.Image.GetThumbnail(...)

{

    //the code could be as simple as this:

    Database db=ApplicationDocumentManager.MdiDocument;

    return db.ThumbnailBitmap;

}

 

is a method YOU are going to write to retrieve Thumbnail from a drawing database. it should return an System.Drawing.Image object that you can assigned to a picture control (OK, it is PictureBox control, to be technically correct).

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 9 of 12

Jedimaster
Collaborator
Collaborator
Is there a way to work in VB?
0 Likes
Message 10 of 12

Jedimaster
Collaborator
Collaborator

I am learning VB .NET

 

I have found possible soultion

https://social.msdn.microsoft.com/Forums/en-US/f4b057f0-b516-4f50-b2e3-8f435c0ee5a5/dwg-thumbnail-in...

 

Very long and ugly way. Backgounds come out white and sizing is a problem. I see no other way to get VB .NET to get the BMP preview from drawing.

0 Likes
Message 11 of 12

Anonymous
Not applicable
Accepted solution

Here is the code I've been using..   I would LOVE to give props to the source, but I don't remember what it is Smiley Frustrated

 

You feed it the DWG path and it returns a Bitmap image (if found)  BMP for 2012 and earier, PNG for 2013 and later

 

Imports System.IO

 

Function GetBitmap(fileName As String) As Bitmap
        Using fs As New FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
            Using br As New BinaryReader(fs)
                fs.Seek(&HD, SeekOrigin.Begin)
                fs.Seek(&H14 + br.ReadInt32(), SeekOrigin.Begin)
                Dim bytCnt As Byte = br.ReadByte()
                If bytCnt <= 1 Then
                    Return Nothing
                End If
                Dim imageHeaderStart As Integer
                Dim imageHeaderSize As Integer
                Dim imageCode As Byte
                For i As Short = 1 To bytCnt
                    imageCode = br.ReadByte()
                    imageHeaderStart = br.ReadInt32()
                    imageHeaderSize = br.ReadInt32()
                    If imageCode = 2 Then ' BMP Preview (2012 file format)
                        ' BITMAPINFOHEADER (40 bytes)
                        br.ReadBytes(&HE)
                        'biSize, biWidth, biHeight, biPlanes
                        Dim biBitCount As UShort = br.ReadUInt16()
                        br.ReadBytes(4)
                        'biCompression
                        Dim biSizeImage As UInteger = br.ReadUInt32()
                        'br.ReadBytes(0x10); //biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant
                        '-----------------------------------------------------
                        fs.Seek(imageHeaderStart, SeekOrigin.Begin)
                        Dim bitmapBuffer As Byte() = br.ReadBytes(imageHeaderSize)
                        Dim colorTableSize As UInteger = CUInt(Math.Truncate(If((biBitCount < 9), 4 * Math.Pow(2, biBitCount), 0)))
                        Using ms As New MemoryStream()
                            Using bw As New BinaryWriter(ms)
                                bw.Write(CUShort(&H4D42))
                                bw.Write(54UI + colorTableSize + biSizeImage)
                                bw.Write(New UShort())
                                bw.Write(New UShort())
                                bw.Write(54UI + colorTableSize)
                                bw.Write(bitmapBuffer)
                                Return New Bitmap(ms)
                            End Using
                        End Using
                    ElseIf imageCode = 6 Then ' PNG Preview (2013 file format)
                        fs.Seek(imageHeaderStart, SeekOrigin.Begin)
                        Using ms As New MemoryStream
                            fs.CopyTo(ms, imageHeaderStart)
                            Dim img = Image.FromStream(ms)
                            Return img
                        End Using
                    ElseIf imageCode = 3 Then
                        Return Nothing
                    End If
                Next
            End Using
        End Using
        Return Nothing
    End Function

Message 12 of 12

Anonymous
Not applicable

You could also look for the modelspace layout thumbnail.

 

This is C# but may be helpful

        internal static System.Drawing.Image GetMSpaceLayoutThumb(string FullDwgPath)
        {
            System.Drawing.Image imgRes = null;
            if (Autodesk.AutoCAD.AutoCADTools.DrawingFile.DwgIsOpen(FullDwgPath))
            {
                foreach (Document doc in acadApp.DocumentManager)
                {
                    if (doc.Name.ToUpper().Equals(FullDwgPath.ToUpper()))
                    {
                        Database db = doc.Database;
                        using (Transaction trans = db.TransactionManager.StartTransaction())
                        {
                            BlockTableRecord mSpaceRecord =
                                trans.GetObject(
                                    SymbolUtilityServices.GetBlockModelSpaceId(db), 
                                    OpenMode.ForRead) as BlockTableRecord;
                            if (mSpaceRecord != null)
                            {
                                Layout msLayout = trans.GetObject(
                                    mSpaceRecord.LayoutId, 
                                    OpenMode.ForRead) as Layout;
                                if (msLayout != null)
                                {
                                    Bitmap bm = msLayout.Thumbnail;
                                    imgRes = bm.Clone() as System.Drawing.Image;
                                }
                            }
                            trans.Commit();
                        }
                        break;
                    }
                }
            }
            else
            {
                try
                {
                    using (Database odb = new Database(false, true))
                    {
                        odb.ReadDwgFile(FullDwgPath, FileOpenMode.OpenForReadAndAllShare, false, null);
                        odb.CloseInput(true);
                        using (Transaction trans = odb.TransactionManager.StartTransaction())
                        {
                            BlockTableRecord mSpaceRecord =
                                trans.GetObject(
                                    SymbolUtilityServices.GetBlockModelSpaceId(odb), 
                                    OpenMode.ForRead) as BlockTableRecord;
                            if (mSpaceRecord != null)
                            {
                                Layout msLayout = trans.GetObject(
                                    mSpaceRecord.LayoutId, 
                                    OpenMode.ForRead) as Layout;
                                if (msLayout != null)
                                {
                                    Bitmap bm = msLayout.Thumbnail;
                                    imgRes = bm.Clone() as System.Drawing.Image;
                                }
                            }
                            trans.Commit();
                        }
                    }
                }
                catch (Autodesk.AutoCAD.Runtime.Exception aex)
                {
                    // as needed
                }
            }
            return imgRes;
        }

The "DwgIsOpen" function justs checks to see if the drawing is already open. If not a side database is used.

 

I hope this helps.

0 Likes