Search code examples
c#resizedxf

Resizing dxf file before drawing C#


I have been given a couple of .dxf files (200x200) and I now have to draw them in a panel (800x800) without losing quality.

My coworkers suggested that I resize/scale the .dxf file before drawing it and I have no clue how to do it.

Library: netDxf

// Get the Image object from DrawDxfEntities method
System.Drawing.Image image = DrawDxfEntities(dxfDocument);

panel1.BackgroundImage = image;

public System.Drawing.Image DrawDxfEntities(DxfDocument dxfDocument)
{
    
    Bitmap bitmap = new Bitmap(205,205);
    Graphics graphics = Graphics.FromImage(bitmap);
    graphics.SmoothingMode = SmoothingMode.AntiAlias;
    graphics.Clear(Color.White);

    string targetLayerName = "separador"; // Change this to the desired layer name

    foreach (var block in dxfDocument.Blocks)
    {
        foreach (var entity in block.Entities)
        {
            if (entity.Layer.Name == targetLayerName)
            {
                DrawDxfEntity(graphics, entity);
            }
        }
    }
    bitmap.RotateFlip(RotateFlipType.Rotate180FlipY);
    
    return bitmap;
}

[Stretched] [Normal]

I tried changing the bitmap size but it didn't change anything.


Solution

  • First, you have to calculate the bounding box of the entities of the .dxf, you will end up having (minX, minY, maxX, maxY).

    Now, you want to map this box to a target box, that would be (0, 0, 800, 800).

    Now, you have two boxes, the first box needs to fit withing the target box, by shifting it to the same origin, and scaling it to be completely withing the target (W.R.T aspect ratio).

    This is how you can calculate the scale factor.

    var panelWidth = 800;
    var panelHeight = 800;
    var entitiesXLength = entitiesMaxX - entitiesMinX;
    var entitiesYLength = entitiesMaxY - entitiesMinY;
    
    // Imagine bounding box of the entities is very wide on X.. this code will make sure you don't scale up on the smaller dimension, so the wider dimension will exceed the target boundaries
    var scaleFactor = entitiesXLength > entitiesYLength
        ? panelWidth / entitiesXLength
        : panelHeight / entitiesYLength;
    

    Now, when looping over dxf entities, shift the points on both axes to make sure the origin of the entities matches the origin of the target (which is (0,0)), and scale the points so they will fit within the target box.

    For example, this is how you update the coordinates of the line entity:

    line.StartPoint.X = (line.StartPoint.X - entitiesMinX) * scaleFactor;
    line.StartPoint.Y = (line.StartPoint.Y - entitiesMinY) * scaleFactor;
    line.EndPoint.X = (line.EndPoint.X - entitiesMinX) * scaleFactor;
    line.EndPoint.Y = (line.EndPoint.Y - entitiesMinY) * scaleFactor;
    

    Note that you might need to add panelHeight to Y-coordinates if the y-axes of the target is pointing downwards, and set the image dimensions to be 800x800.