Author Topic: how to get preview dwg without autocad ?  (Read 30138 times)

0 Members and 1 Guest are viewing this topic.

bikelink

  • Guest
how to get preview dwg without autocad ?
« on: November 17, 2009, 05:59:31 AM »
I've been searchin for a while  to get a preview without use readdwg --> getthumbnail but I haven't found a solution.
Could  someone give me some suggestion about it ?
thanks in advance.

dgorsman

  • Water Moccasin
  • Posts: 2400
Re: how to get preview dwg without autocad ?
« Reply #1 on: November 17, 2009, 02:05:46 PM »
Fire up a session of TrueView and use the drawing file as an argument.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #2 on: November 17, 2009, 02:31:02 PM »
You didn't say what versions you're using but here's some more info on the subject:

http://discussion.autodesk.com/forums/thread.jspa?messageID=5405749&#5405749

Goodbye friends! :)
Aug. I'll be leaving work for good.

bikelink

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #3 on: November 18, 2009, 02:09:47 AM »
some as "extractImage" because I need to obtain the preview of a files in a folder.I've tried but it don't works.
« Last Edit: November 18, 2009, 02:25:09 AM by bikelink »

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #4 on: November 18, 2009, 06:37:45 AM »
same as "extractImage" because I need to obtain the preview of a files in a folder.I've tried but it don't works.

Doesn't work? Really?
That's exactly what I use it for.

What doesn't work?

Oh, this is an external app you're using?

I use it inside AutoCAD in a netloadable dll.





Goodbye friends! :)
Aug. I'll be leaving work for good.

bikelink

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #5 on: November 18, 2009, 09:11:30 AM »
yes it is extern code. I'm  trying to write a usercontrol in order to show preview of a  folder drawings.
Inside autocad I haven't trouble , can i use thumbnail of database or some method to create a preview..(i don't remember the exact name but i already wrote it).
well..I can't imagine how an extern program could be retrieve the preview from dwg!  :x
 
the API to retrieve the bitmap ,loads acmgdb.dll and then  it crash if you don't run inside autocad.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #6 on: November 18, 2009, 11:35:55 PM »
OK, I modified a bit of code that I used several years ago ... it needed to be updated anyway ... I could have changed the code a bit to add additional error checking, but I decided against it ...

My code was modeled after a VBA utility designed to read the bitmap and write it to a usercontrol pixel by pixel. I don't remember the original source (it has been too many years) so if anyone knows who it is, let me know and I'll be happy to credit them with the idea.

Anyway, I have updated it to read the thumbnail information and put it into a bitmap object that can be assigned to any control where an image is required. i.e. a picturebox, frame, form etc. I have also added the ability to toggle the background color from the default white in the thumbnail to black (and vice versa) and the ability to save the file if desired.

The usage is very simple ...
This will load the bitmap from the file in FileName and will set the backcolor to black.
Code: [Select]
Dim imgMyImage As Image
imgMyImage = acThumbnailReader.GetThumbnail(FileName, False)
Me.PictureBox1.Image = imgMyImage

Additional options:
Code: [Select]
'returns bitmap image exactly as it is in the file
imgMyImage = acThumbnailReader.GetThumbnail(FileName)

'returns bitmap image exactly as it is in the file
imgMyImage = acThumbnailReader.GetThumbnail(FileName, True)

'returns bitmap image with inverted backcolor
imgMyImage = acThumbnailReader.GetThumbnail(FileName, False)

'returns bitmap image exactly as it is in the file and saves it as a temporary file in %temp%
imgMyImage = acThumbnailReader.GetThumbnail(FileName, True, True)

'returns bitmap image with inverted backcolor and saves it as a temporary file in %temp%
imgMyImage = acThumbnailReader.GetThumbnail(FileName, False, True)

'returns bitmap image exactly as it is in the file and saves it to a specified file
imgMyImage = acThumbnailReader.GetThumbnail(FileName, True, True, SaveNameWithPath)

'returns bitmap image with inverted backcolor and saves it to a specified file
imgMyImage = acThumbnailReader.GetThumbnail(FileName, False, True, SaveNameWithPath)

