원클릭으로
acad-images-ole
Raster images, PDF/DWF/DGN underlays, OLE objects, wipeouts, image clipping
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Raster images, PDF/DWF/DGN underlays, OLE objects, wipeouts, image clipping
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | acad-images-ole |
| description | Raster images, PDF/DWF/DGN underlays, OLE objects, wipeouts, image clipping |
Use this skill when inserting or manipulating raster images, PDF/DWF/DGN underlays, OLE embedded objects, or wipeout masking entities in AutoCAD drawings.
Every raster image requires a RasterImageDef stored in the ACAD_IMAGE_DICT dictionary. The definition holds the source file path and resolution; multiple RasterImage entities can reference the same definition.
public static ObjectId GetOrCreateImageDef(Database db, Transaction tr,
string imagePath, string dictKey)
{
ObjectId imageDictId = RasterImageDef.GetImageDictionary(db);
if (imageDictId.IsNull)
imageDictId = RasterImageDef.CreateImageDictionary(db);
DBDictionary imageDict = (DBDictionary)tr.GetObject(
imageDictId, OpenMode.ForWrite);
if (imageDict.Contains(dictKey))
return imageDict.GetAt(dictKey);
RasterImageDef imageDef = new RasterImageDef();
imageDef.SourceFileName = imagePath;
imageDef.Load(); // reads file to get resolution and pixel dimensions
ObjectId defId = imageDict.SetAt(dictKey, imageDef);
tr.AddNewlyCreatedDBObject(imageDef, true);
return defId;
}
A RasterImageDefReactor keeps an image definition alive while RasterImage entities reference it. Without a reactor, the definition can be purged prematurely.
RasterImageDefReactor reactor = new RasterImageDefReactor();
reactor.ImageDefId = imageDefId;
btr.AppendEntity(reactor);
tr.AddNewlyCreatedDBObject(reactor, true);
rasterImage.ReactorId = reactor.ObjectId;
public static ObjectId InsertRasterImage(Database db, ObjectId imageDefId,
Point3d insertionPt, double widthInDrawingUnits)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
RasterImageDef imageDef = (RasterImageDef)tr.GetObject(
imageDefId, OpenMode.ForRead);
RasterImage image = new RasterImage();
image.SetDatabaseDefaults();
image.ImageDefId = imageDefId;
// U/V vectors represent FULL width and height in drawing units
Vector2d pixelSize = imageDef.Size;
double height = widthInDrawingUnits * (pixelSize.Y / pixelSize.X);
image.Orientation = new CoordinateSystem3d(insertionPt,
Vector3d.XAxis * widthInDrawingUnits,
Vector3d.YAxis * height);
btr.AppendEntity(image);
tr.AddNewlyCreatedDBObject(image, true);
// Attach reactor to keep definition alive
RasterImageDefReactor reactor = new RasterImageDefReactor();
reactor.ImageDefId = imageDefId;
btr.AppendEntity(reactor);
tr.AddNewlyCreatedDBObject(reactor, true);
image.ReactorId = reactor.ObjectId;
// Associate image with its definition for xref-style tracking
image.AssociateRasterDef(imageDef);
tr.Commit();
return image.ObjectId;
}
}
Clip boundaries are specified in image pixel coordinates (origin at bottom-left corner of the image).
// Rectangular clip — exactly 2 points (lower-left, upper-right)
Point2dCollection rectPts = new Point2dCollection();
rectPts.Add(new Point2d(100, 100)); // lower-left in pixels
rectPts.Add(new Point2d(400, 300)); // upper-right in pixels
rasterImage.SetClipBoundary(ClipBoundaryType.Rectangle, rectPts);
rasterImage.IsClipped = true;
// Polygonal clip — 3+ vertices, first and last must match to close
Point2dCollection polyPts = new Point2dCollection();
polyPts.Add(new Point2d(50, 50));
polyPts.Add(new Point2d(300, 50));
polyPts.Add(new Point2d(300, 250));
polyPts.Add(new Point2d(150, 300));
polyPts.Add(new Point2d(50, 50)); // close
rasterImage.SetClipBoundary(ClipBoundaryType.Poly, polyPts);
rasterImage.IsClipped = true;
// Reset clip to full image
rasterImage.SetClipBoundaryToWholeImage();
rasterImage.IsClipped = false;
// Read existing clip boundary
ClipBoundary clip = rasterImage.GetClipBoundary();
// clip.ClipPoints — 2 points for rectangle, N+1 for polygon
// Use the inverse of PixelToModelTransform to convert WCS points to pixels
Matrix3d pixelToModel = rasterImage.PixelToModelTransform;
Matrix3d modelToPixel = pixelToModel.Inverse();
Point3d wcsPoint = new Point3d(50.0, 25.0, 0.0);
Point3d pixelPoint = wcsPoint.TransformBy(modelToPixel);
Point2d clipPt = new Point2d(pixelPoint.X, pixelPoint.Y);
Drawing-wide image display settings stored in the named object dictionary.
ObjectId rvId = RasterVariables.GetRasterVariables(db);
if (rvId.IsNull)
rvId = RasterVariables.CreateRasterVariables(db);
RasterVariables rv = (RasterVariables)tr.GetObject(rvId, OpenMode.ForWrite);
rv.ImageFrame = ImageFrameType.DisplayedNotPlotted;
// ImageFrameType: None=0, DisplayedAndPlotted=1, DisplayedNotPlotted=2
rv.ImageQuality = ImageQualityType.High; // Draft=0, High=1
rv.UserScale = 1.0;
PDF underlays use a definition/reference pair: PdfDefinition + PdfReference. The definition lives in the ACAD_PDFDEFINITIONS named dictionary.
public static ObjectId InsertPdfUnderlay(Database db, string pdfPath,
int pageNumber, Point3d insertionPt, double scale)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
// Get or create the PDF definitions dictionary
ObjectId pdDictId = UnderlayDefinition.GetDictionaryId(db,
new PdfDefinition().GetType());
if (pdDictId.IsNull)
pdDictId = UnderlayDefinition.CreateDictionary(db,
new PdfDefinition().GetType());
DBDictionary pdfDict = (DBDictionary)tr.GetObject(
pdDictId, OpenMode.ForWrite);
PdfDefinition pdfDef = new PdfDefinition();
pdfDef.SourceFileName = pdfPath;
pdfDef.ItemName = pageNumber.ToString(); // 1-based page number
ObjectId pdfDefId = pdfDict.SetAt(
"MyPdf_Page" + pageNumber, pdfDef);
tr.AddNewlyCreatedDBObject(pdfDef, true);
PdfReference pdfRef = new PdfReference();
pdfRef.SetDatabaseDefaults();
pdfRef.DefinitionId = pdfDefId;
pdfRef.Position = insertionPt;
pdfRef.ScaleFactors = new Scale3d(scale, scale, scale);
pdfRef.Rotation = 0.0;
btr.AppendEntity(pdfRef);
tr.AddNewlyCreatedDBObject(pdfRef, true);
tr.Commit();
return pdfRef.ObjectId;
}
}
DWF and DGN underlays follow the identical definition/reference pattern with swapped types:
| Format | Definition | Reference | Dictionary | ItemName |
|---|---|---|---|---|
PdfDefinition | PdfReference | ACAD_PDFDEFINITIONS | Page number | |
| DWF | DwfDefinition | DwfReference | ACAD_DWFDEFINITIONS | Sheet name |
| DGN | DgnDefinition | DgnReference | ACAD_DGNDEFINITIONS | Model name |
// Clip underlay — 2 points = rectangle, 3+ = polygon (in underlay space)
Point2dCollection clipPts = new Point2dCollection();
clipPts.Add(new Point2d(0, 0));
clipPts.Add(new Point2d(500, 350));
pdfRef.SetClipBoundary(clipPts);
pdfRef.IsClipped = true;
// Filter underlay layers
for (int i = 0; i < pdfRef.UnderlayLayerCount; i++)
{
UnderlayLayer layer = pdfRef.GetUnderlayLayer(i);
string name = layer.Name;
layer.State = UnderlayLayerState.Off; // On or Off
}
OLE objects embed or link external documents (Excel, Word, images) in the drawing. The .NET API cannot create new OLE objects programmatically; use COM automation or SendStringToExecute with the INSERTOBJ command instead.
foreach (ObjectId entId in btr)
{
Entity ent = (Entity)tr.GetObject(entId, OpenMode.ForRead);
if (ent is Ole2Frame ole)
{
ed.WriteMessage("\nOLE: {0}, Linked={1}", ole.UserType, ole.IsLinked);
if (ole.IsLinked)
ed.WriteMessage(", Path={0}", ole.LinkPath);
// Reposition an OLE object
ole.UpgradeOpen();
ole.Location = new Point3d(100, 200, 0);
ole.WcsWidth = 50.0;
ole.WcsHeight = 30.0;
}
}
A Wipeout masks entities behind it with the background color. It inherits from RasterImage.
public static ObjectId CreateWipeout(Database db, Point2dCollection boundary)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
Wipeout wipeout = new Wipeout();
wipeout.SetDatabaseDefaults();
wipeout.SetFrom(boundary, Vector3d.ZAxis);
btr.AppendEntity(wipeout);
tr.AddNewlyCreatedDBObject(wipeout, true);
tr.Commit();
return wipeout.ObjectId;
}
}
// Boundary must be a closed polygon (first point = last point)
Point2dCollection pts = new Point2dCollection();
pts.Add(new Point2d(0, 0));
pts.Add(new Point2d(100, 0));
pts.Add(new Point2d(100, 50));
pts.Add(new Point2d(0, 50));
pts.Add(new Point2d(0, 0));
// Frame visibility: 0=hidden, 1=displayed+plotted, 2=displayed not plotted
Application.SetSystemVariable("WIPEOUTFRAME", 2);
// Draw order — wipeout must be behind text but in front of hidden entities
DrawOrderTable dot = (DrawOrderTable)tr.GetObject(
btr.DrawOrderTableId, OpenMode.ForWrite);
ObjectIdCollection ids = new ObjectIdCollection { wipeoutId };
dot.MoveBelow(ids, entityAboveId);
RasterImageDef.Load() throws if the image file does not exist — verify the path or wrap in try/catchOrientation on RasterImage uses U and V vectors representing the FULL width and height in drawing units, NOT unit vectors — setting unit vectors produces a 1x1 unit imageRasterImageDefReactor is required to prevent image definitions from being purged — always create and attach one per image entityRasterImageDef.GetImageDictionary() returns ObjectId.Null if no images exist yet — always check and call CreateImageDictionary() if nullPixelToModelTransform to convert from WCSClipBoundaryType.Rectangle requires exactly 2 points (lower-left, upper-right) — ClipBoundaryType.Poly requires 3+ points with first = last to closeItemName must be a valid page number string (e.g., "1") — invalid values throw eInvalidValue or eOutOfRangeOle2Frame cannot be created programmatically via the .NET API — use COM automation or SendStringToExecute("INSERTOBJ\n") to embed new OLE contentUnderlayDefinition.GetDictionaryId() and CreateDictionary() require the concrete type (e.g., typeof(PdfDefinition)) to locate the correct named dictionaryAssociateRasterDef() must be called AFTER the RasterImage is added to the database — it establishes the reactor connection between image and definitionacad-blocks — images and underlays inserted inside block definitionsacad-layers — layer assignment for image, underlay, wipeout, and OLE entitiesacad-geometry — CoordinateSystem3d orientation vectors and Matrix3d transforms for image positioningacad-xrefs — underlays vs xrefs: underlays are display-only while xrefs bring full DWG geometryCorridors, baselines, regions, assemblies, subassemblies, corridor surfaces
Custom subassembly .NET design — CorridorState, SubassemblyGenerator, targets, SATemplate
Stock-subassembly pattern catalog — need→file index, worked DrawImplement recipes, point/link/shape code reference, mined from Autodesk's 120 VB stock subassemblies
Superelevation design, attainment, cross slope, pivot points, lane config
Block definitions, references, attributes, dynamic block properties, exploding
Dimensions — aligned, rotated, arc, radial, angular, ordinate, text overrides