Capturing an image of the current AutoCAD document using .NET

This is a topic that has been addressed a few times on this blog, whether by posts that use the 3D graphics system to capture screenshots or the series of posts regarding the Screenshot Plugin of the Month from a few years ago. I thought it worth revisiting, though, as I noticed an API that I hadn't used before and decided to put it through its paces.

The API is a simple one – Document.CapturePreviewImage() – and it's been covered before on the AutoCAD DevBlog. But I thought I'd take some file-selection code from the Screenshot app and see whether it was possible to create a full-size screenshot of the current drawing window using it.

Here's the C# implementation of a CPI command that uses the API to save a "preview" image that's the same exact size as the document window.

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System;

using System.Drawing.Imaging;

using System.IO;

 

namespace ListApplications

{

  public static class Extensions

  {

    // Return the image format to use for a particular filename

 

    public static ImageFormat GetFormat(this string filename)

    {

      // If all else fails, let's create a PNG

      // (might also choose to throw an exception)

 

      var imf = ImageFormat.Png;

      if (filename.Contains("."))

      {

        // Get the filename's extension (what follows the last ".")

 

        string ext = filename.Substring(filename.LastIndexOf(".") + 1);

 

        // Get the first three characters of the extension

 

        if (ext.Length > 3)

          ext = ext.Substring(0, 3);

 

        // Choose the format based on the extension (in lowercase)

 

        switch (ext.ToLower())

        {

          case "bmp":

            imf = ImageFormat.Bmp;

            break;

          case "gif":

            imf = ImageFormat.Gif;

            break;

          case "jpg":

            imf = ImageFormat.Jpeg;

            break;

          case "tif":

            imf = ImageFormat.Tiff;

            break;

          case "wmf":

            imf = ImageFormat.Wmf;

            break;

          default:

            imf = ImageFormat.Png;

            break;

        }

      }

      return imf;

    }

  }

 

  public class Commands

  {

    [CommandMethod("CPI")]

    static public void CreatePreviewImage()

    {

      var doc = Application.DocumentManager.MdiActiveDocument;

      if (doc == null) return;

 

      var ed = doc.Editor;

 

      // Select the filename and type for our output image

 

      var pofo = new PromptSaveFileOptions("\nSelect image location");

 

      pofo.Filter =

        "Bitmap (*.bmp)|*.bmp|GIF (*.gif)|*.gif|JPEG (*.jpg)|*.jpg|" +

        "PNG (*.png)|*.png|TIFF (*.tif)|*.tif";

 

      // Set the default save location to be that of the current drawing

 

      string fn = doc.Database.Filename;

      if (fn.Contains("."))

      {

        int extIdx = fn.LastIndexOf(".");

        if (fn.Substring(extIdx + 1) != "dwt" && fn.Contains("\\"))

        {

          pofo.InitialDirectory = Path.GetDirectoryName(doc.Database.Filename);

        }

      }

 

      var pfnr = ed.GetFileNameForSave(pofo);

      if (pfnr.Status != PromptStatus.OK)

        return;

 

      var outFile = pfnr.StringResult;

 

      // Get the size of the document and capture the preview at that size

 

      var size = doc.Window.DeviceIndependentSize;

      using (

        var bmp =

          doc.CapturePreviewImage(

            Convert.ToUInt32(size.Width), Convert.ToUInt32(size.Height)

          )

      )

      {

        // Save the file with the format derived from the filename

 

        bmp.Save(outFile, outFile.GetFormat());

      }

    }

  }

}

 

Here's a sample drawing we'll run the command against:

A drawing to be screenshotted

And here's the output of the command:

A full-size screenshot of the drawing

2 responses to “Capturing an image of the current AutoCAD document using .NET”

  1. This is interesting. Because black bagrounds with blue and red geometry is difficult to read and print if the image was used in a document, is it possible to capture the image in black and white?

    1. Hi Jason,

      I just gave it a try: if you change the drawing background to white, the saved bitmap will also have a white background.

      To reduce the foreground to black or greyscale, you'll need to do some image simple image post-processing. The original Screenshot app linked to in the post does just that.

      Regards,

      Kean

  2. Matteo Conte Avatar

    Hi Kean,
    I use this function on my plugin. On some installations, the function saves a gray image (totally). Do you know why?
    Regards,
    Matteo

    1. Kean Walmsley Avatar
      Kean Walmsley

      Hi Matteo,

      That's very strange: it's the first time I've heard of something like this happening.

      If you can provide some steps to reproduce, I'll try to look into it.

      Regards,

      Kean

  3. Hello Kean, just my 2c. 🙂 Why not use io.path.getextension on the filename? Is there an option for alpha channel for png?
    BR, Daniel

    1. Kean Walmsley Avatar

      Hi Daniel,

      You're quite right: I'm not sure why I didn't. I see that I took some code from an old app - if I'd written it from scratch I'd have used it.

      Thanks for pointing this out!

      Kean

    2. Kean Walmsley Avatar

      Re: alpha channel

      Not that I'm aware of...

      Kean

      1. Thanks for the info!
        BR,
        Daniel

  4. Sheldon Alexandre Avatar
    Sheldon Alexandre

    Can this code be adapted to others 2D drawing programs?

    1. I doubt it, but give it a try and let us know.

      Kean

  5. Hello,I used this demo.I set window size 400*400, I want to create a picture same with 400*400,but picture size is 384* 390, not 400*400, Has anyone had this problem? Map3D 2016 and AutoDesk 2022

    1. Sorry for the delayed reply: please post your support questions to the appropriate Autodesk forum.

      Thank you,

      Kean

Leave a Reply

Your email address will not be published. Required fields are marked *