Simply add the attached class to your VB.Net project

I would convert it to C#, but it is late ..maybe tomorrow ;-)
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #7 on: November 20, 2009, 11:15:21 AM »
ok .. I've rewritten it in C# for those who prefer ...

The same things apply as in the VB.Net version (i.e. GetThumbnail has 4 overloads) ... and the bitmap can be saved to a file and/or set to the image property of any control.

As always, the error checking is limited so use it keeping that in mind.

Enjoy!
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

bikelink

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #8 on: December 01, 2009, 05:20:59 AM »
wow! I saw just now... I'm going to try it! :roll:

ognyandim

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #9 on: November 15, 2010, 05:30:40 AM »
It works fine on AutoCAD 2008 64 bit! :) Very nice work!

kaefer

  • Swamp Rat
  • Posts: 572
Re: how to get preview dwg without autocad ?
« Reply #10 on: November 15, 2010, 12:47:13 PM »
It works fine on AutoCAD 2008 64 bit! :) Very nice work!

You mean, it works fine on DWG-files created by AutoCAD 64 bit?  Well, we would certainly hope for that kind of compatibility...

A word of caution though: Those structures aren't packed exactly as they would be inside the drawing, since in Keith's code each field is aligned with native word boundaries. I tried a quick and dirty port to F# (can't help myself), and attempted to read the structures directly by pinning the bytes[] returned by BinaryReader.ReadBytes. That may not be the most efficient approach and could introduce issues with endianness. And BTW, the image format looks like it's actually PNG. Here's the code:

Code: [Select]
#nowarn "9"

//Copyright 2009 K.E. Blackie
//This work is based in part from a VBA macro
//initially developed by members of www.vbdesign.net
//it may be used freely and may be modified to suit
//your needs as long as credit is given where it is due

open System.IO
open System.Runtime.InteropServices

[<Struct; StructLayout(LayoutKind.Sequential, Pack = 1)>]
type BITMAPINFOHEADER =
    val biSize: int32
    val biWidth: int32
    val biHeight: int32
    val biPlanes: int16
    val biBitCount: int16
    val biCompression: int32
    val biSizeImage: int32
    val biXPelsperMeter: int32
    val biYPelsPerMeter: int32
    val biClrUsed: int32
    val biClrImportant: int32

[<Struct; StructLayout(LayoutKind.Sequential, Pack = 1)>]
type IMGREC =
    val bytType: byte
    val lngStart: int32
    val lngLen: int32

[<Struct; StructLayout(LayoutKind.Sequential, Pack = 1)>]
type RGBQUAD =
    val rgbBlue: byte
    val rgbGreen: byte
    val rgbRed: byte
    val rgbReserved: byte

