How to add or replace bitmap images in CAD .NET

So I have found example code on how I am supposed to add images to DXF in CAD .NET, but the image does not come up and it breaks the DXF.

Could you give a working example:

Here is my code:

           double posX = 100;
            double posY = 100;
            string targetLayout = "Model";

            CadRasterImageDef rasterImageDef = new CadRasterImageDef(@"D:\dummy.png", 498, 186);
            rasterImageDef.ObjectHandle = "RefID";
            rasterImageDef.SoftOwner = _cadImage.Layouts[targetLayout].BlockTableRecordHandle;
            rasterImageDef.FileName = "dummy.png";

            // inserts RasterImage inside dxf
            CadRasterImage rasterImage = new CadRasterImage(
                rasterImageDef,
                new Cad3DPoint(posX, posY, 0), 
                new Cad3DPoint(0.5, 0, 0), 
                new Cad3DPoint(0, 0.5, 0)
            );


            rasterImage.ObjectHandle = "RefID-RasterImage";
            rasterImage.SoftOwner = _cadImage.Layouts[targetLayout].BlockTableRecordHandle;
            rasterImage.LayerName = "0";
            rasterImage.ImageDefReference = "RefID";
            rasterImage.DisplayFlags = 1;
            rasterImage.InsertionPoint.X = posX;
            rasterImage.InsertionPoint.Y = posY;
            rasterImage.UVector.X = 0.5;
            rasterImage.VVector.Y = 0.5;


            List<CadBaseEntity> entities = new List<CadBaseEntity>(_cadImage.Entities);
            entities.Insert(
                0,
                rasterImage
            ); // add to the beginning to fill image with background, entities will be above
            _cadImage.Entities = entities.ToArray();

            List<CadBaseObject> objects = new List<CadBaseObject>(_cadImage.Objects);
            objects.Add(rasterImageDef);
            _cadImage.Objects = objects.ToArray();

but the above image does not appear in PDF not SVG export and the DXF save breaks the DXF, so now it is corrupt.

Basically I want to either replace an existing image or add a new one… it seams like it could be possible, but I have no idea how to do it.

Also it would be good to know if I could use a memory stream instead of a file path that would be good.

@idra,
Hi.
Please attach the initial DXF file so we can investigate how exactly image is stored there and work on examples how to process it.

So this is the DXF to with we want to add the image. Again, if we can simply replace an image in the DXF than that would work for us as well. Perhaps even be better.

AIR_WATER_LWAV_FINAL.zip (1.2 MB)

So we are rasterizing “Layout1”! Also the latest DLL is not stable with our template so we are forced to use v23.4.0

So we finally figured it out. The image was added and the object handlers where something that DXF did not like, but we got them to work with “5631f”

Anyway, now the issue is that the image is rotated 90deg and there is no rotation property on the image objects

@idra,
OK, I don’t see any image now in the attached DXF, is it correct? Are you going to add the image, right?
Yes, saving to DXF back is a bit more strict compared to export to PDF, so some additional properties may be required to set up there. Could you please share code sample you are using now to insert rotated image?

