same as "extractImage" because I need to obtain the preview of a files in a folder.I've tried but it don't works.
Dim imgMyImage As Image
imgMyImage = acThumbnailReader.GetThumbnail(FileName, False)
Me.PictureBox1.Image = imgMyImage
'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)
It works fine on AutoCAD 2008 64 bit! :) Very nice work!
#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
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.
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;
}
}
}
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;
}
}
}
The 2013 format uses a PNG file instead of BMP, you will see an object type code of 6.
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
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
vs2010EX acad2012.The CopyTo() is there in C#. Look for other errors preventing the Intellisense from working. (Sometimes unclosed braces will do this to me.)
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?
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
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.
Wish I could help.Which code are you on then? The one from Keith?
I'm still on 2012 Acad which I know will not work with this code.
I think I changed to the one attached because of some background color issues with one I was using.
The one I provided early on in this thread does not handle the png images embedded in the drawing very well.I will be looking forward to that, would be AWESOME :) Thanks in advance
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.
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.
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.
Just an FYI:
Here is the error I was getting before I checked for file lock.(attached .png)
Are you saying you CANNOT download the file?