let byteToType<'T>(reader: BinaryReader) =
    let bytes = reader.ReadBytes(Marshal.SizeOf(typeof<'T>))

    let handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    let theStructure = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof<'T>) :?> 'T
    handle.Free()

    theStructure

let getThumbnail strFile boolRetainBackColor boolSaveToFile strSaveName =
   
    let mutable bmp =
        new System.Drawing.Bitmap(
            1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed )
    if File.Exists strFile then
        let fs = File.OpenRead strFile
        try
            use br = new BinaryReader(fs)
            fs.Seek(13L, SeekOrigin.Begin) |> ignore
            let lngImgLoc = br.ReadInt32()
            fs.Seek(int64 lngImgLoc + 17L, SeekOrigin.Begin) |> ignore
            let lngCurLoc = lngImgLoc + 17
            fs.Seek(int64 lngCurLoc + 3L, SeekOrigin.Begin) |> ignore
            let bytCnt = br.ReadByte()
            if bytCnt > 1uy then
                let intCnt = ref 0
                while !intCnt < int bytCnt do
                    incr intCnt
                    let udtRec = byteToType<IMGREC> br
                    if udtRec.bytType = 2uy then
                        fs.Seek(int64 udtRec.lngStart, SeekOrigin.Begin) |> ignore
                        let udtHeader = byteToType<BITMAPINFOHEADER> br
                        if udtHeader.biBitCount = 8s then
                            let udtColors =
                                [|  for count = 0 to 255 do
                                        yield byteToType<RGBQUAD> br |]
                            fs.Seek(int64 udtRec.lngStart, SeekOrigin.Begin) |> ignore
                            let bytBMPBuff = br.ReadBytes udtRec.lngLen

                            bmp <- new System.Drawing.Bitmap(udtHeader.biWidth, udtHeader.biHeight)
                            let lngCnt = ref (udtRec.lngLen - 1)
                            for y = 0 to udtHeader.biHeight - 1 do
                                for x = 1 to udtHeader.biWidth do
                                    let udtColor = udtColors.[int bytBMPBuff.[!lngCnt]]
                                    let lngColor =
                                        System.Drawing.Color.FromArgb(
                                            int udtColor.rgbRed,
                                            int udtColor.rgbGreen,
                                            int udtColor.rgbBlue )
                                        |> System.Drawing.ColorTranslator.ToOle
                                    let lngColor =
                                        if boolRetainBackColor then lngColor
                                        elif lngColor = System.Drawing.ColorTranslator.ToOle System.Drawing.Color.Black then
                                            System.Drawing.ColorTranslator.ToOle System.Drawing.Color.White
                                        elif lngColor = System.Drawing.ColorTranslator.ToOle System.Drawing.Color.White then
                                            System.Drawing.ColorTranslator.ToOle System.Drawing.Color.Black
                                        else lngColor

                                    bmp.SetPixel(udtHeader.biWidth - x,  y, System.Drawing.ColorTranslator.FromOle lngColor)
                                    decr lngCnt
                            intCnt := int bytCnt
        finally
            fs.Close()
   
    if boolSaveToFile then
        if System.String.IsNullOrEmpty strSaveName then
            let fName =
                System.String.Concat(
                    Path.GetTempPath(),
                    Path.GetFileNameWithoutExtension(Path.GetRandomFileName()),
                    ".bmp" )
            bmp.Save fName
        else
            bmp.Save strSaveName
    bmp

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #11 on: November 15, 2010, 01:09:38 PM »
meh ... the code I provided is merely for extracting the bitmap preview and letting the user see it, nothing else, others can use it .. or not .. it really makes no difference.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

kaefer

  • Swamp Rat
  • Posts: 572
Re: how to get preview dwg without autocad ?
« Reply #12 on: November 16, 2010, 03:10:43 AM »
meh ... the code I provided is merely for extracting the bitmap preview and letting the user see it, nothing else, others can use it .. or not .. it really makes no difference.

Hi Keith,

don't get me wrong. Your code is great and a helpful example of extracting the preview image. And it would really make a difference (for worse), if you hadn't posted it. Might've been my own inexperience that I was thrown off by the field packing issue, since it was somewhat contrary to my expectations.

Many thanks for the information and inspiration!

Sincerely, Thorsten

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #13 on: June 14, 2011, 03:27:42 PM »
Thanks Keith!
So much simpler then what I used before the upgrade. :)

Goodbye friends! :)
Aug. I'll be leaving work for good.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #14 on: June 15, 2011, 11:36:52 AM »
You are welcome
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Irvin

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #15 on: June 20, 2011, 08:03:00 AM »
Hi there,

Iv'e created a new component based on the standard picturebox.
Iv'e added 2 properties 1 is a file string of the dwg that needs to be showed.

here's the code. Don't know how to upload files here:

