Export area around set of entities to PNG

Dominik Egger
12/2/2013 11:40 AM

So again a question.

I have a set of entities around which I would like to Export the drawing to PNG (with a "buffer of [x] units.

I am currently not getting the right coordinates - the buffers as well as width and height ar not diaplayed correctly.

I would Need a Resolution of at least 10 Pixels per Meter, or 5 times as good as the current view.

At the Moment I am calculating the bounds of the entities like this:

C# Code:
var entities = _model.Entities.Select(x => x).Where(x => x.Layer.Name.Equals(_outlineLayer.Name)).ToList();
 BoundsCalculator boundsCalculator = new BoundsCalculator();  
boundsCalculator.GetBounds(_model, entities);
      Bounds3D bounds = boundsCalculator2.Bounds;

Then I use the Delta to calculate width and height and multiply it by the "improvement factor". I also left in the margin

C# Code:
 const int margin = 2;
 int width = (int)System.Math.Ceiling(delt3a.X * 5) +  _exportBufferX;
 int height = (int)System.Math.Ceiling(delt3a.Y * 5) + _exportBufferY;     

I get the Corners from the bounds, transform them, apply the buffers and calculate the new matrix:

C# Code:
 var c1trans = viewControl1.GetTransformation().Transform(bound3s.Corner1);
      var c1 = new Point3D(c1trans.X - _exportBufferX, c1trans.Y + _exportBufferY, 0);
      var c2trans = viewControl1.GetTransformation().Transform(bound3s.Corner2);
     var  c2 = new Point3D(c2trans.X + _exportBufferX, c2trans.Y - _exportBufferY, 0);
      Matrix4D to2DTransform = DxfUtil.GetScaleTransform(
      new Point3D(c1.X, c2.Y, 0d),
      new Point3D(0d, delt3a.Y * 15, 0d),
      new Point3D(delt3a.X * 15, 0d, 0d),
      new Point3D(margin, margin, 0d)
    ) * viewControl1.GetTransformation(); 

and now (if not before) is the Point where I think I make the mistake.

I create the Bitmap and use the width and height i calculated from the bounds calculator.

C# Code:
  return ImageExporter.CreateBitmap(_model, to2DTransform,
                       GraphicsConfig.WhiteBackgroundCorrectForBackColor, SmoothingMode.HighQuality,
                       width, height);

Now I have two questions:
1: How can I update width and height of the Image?
2: Is it possible to ensure a certain number of Pixels per m?


12/2/2013 12:36 PM

In your first code you are use boundsCalculator to calculate bounds, but use boundsCalculator2 (note the 2) to access the bounds. Please check.

Your following code looks overly complex to me, and there are various variable definitions missing which might help to understand what you are doing. But what you should do is:

  1. Calculate the correct bounds.
  2. Define the scaling you want to have (pixels per model unit, the latter is not necessarily meter).
  3. Use the following code to scale the portion of the screen you want to fit into your image of size width*height:
  4. Code:
    Matrix4D modelToImageTransform = 
            Transformation4D.Translate(0.5 * (width -1), 0.5 * (height - 1), 0) *  // 3rd: move zero to image center
            Transformation4D.Scaling(scaling, -scaling, scaling) *                 // 2nd: scale (y points up in DXF, but down in image)
            Transformation4D.Translate(-(Vector3D)bounds.Center);                  // 1st: move center of selection to zero

    The above assumes that you have no rotations involved which you want to keep in the image. Just note that CalLib evaluates chained transformations from right to left, so what the above chain of transformations is doing is

    1. Move the center of the bounds to the center of the coordinate system (zero)
    2. Scale everything as you want to have while mirroring the y direction. Scaling is always around zero.
    3. Move zero (eg the former bounds center) to the center of the image.

The above assumes that you have no rotations involved which you want to keep in the image.

- Rammi