Author Topic: ExternalException: A generic error occurred in GDI+  (Read 2113 times)

0 Members and 1 Guest are viewing this topic.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
ExternalException: A generic error occurred in GDI+
« on: October 17, 2012, 09:53:36 AM »
Hi all,

I have some code for snapshots creating (on AutoCAD), but it ain't working to me. I get the ExternalException with message: "A generic error occurred in GDI+".
It always happens when was calling methods 'GetSnapshot' or 'RenderToImage'.

Why it happens? How can I fix it?

Code - C#: [Select]
  1. // AutoCAD 2009 SP3 x86 Enu
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using WinForms = System.Windows.Forms;
  7. //Autodesk namespaces ***************
  8. using acad = Autodesk.AutoCAD.ApplicationServices.Application;
  9. using AcApp = Autodesk.AutoCAD.ApplicationServices;
  10. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  11. using AcEd = Autodesk.AutoCAD.EditorInput;
  12. using AcRtm = Autodesk.AutoCAD.Runtime;
  13. using AcPub = Autodesk.AutoCAD.Publishing;
  14. using AcPlt = Autodesk.AutoCAD.PlottingServices;
  15. using AcGem = Autodesk.AutoCAD.Geometry;
  16. using AcCol = Autodesk.AutoCAD.Colors;
  17. using AcCMod = Autodesk.AutoCAD.ComponentModel;
  18. using AcGInt = Autodesk.AutoCAD.GraphicsInterface;
  19. using AcGSys = Autodesk.AutoCAD.GraphicsSystem;
  20. using AcLayMng = Autodesk.AutoCAD.LayerManager;
  21. using AcWin = Autodesk.AutoCAD.Windows;
  22. using AcICen = Autodesk.AutoCAD.AcInfoCenterConn;
  23. //************************************
  24.  
  25. namespace AcadGUI {
  26.         public class TestClass {
  27.  
  28.                 /// <summary>
  29.                 /// The "GetScreenAndSnapshot" shows how to call 'RenderOffScreen'
  30.                 /// and 'GetSnapshot'.
  31.                 /// NOTE: You must supply at least one 3D Object for it to work.
  32.                 /// </summary>
  33.                 [AcRtm.CommandMethod("GetScreenAndSnapshot")]
  34.                 public void GetScreenAndSnapshot() {
  35.                         AcApp.Document doc = acad.DocumentManager.MdiActiveDocument;
  36.                         // get the viewport number from the cvport variable
  37.                         Int16 nViewportNumber = (Int16)acad.GetSystemVariable("CVPORT");
  38.                         // construct a gsview from the cvport window number
  39.                         AcGSys.View oGsView = doc.GraphicsManager.GetGsView(nViewportNumber, true);
  40.                         using (AcGSys.View view = oGsView.Clone(true, true)) {
  41.                                 // create the offscreen device to render to
  42.                                 using (AcGSys.Device dev = doc.GraphicsManager.CreateAutoCADOffScreenDevice()) {
  43.                                         // resize the same as the cvport window size
  44.                                         dev.OnSize(doc.GraphicsManager.DisplaySize);
  45.                                         // set to full render
  46.                                         dev.DeviceRenderType = AcGSys.RendererType.FullRender;
  47.                                         // add the view to the device
  48.                                         dev.Add(view);
  49.  
  50.                                         // now create the bitmaps:
  51.  
  52.                                         // Get snapshot:
  53.                                         // ExternalException: A generic error occurred in GDI+.
  54.                                         using (System.Drawing.Bitmap bitmap = view.GetSnapshot(
  55.                                                 new System.Drawing.Rectangle(0, 0, (Int32)view.FieldWidth, (Int32)view.FieldHeight))) {
  56.                                                 bitmap.Save(@"c:\temp\snapshot.bmp");
  57.                                         }
  58.  
  59.                                         // Get screen:
  60.                                         // ExternalException: A generic error occurred in GDI+.
  61.                                         using (System.Drawing.Bitmap bitmap = view.RenderToImage()) {
  62.                                                 bitmap.Save(@"c:\temp\test.bmp");
  63.                                         }
  64.                                 }
  65.                         }
  66.                         // all clean up is handled automatically this way
  67.                 }
  68.  
  69.                 /// <summary>
  70.                 /// The next "GetScreen2" shows how to use GetSnapShot, notice the code is
  71.                 /// implemented slightly differently (mirrors more the ObjectARX way of doing it).
  72.                 /// </summary>
  73.                 [AcRtm.CommandMethod("GetScreen2")]
  74.                 public void GetScreen2() {
  75.  
  76.                         using (AcDb.Database newDb = new AcDb.Database(true, true)) {
  77.                                 using (AcDb.Transaction tr = newDb.TransactionManager.StartTransaction()) {
  78.                                         using (AcDb.BlockTableRecord TestBlock = new AcDb.BlockTableRecord()) {
  79.                                                 using (AcDb.BlockTable PBlockTable = tr.GetObject(newDb.BlockTableId,
  80.                                                         AcDb.OpenMode.ForWrite) as AcDb.BlockTable) {
  81.                                                         using (AcDb.BlockTableRecord modspace = tr.GetObject(PBlockTable[
  82.                                                                 AcDb.BlockTableRecord.ModelSpace],
  83.                                                                 AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord) {
  84.                                                                 TestBlock.Name = "Testblock";
  85.                                                                 AcDb.DBText testtext = new AcDb.DBText();
  86.                                                                 testtext.Position = new AcGem.Point3d(0, 0, 0);
  87.                                                                 testtext.TextString = "ABC-abc";
  88.                                                                 testtext.Height = 50;
  89.                                                                 modspace.AppendEntity(testtext);
  90.                                                                 tr.AddNewlyCreatedDBObject(testtext, true);
  91.                                                                 tr.Commit();
  92.                                                         }
  93.                                                 }
  94.                                         }
  95.                                 }
  96.  
  97.                                 // get the active document
  98.                                 AcApp.Document document = acad.DocumentManager.MdiActiveDocument;
  99.  
  100.                                 // get the current viewport number
  101.                                 Int16 cvPort = (Int16)acad.GetSystemVariable("CVPORT");
  102.                                 // next get the graphics system manager so we can access the off screen device functionality
  103.                                 using (AcGSys.Manager gsManager = document.GraphicsManager) {
  104.                                         // create an offscreen device
  105.                                         using (AcGSys.Device offDevice = gsManager.CreateAutoCADOffScreenDevice()) {
  106.                                                 // now set the size of the device
  107.                                                 offDevice.OnSize(document.GraphicsManager.DisplaySize);
  108.  
  109.                                                 // now create a new view
  110.                                                 using (AcGSys.View view = new AcGSys.View()) {
  111.                                                         // set the mode of the view to just a normal wire frame
  112.                                                         view.Mode = Autodesk.AutoCAD.GraphicsSystem.RenderMode.Wireframe;
  113.                                                         offDevice.DeviceRenderType = AcGSys.RendererType.Default;
  114.                                                         // add the empty view to the device
  115.                                                         offDevice.Add(view);
  116.                                                         offDevice.Update();
  117.  
  118.                                                         // now lets create a model to put into the view
  119.                                                         using (AcGSys.Model model = gsManager.CreateAutoCADModel()) {
  120.                                                                 try {
  121.                                                                         using (AcDb.Transaction trans = newDb.TransactionManager.StartTransaction()) {
  122.                                                                                 //  just add the whole modelspace to the model view
  123.                                                                                 AcDb.BlockTableRecord btr = trans.GetObject(newDb.CurrentSpaceId,
  124.                                                                                         AcDb.OpenMode.ForRead) as AcDb.BlockTableRecord;
  125.                                                                                 view.Add(btr, model);
  126.                                                                         }
  127.                                                                 }
  128.                                                                 catch {
  129.                                                                 }
  130.  
  131.                                                                 // just zoom out a bit
  132.                                                                 AcGem.Point3d extmin = new AcGem.Point3d(-100, -100, 0);
  133.                                                                 AcGem.Point3d extmax = new AcGem.Point3d(100, 100, 0);
  134.                                                                 // now zoom the view to the extents of the drawing
  135.                                                                 view.ZoomExtents(extmin, extmax);
  136.  
  137.                                                                 System.Drawing.Rectangle rect = view.Viewport;
  138.  
  139.                                                                 //  no render it
  140.  
  141.                                                                 // ExternalException: A generic error occurred in GDI+.
  142.                                                                 System.Drawing.Bitmap bitmap = view.GetSnapshot(rect);
  143.  
  144.                                                                 //  finally save
  145.                                                                 bitmap.Save(@"c:\temp\test2.bmp");
  146.  
  147.                                                                 //  we must clean up a little otherwise AutoCAD may become unstable
  148.                                                                 view.EraseAll();
  149.                                                                 offDevice.Erase(view);
  150.                                                         }
  151.                                                 }
  152.                                         }
  153.                                 }
  154.                         }
  155.                 }
  156.         }
  157. }
  158.  

Regards
« Last Edit: October 17, 2012, 10:10:30 AM by Andrey »

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: ExternalException: A generic error occurred in GDI+
« Reply #1 on: October 17, 2012, 10:35:44 AM »
If I try to use this Kean Walmsley's code, I get this Exception too, on
Code - C#: [Select]
  1. Bitmap bitmap = view.GetSnapshot(rect)
code row.