Code: [Select]
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace AcDgLibrary.Components
{
    public class AcDgDwgThumbnail : PictureBox
    {
        private string _dwgfile = string.Empty;
        private bool _retainbackcolor= true;

        [StructLayout(LayoutKind.Sequential)]
        private struct BITMAPINFOHEADER
        {
            public int biSize;
            public int biWidth;
            public int biHeight;
            public short biPlanes;
            public short biBitCount;
            public int biCompression;
            public int biSizeImage;
            public int biXPelsPerMeter;
            public int biYPelsPerMeter;
            public int biClrUsed;
            public int biClrImportant;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct IMGREC
        {
            public byte bytType;
            public int lngStart;
            public int lngLen;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct RGBQUAD
        {
            public byte rgbBlue;
            public byte rgbGreen;
            public byte rgbRed;
            public byte rgbReserved;
        }

        [Description("Gets or Sets the AutoCAD drawingfile to show it's thumbnail")]
        [Category("AutoCAD")]
        public string DwgFile
        {
            get { return _dwgfile; }
            set
            {
                _dwgfile = value;
                if (DwgFile == string.Empty) return;
                this.Image = GetThumbnail(_dwgfile, _retainbackcolor);
            }
        }

        [Description("Gets or Sets whether the image backcolor is retained.")]
        [Category("AutoCAD")]
        public bool RetainBackColor
        {
            get { return _retainbackcolor; }
            set { _retainbackcolor = value; }
        }

        private Bitmap GetThumbnail(string strFile, bool boolRetainBackColor)
        {
            Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed);
            byte bytCnt;
            byte[] bytBMPBuff;
            int lngImgLoc;
            FileStream fs = null;
            BinaryReader br = null;
            int lngCurLoc;
            int lngY;
            int lngX;
            int lngColor;
            int lngCnt;
            short intCnt;
            IMGREC udtRec;
            RGBQUAD[] udtColors;
            RGBQUAD udtColor;
            BITMAPINFOHEADER udtHeader;
            short intRed;
            short intGreen;
            short intBlue;
            try
            {
                if (File.Exists(strFile))
                {
                    fs = File.OpenRead(strFile);
                    br = new BinaryReader(fs);
                    fs.Seek(13, SeekOrigin.Begin);
                    lngImgLoc = br.ReadInt32();
                    fs.Seek(lngImgLoc + 17, SeekOrigin.Begin);
                    lngCurLoc = lngImgLoc + 17;
                    fs.Seek(lngCurLoc + 3, SeekOrigin.Begin);
                    bytCnt = br.ReadByte();
                    if (bytCnt > 1)
                    {
                        for (intCnt = 0; intCnt < bytCnt; intCnt++)
                        {
                            udtRec.bytType = br.ReadByte();
                            udtRec.lngStart = br.ReadInt32();
                            udtRec.lngLen = br.ReadInt32();
                            if (udtRec.bytType == 2)
                            {
                                fs.Seek(udtRec.lngStart, SeekOrigin.Begin);
                                udtHeader.biSize = br.ReadInt32();
                                udtHeader.biWidth = br.ReadInt32();
                                udtHeader.biHeight = br.ReadInt32();
                                udtHeader.biPlanes = br.ReadInt16();
                                udtHeader.biBitCount = br.ReadInt16();
                                udtHeader.biCompression = br.ReadInt32();
                                udtHeader.biSizeImage = br.ReadInt32();
                                udtHeader.biXPelsPerMeter = br.ReadInt32();
                                udtHeader.biYPelsPerMeter = br.ReadInt32();
                                udtHeader.biClrUsed = br.ReadInt32();
                                udtHeader.biClrImportant = br.ReadInt32();
                                bytBMPBuff = new byte[udtRec.lngLen + 1];
                                if (udtHeader.biBitCount == 8)
                                {
                                    udtColors = new RGBQUAD[256];
                                    for (int count = 0; count < 256; count++)
                                    {
                                        udtColors[count].rgbBlue = br.ReadByte();
                                        udtColors[count].rgbGreen = br.ReadByte();
                                        udtColors[count].rgbRed = br.ReadByte();
                                        udtColors[count].rgbReserved = br.ReadByte();
                                    }
                                fs.Seek(udtRec.lngStart - 1, SeekOrigin.Begin);
                                for (int count = 0; count <= udtRec.lngLen; count++)
                                {
                                    bytBMPBuff[count] = br.ReadByte();
                                }
                                bmp = new Bitmap(udtHeader.biWidth, udtHeader.biHeight);
                                lngCnt = 0;
                                for (lngY = 1; lngY <= udtHeader.biHeight; lngY++)
                                {
                                    for (lngX = udtHeader.biWidth; lngX >= 1; lngX--)
                                    {
                                        lngColor = bytBMPBuff[bytBMPBuff.GetUpperBound(0) - lngCnt];
                                        udtColor = udtColors[lngColor];
                                        intRed = Convert.ToInt16(udtColor.rgbRed);
                                        intGreen = Convert.ToInt16(udtColor.rgbGreen);
                                        intBlue = Convert.ToInt16(udtColor.rgbBlue);
                                        lngColor = ColorTranslator.ToOle(Color.FromArgb(intRed, intGreen, intBlue));
                                        if (boolRetainBackColor == false)
                                        {
                                            if (lngColor == ColorTranslator.ToOle(Color.Black))
                                            {
                                                lngColor = ColorTranslator.ToOle(Color.White);
                                            }
                                            else
                                            {
                                                if (lngColor == ColorTranslator.ToOle(Color.White))
                                                {
                                                    lngColor = ColorTranslator.ToOle(Color.Black);
                                                }
                                            }
                                        }
                                        bmp.SetPixel(lngX - 1, lngY - 1, ColorTranslator.FromOle(lngColor));
                                        lngCnt++;
                                    }
                                }
                            }
                            goto Exit_Here;
                            }
                            else
                            {
                                if (udtRec.bytType == 3)
                                {
                                    goto Exit_Here;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
                goto Exit_Here;
            }
            Exit_Here:
            if (br != null)
            {
                br.Close();
                fs.Close();
                fs.Dispose();
       
            }
            return bmp;
        }
    }
}

Hop this will help you.

Kind regards,

irvin

jgr

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #16 on: August 06, 2011, 12:26:03 AM »
jgr's version:
Also works with 32-bit images (Yes, .dwg files can also contain 32-bit images!).

Code: [Select]
using System;
using System.Drawing;
using System.IO;

namespace DwgUtilities {
    internal static class ThumbnailReader {
        internal static Bitmap GetBitmap(string fileName) {
            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
                using (BinaryReader br = new BinaryReader(fs)) {                   
                    fs.Seek(0xD, SeekOrigin.Begin);
                    fs.Seek(0x14 + br.ReadInt32(), SeekOrigin.Begin);
                    byte bytCnt = br.ReadByte();
                    if (bytCnt <= 1)
                        return null;
                    int imageHeaderStart;
                    int imageHeaderSize;
                    byte imageCode;
                    for (short i = 1; i <= bytCnt; i++) {
                        imageCode = br.ReadByte();
                        imageHeaderStart = br.ReadInt32();
                        imageHeaderSize = br.ReadInt32();
                        if (imageCode == 2) {
                            fs.Seek(imageHeaderStart, SeekOrigin.Begin);
                            //-----------------------------------------------------
                            // BITMAPINFOHEADER (40 bytes)
                            br.ReadBytes(0xE); //biSize, biWidth, biHeight, biPlanes
                            ushort biBitCount = br.ReadUInt16();
                            br.ReadBytes(4); //biCompression
                            uint biSizeImage = br.ReadUInt32();
                            //br.ReadBytes(0x10); //biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant
                            //-----------------------------------------------------
                            fs.Seek(imageHeaderStart, SeekOrigin.Begin);
                            byte[] bitmapBuffer = br.ReadBytes(imageHeaderSize);
                            uint colorTableSize =(uint)((biBitCount < 9) ? 4 * Math.Pow(2, biBitCount) : 0);
                            using (MemoryStream ms = new MemoryStream()) {
                                using (BinaryWriter bw = new BinaryWriter(ms)) {                                 
                                    //bw.Write(new byte[] { 0x42, 0x4D });
                                    bw.Write((ushort)0x4D42);
                                    bw.Write(54U + colorTableSize + biSizeImage);
                                    bw.Write(new ushort());
                                    bw.Write(new ushort());
                                    bw.Write(54U + colorTableSize);
                                    bw.Write(bitmapBuffer);
                                    return new Bitmap(ms);
                                }
                            }
                        } else if (imageCode == 3) {
                            return null;
                        }
                    }
                }
            }
            return null;
        }
    }
}

huiz

  • Swamp Rat
  • Posts: 845
  • Certified Prof C3D
Re: how to get preview dwg without autocad ?
« Reply #17 on: June 11, 2012, 03:11:06 PM »
Code by jgr=&jgr and Keith does work perfectly with drawing files up to 2010 format but not with 2013 file format. There were a few changes I've read. Is there anybody who has found out how to read the file thumbs of 2013 files?
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #18 on: June 11, 2012, 05:24:02 PM »
I've not looked at the 2013 file version so I couldn't tell you.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

twdotson

  • Mosquito
  • Posts: 13
Re: how to get preview dwg without autocad ?
« Reply #19 on: June 11, 2012, 06:20:50 PM »
The 2013 format uses a PNG file instead of BMP, you will see an object type code of 6.

huiz

  • Swamp Rat
  • Posts: 845
  • Certified Prof C3D
Re: how to get preview dwg without autocad ?
« Reply #20 on: June 12, 2012, 03:04:09 AM »
The 2013 format uses a PNG file instead of BMP, you will see an object type code of 6.

Ah indeed, BMP is 2. Thanks!
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

huiz

  • Swamp Rat
  • Posts: 845
  • Certified Prof C3D
Re: how to get preview dwg without autocad ?
« Reply #21 on: June 12, 2012, 04:00:11 AM »
Wow, that was easy. For who is interested, here the code to read thumbs, file format very old up to 2013:


Code: [Select]
Imports System.Drawing
Imports System.IO

' 2011 Copyright (C) jgr=&jgr, via http://www.theswamp.org
' 2012 (me): Added code to read PNG Thumbnails from DWG (2013 file format)
Friend NotInheritable Class ThumbnailReader
  Private Sub New()
  End Sub
  Friend Shared 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
End Class
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

TJK44

  • Newt
  • Posts: 196
Re: how to get preview dwg without autocad ?
« Reply #22 on: August 07, 2012, 09:13:16 AM »
Hi,

Wondering if anyone has been able to make the preview sharper. I don't have an overwhelmingly big picturebox displaying the preview, but the preview it generates isn't very clear. Anyway to make it look better?

Thanks

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #23 on: August 07, 2012, 09:19:49 AM »
The drawing preview is generated by AutoCAD and is stored in the drawing file. As far as I know, the preview image resolution is not able to be changed.

However, my understanding is that there might be a way to dynamically generate your own preview from the objects withing the drawing. Maybe someone can shed some light on that idea.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #24 on: August 09, 2012, 01:04:41 PM »
vs2010EX acad2012.

I have been converting this code to C# but evidently there are methods in vb.net that are not in C#.
The FileStream (fs) does not contain "CopyTo" in my intellisense. Any way to work around that?
Code: [Select]
if (imageCode == 6)       //PNG Preview (2013 file format);
           {
              fs.Seek(imageHeaderStart, SeekOrigin.Begin);         

              using (MemoryStream ms = new MemoryStream())
                {
                 
                 fs.CopyTo(ms, imageHeaderStart);
                 Image img = Image.FromStream(ms);
                 return new Bitmap(img);
                }   //end using
           } //end if

This is not an emergency I am just doing this for my own education.
I can't test it right now anyways but they are threatening me with an upgrade to 2013 Acad.
The entire file is attached.
Goodbye friends! :)
Aug. I'll be leaving work for good.

Jeff_M

  • King Gator
  • Posts: 3946
  • C3D user & customizer
Re: how to get preview dwg without autocad ?
« Reply #25 on: August 09, 2012, 02:14:11 PM »
vs2010EX acad2012.

I have been converting this code to C# but evidently there are methods in vb.net that are not in C#.
The FileStream (fs) does not contain "CopyTo" in my intellisense. Any way to work around that?

The CopyTo() is there in C#.  Look for other errors preventing the Intellisense from working. (Sometimes unclosed braces will do this to me.)

TJK44

  • Newt
  • Posts: 196
Re: how to get preview dwg without autocad ?
« Reply #26 on: August 09, 2012, 03:12:42 PM »
The Stream.CopyTo Method only became available with .NET Framework 4.0. Is your project targeting the 4.0 framework?

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #27 on: August 13, 2012, 07:01:48 AM »
@JeffM

Entirely possible.
I cut & paste the VB.net in to a new project and am debugging on a "most obvious comes first" scenario.
I'll isolate the irrellevant code as I should have done in the first place.

@TJK44

Yes, using .net framework 4 Client Profile.

Thanks!
Goodbye friends! :)
Aug. I'll be leaving work for good.

WILL HATCH

  • Bull Frog
  • Posts: 448
Re: how to get preview dwg without autocad ?
« Reply #28 on: March 17, 2013, 06:09:07 PM »
The options in AutoCAD 2013 shows the ability to save larger preview icons, but both the out of process and in process methods only get an image with a max width or height of 256 pixels. Anybody know how to get a larger image out?

Rusel

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #29 on: June 08, 2014, 05:38:30 AM »
Wow, that was easy. For who is interested, here the code to read thumbs, file format very old up to 2013:


Code: [Select]
Imports System.Drawing
Imports System.IO

' 2011 Copyright (C) jgr=&jgr, via http://www.theswamp.org
' 2012 (me): Added code to read PNG Thumbnails from DWG (2013 file format)
Friend NotInheritable Class ThumbnailReader
  Private Sub New()
  End Sub
  Friend Shared 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
End Class


Thank you for the code, but how do I make the background black? It is always gray in the picturbox.
Thanks,

WILL HATCH

  • Bull Frog
  • Posts: 448
Re: how to get preview dwg without autocad ?
« Reply #30 on: June 08, 2014, 07:01:35 PM »
far as I know that's based on the settings in the autocad instance which created it

Squazz

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #31 on: November 16, 2015, 07:44:37 AM »
vs2010EX acad2012.

I have been converting this code to C# but evidently there are methods in vb.net that are not in C#.
The FileStream (fs) does not contain "CopyTo" in my intellisense. Any way to work around that?
Code: [Select]
if (imageCode == 6)       //PNG Preview (2013 file format);
           {
              fs.Seek(imageHeaderStart, SeekOrigin.Begin);         

              using (MemoryStream ms = new MemoryStream())
                {
                 
                 fs.CopyTo(ms, imageHeaderStart);
                 Image img = Image.FromStream(ms);
                 return new Bitmap(img);
                }   //end using
           } //end if

This is not an emergency I am just doing this for my own education.
I can't test it right now anyways but they are threatening me with an upgrade to 2013 Acad.
The entire file is attached.

Trying out the code from BillZndl, I simply cannot get it to work. I'm constantly getting a "image fromstream parameter is not valid" error, no matter if I'm using dwg files from 2010, 2011, 2013 or 2015. I have attached the files I'm trying this with for reference.

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #32 on: November 16, 2015, 08:16:32 AM »
Wish I could help.
I'm still on 2012 Acad which I know will not work with this code.
Goodbye friends! :)
Aug. I'll be leaving work for good.

Squazz

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #33 on: November 16, 2015, 08:34:09 AM »
Wish I could help.
I'm still on 2012 Acad which I know will not work with this code.
Which code are you on then? The one from Keith?

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #34 on: November 16, 2015, 01:10:46 PM »
I think I changed to the one attached because of some background color issues with one I was using.
Goodbye friends! :)
Aug. I'll be leaving work for good.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #35 on: November 16, 2015, 01:37:19 PM »
The one I provided early on in this thread does not handle the png images embedded in the drawing very well.

I've just revisited this project because I needed to update a software package. I've implemented several of the changes in my new thumbnail reader class and it works great for drawings up to AutoCAD 2015.

I am not where I can upload the file, but if I get a chance I'll do it later today.

Keep in mind that if there is not a drawing preview saved in the DWG file, then no preview will be available.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Squazz

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #36 on: November 17, 2015, 02:54:12 AM »
I think I changed to the one attached because of some background color issues with one I was using.

That's also the one I'm having the best results with :)