Hei hei, so I finally got the code to work with trial and error. Here is a working example for anyone interested:

        using (CadImage cadImage = (CadImage)Aspose.CAD.Image.Load($@"{path}\template.dxf")) {
            
            double posX = 26950; //  image position X (buttom left corner)
            double posY = 545; // image position Y (buttom left corner)
            double scale = 16; // scales both the X and Y axis
            string targetLayout = "Model";

            CadRasterImageDef rasterImageDef = new CadRasterImageDef(@$"{path}\dummy.png", 498, 186);
            rasterImageDef.ObjectHandle = "5631f";
            rasterImageDef.SoftOwner = cadImage.Layouts[targetLayout].BlockTableRecordHandle;
            rasterImageDef.FileName = "dummy.png";
            

            // inserts RasterImage inside dxf
            CadRasterImage rasterImage = new CadRasterImage(
                rasterImageDef,
                new Cad3DPoint(posX, posY, 0), 
                new Cad3DPoint(1, 0, 0), //somehow rotate!
                new Cad3DPoint(0, 1, 0)
            );

            rasterImage.ObjectHandle = "4631f";
            rasterImage.SoftOwner = cadImage.Layouts[targetLayout].BlockTableRecordHandle;
            rasterImage.LayerName = "Logo";
            rasterImage.ImageDefReference = "5631f";
            rasterImage.DisplayFlags = 1;
            rasterImage.InsertionPoint.X = posX;
            rasterImage.InsertionPoint.Y = posY;
            rasterImage.UVector.X = scale; //scale
            rasterImage.VVector.Y = scale; 
            
                  


            List<CadBaseEntity> entities = new List<CadBaseEntity>(cadImage.Entities);
            entities.Insert(
                0,
                rasterImage
            ); // add to the beginning to fill image with background, entities will be above
            cadImage.Entities = entities.ToArray();

            List<CadBaseObject> objects = new List<CadBaseObject>(cadImage.Objects);
            objects.Add(rasterImageDef);
            cadImage.Objects = objects.ToArray();

            //save PDF

            PdfOptions options = new PdfOptions();

            CadRasterizationOptions rasterizationOptions = new Aspose.CAD.ImageOptions.CadRasterizationOptions();
            rasterizationOptions.PageWidth = cadImage.Width;
            rasterizationOptions.PageHeight = cadImage.Height;
            rasterizationOptions.DrawType = CadDrawTypeMode.UseObjectColor;            
            rasterizationOptions.AutomaticLayoutsScaling = true;
            rasterizationOptions.NoScaling = false;
            rasterizationOptions.ScaleMethod = ScaleType.GrowToFit;    
            rasterizationOptions.Layouts = new string[]{ "Layout1" };
                            
            options.VectorRasterizationOptions = rasterizationOptions;               
            
            cadImage.Save($@"{path}\result.pdf", options);         
        }

Still though, no idea why this works :stuck_out_tongue: The Aspose examples should do a better job explaining what is going on in here.

1 Like

Although I would like to add the image as a memory stream if at all possible?

@idra,
Hello.
Happy to hear it worked.

You can use this example to generate next available value for object handles instead of placing them fixed:


// search for available handle
string newObjectID = "FFFFFF";

if (cadImage.Header.HeaderProperties.ContainsKey(CadHeaderAttribute.HANDSEED))
{
	newObjectID = ((CadStringParameter)cadImage.Header.HeaderProperties[CadHeaderAttribute.HANDSEED][0]).Value;
	int nextAvailableID = int.Parse(newObjectID, System.Globalization.NumberStyles.HexNumber) + 1;
	((CadStringParameter)cadImage.Header.HeaderProperties[CadHeaderAttribute.HANDSEED][0]).Value = nextAvailableID.ToString("X");
}

Your original code sample works without rotation for me :slight_smile: . U-vector and V-vector point the direction of the image (as it comes from the definition of IMAGE object). Unfortunately, loading from stream is not possible as IMAGEDEF object requires filename to be set.

We can confirm also that saving this back to DXF doesn’t work, we have created CADNET-9783 to cover this issue.

@idra,
you can also try this example to add images and save to DXF:

string png1 = "adding_images_1.png";
string png2 = "adding_images_2.png";
string file = NameOfEmptyDxfFile;
string fileResult = NameOfEditedDxfFile;

// Adding images
using (var dxf = (DxfImage)Image.Load(file))
{
    var imgDef = new CadRasterImageDef(png1, 200, 200);
    dxf.AssignHandle(imgDef);

    var img = new CadRasterImage(imgDef, new Cad3DPoint(18, 0, 0), new Cad3DPoint(0.01, 0, 0), new Cad3DPoint(0, 0.01, 0));
    var img2 = new CadRasterImage(imgDef, new Cad3DPoint(5, 0, 0), new Cad3DPoint(0.01, 0, 0), new Cad3DPoint(0, 0.01, 0));
    dxf.AddObject(imgDef);
    dxf.AddEntity(img);
    dxf.AddEntity(img2);

    var imgDef2 = new CadRasterImageDef
    {
        FileName = png2,
        ImageSizeU = 300,
        ImageSizeV = 300,
    };

    dxf.AssignHandle(imgDef2);

    var img3 = new CadRasterImage(imgDef2, new Cad3DPoint(18, 18, 0), new Cad3DPoint(0.01, 0, 0), new Cad3DPoint(0, 0.01, 0));
    var img4 = new CadRasterImage(imgDef2, new Cad3DPoint(5, 18, 0), new Cad3DPoint(0.01, 0, 0), new Cad3DPoint(0, 0.01, 0));

    dxf.AddObject(imgDef2);
    dxf.AddEntity(img3);
    dxf.AddEntity(img4);
    dxf.Save(fileResult);
}