The one I provided early on in this thread does not handle the png images embedded in the drawing very well.

I've just revisited this project because I needed to update a software package. I've implemented several of the changes in my new thumbnail reader class and it works great for drawings up to AutoCAD 2015.

I am not where I can upload the file, but if I get a chance I'll do it later today.

Keep in mind that if there is not a drawing preview saved in the DWG file, then no preview will be available.
I will be looking forward to that, would be AWESOME :) Thanks in advance

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #37 on: November 19, 2015, 12:29:58 PM »
Keith,
just thought I'd throw this out there.

The acThumbnailReader would fail if the dwg was open by another user/computer.
I looked at the code and it looked like it was opening the file as read only.
Code - C#: [Select]
  1. fs = File.OpenRead(strFile);
I got around this by checking to see if the file was locked before I tried to use it.
Code - C#: [Select]
  1.  WhoHasInfo info = AcadApp.GetWhoHasInfo(FlNam);
  2.  
  3.                         if (!info.IsFileLocked)
  4.                         {

Just thought it was funny that it would not be able to open the dwg in read mode.





The one I provided early on in this thread does not handle the png images embedded in the drawing very well.

I've just revisited this project because I needed to update a software package. I've implemented several of the changes in my new thumbnail reader class and it works great for drawings up to AutoCAD 2015.

I am not where I can upload the file, but if I get a chance I'll do it later today.

Keep in mind that if there is not a drawing preview saved in the DWG file, then no preview will be available.
Goodbye friends! :)
Aug. I'll be leaving work for good.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #38 on: November 20, 2015, 01:58:33 AM »
Interesting .. considering I tested it with several open drawings and there was no issue. If it becomes an issue, I'd suggest checking the lock status prior to calling the GetBitmap method.

Anyway, I've attached the dll that you can include in your projects. It reads all thumbnails from R14 to R2015 and should read through R2017 because there are no scheduled DWG format changes in the works.

This particular build has one public method GetBitmap and it accepts two parameters, filename and boolean retainBackColor.

A little more research into the preview section in the DWG file indicates that there is the possibility that the image format can be BMP, WMF or PNG (imagetype will be 2, 3, 6 respectively).

Also, the images can have pretty much any valid palette type and it makes a huge difference when swapping the background colors. For now, I've only coded the 8bit palette color swap. If you set retainBackColor to "false" the background will be solid black, otherwise it will be whatever color AutoCAD decides it needs to be.

A bitmap image is returned to the calling function so it can be saved from there or manipulated additionally.

I have found one minor bug in the image extraction. If the AutoCAD drawing window has an aspect ratio of less than 4:3 (roughly) when the preview is saved, the image will be skewed more prominently the closer to 4:3 the ratio gets. Once the ratio exceeds 4:3 (say 5:3), the image is no longer skewed.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #39 on: November 20, 2015, 09:44:28 AM »
Interesting .. considering I tested it with several open drawings and there was no issue. If it becomes an issue, I'd suggest checking the lock status prior to calling the GetBitmap method.

I don't get it either.

But thanks for the update.

Aw, geez, now I see I can download the file as my security settings have been changed by a blanket update on our computers.  :-(
Goodbye friends! :)
Aug. I'll be leaving work for good.

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #40 on: November 20, 2015, 11:47:13 AM »
Just an FYI:

Here is the error I was getting before I checked for file lock.(attached .png)
Goodbye friends! :)
Aug. I'll be leaving work for good.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16727
  • Superior Stupidity at its best
Re: how to get preview dwg without autocad ?
« Reply #41 on: November 20, 2015, 04:47:51 PM »
Are you saying you CANNOT download the file?
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

tetrahidrocannabinol

  • Guest
Re: how to get preview dwg without autocad ?
« Reply #42 on: November 21, 2015, 10:40:35 PM »
Just an FYI:

Here is the error I was getting before I checked for file lock.(attached .png)

Weird, unless the other process use FileShare.None (CreateFile("fu", 0..), in any case acThumbnailPreview.GetBitmap looks right

BillZndl

  • Bull Frog
  • Posts: 308
  • Retired
Re: how to get preview dwg without autocad ?
« Reply #43 on: November 23, 2015, 06:22:17 AM »
Are you saying you CANNOT download the file?

Yes, cannot, sorry.


Edit:
I managed to change the settings so I can down load the file.
When I get time, I'll try it out.
Thanks again!

« Last Edit: November 23, 2015, 07:00:44 AM by BillZndl »
Goodbye friends! :)
Aug. I'll be leaving work for good.