| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 | using System.Drawing;using System.Drawing.Drawing2D;using netDxf;using netDxf.Entities;using Point = System.Drawing.Point;namespace InABox.Dxf{    public static class DxfUtils    {        // Draw a rotated string at a particular position.        private static void DrawRotatedTextAt(Graphics gr, float angle,            string txt, float x, float y, Font the_font, Brush the_brush)        {            // Save the graphics state.            var state = gr.Save();            gr.ResetTransform();            // Rotate.            gr.RotateTransform(angle);            // Translate to desired position. Be sure to append            // the rotation so it occurs after the rotation.            gr.TranslateTransform(x, y, MatrixOrder.Append);            // Draw the text at the origin.            gr.DrawString(txt, the_font, the_brush, 0, 0);            // Restore the graphics state.            gr.Restore(state);        }        private static void CheckPoints(double x, double y, ref double minX, ref double minY, ref double maxX, ref double maxY)        {            minX = x < minX ? x : minX;            minY = y < minY ? y : minY;            maxX = x > maxX ? x : maxX;            maxY = y > maxY ? y : maxY;        }        private static float Scale(int value, float offset, double scale, int border)        {            return (value - offset) * (float)scale + border;        }        private static float Scale(double value, float offset, int scale, int border)        {            return ((float)value - offset) * scale + border;        }        private static PointF VectorToPointF(Vector3 vector, PointF offset, int scale, Point border)        {            return new PointF(Scale(vector.X, offset.X, scale, border.X), Scale(vector.Y, offset.Y, scale, border.Y));        }        private static PointF VectorToPointF(Vector2 vector, PointF offset, int scale, Point border)        {            return new PointF(Scale(vector.X, offset.X, scale, border.X), Scale(vector.Y, offset.Y, scale, border.Y));        }        public static Bitmap ProcessImage(Stream stream, string caption)        {            var minX = double.MaxValue;            var minY = double.MaxValue;            var maxX = double.MinValue;            var maxY = double.MinValue;            var document = DxfDocument.Load(stream);            // Lets Explode all the various bits into their component atoms             // (i.e. everything is gonna be a line)            var lines = new List<Line>();            lines.AddRange(document.Lines);            foreach (var polyline in document.LwPolylines)            {                var components = polyline.Explode();                lines.AddRange(components.Where(x => x is Line).Select(x => x as Line));                foreach (Arc arc in components.Where(x => x is Arc))                    ArcToLines(lines, arc);            }            foreach (var polyline in document.Polylines)            {                var components = polyline.Explode();                lines.AddRange(components.Where(x => x is Line).Select(x => x as Line));                foreach (Arc arc in components.Where(x => x is Arc))                    ArcToLines(lines, arc);            }            foreach (var arc in document.Arcs)                ArcToLines(lines, arc);            foreach (var ellipse in document.Ellipses)            {                var precision = (int)((ellipse.MajorAxis + ellipse.MinorAxis) * 2.0F * Math.PI);                var polyline = ellipse.ToPolyline(precision);                var segments = polyline.Explode();                lines.AddRange(segments.Select(x => x as Line));            }            if (!lines.Any())                throw new Exception(string.Format("No Data Found in {0}!", caption));            foreach (var line in lines)            {                CheckPoints(line.StartPoint.X, line.StartPoint.Y, ref minX, ref minY, ref maxX, ref maxY);                CheckPoints(line.EndPoint.X, line.EndPoint.Y, ref minX, ref minY, ref maxX, ref maxY);            }            var height = (int)Math.Abs(maxY - minY);            var width = (int)Math.Abs(maxX - minX);            var scale = 15;            var margin = 100;            var offset = new PointF((float)minX, (float)minY);            var border = new Point(margin, margin);            var result = new Bitmap(width * scale + margin * 2, height * scale + margin * 2);            var pen = new Pen(new SolidBrush(Color.Black), 3.0F);            using (var g = Graphics.FromImage(result))            {                Brush bg = new SolidBrush(Color.White);                g.FillRectangle(bg, 0, 0, result.Width, result.Height);                foreach (var line in lines)                {                    var start = VectorToPointF(line.StartPoint, offset, scale, border);                    var end = VectorToPointF(line.EndPoint, offset, scale, border);                    g.DrawLine(pen, start, end);                }                var font = new Font("Arial", 20.0F);                var brush = new SolidBrush(Color.Blue);                pen = new Pen(brush);                var crect = g.MeasureString(caption, font);                g.DrawString(caption, font, brush, new PointF(result.Width / 2.0F - crect.Width / 2.0F, 10));                var heightrect = g.MeasureString(height.ToString(), font);                g.DrawLine(pen, new PointF(result.Width - (heightrect.Height + 10.0F), 100), new PointF(result.Width - 30, 100));                g.DrawLine(pen, new PointF(result.Width - (heightrect.Height + 10.0F), result.Height - 100),                    new PointF(result.Width - 30, result.Height - 100));                g.DrawLine(pen, new PointF(result.Width - (20.0F + heightrect.Height / 2.0F), 105),                    new PointF(result.Width - (20.0F + heightrect.Height / 2.0F), result.Height - 105));                var aX = result.Width - (20.0F + heightrect.Height / 2.0F);                float aY = 105;                g.FillPolygon(brush, new[]                {                    new(aX, aY),                    new PointF(aX - 10.0F, aY + 10.0F),                    new PointF(aX + 10.0F, aY + 10.0F)                });                aY = result.Height - 105;                g.FillPolygon(brush, new[]                {                    new(aX, aY),                    new PointF(aX - 10.0F, aY - 10.0F),                    new PointF(aX + 10.0F, aY - 10.0F)                });                g.FillRectangle(bg, result.Width - (heightrect.Height + 15.0F), result.Height / 2.0F - heightrect.Width / 2.0F, heightrect.Height,                    heightrect.Width);                DrawRotatedTextAt(g, 270.0F, height.ToString(), result.Width - (heightrect.Height + 15.0F),                    result.Height / 2.0F + heightrect.Width / 2.0F, font, brush);                var widthrect = g.MeasureString(width.ToString(), font);                g.DrawLine(pen, new PointF(100, result.Height - (widthrect.Height + 10.0F)), new PointF(100, result.Height - 30));                g.DrawLine(pen, new PointF(result.Width - 100, result.Height - (widthrect.Height + 10.0F)),                    new PointF(result.Width - 100, result.Height - 30));                g.DrawLine(pen, new PointF(105, result.Height - (20.0F + widthrect.Height / 2.0F)),                    new PointF(result.Width - 105, result.Height - (20.0F + widthrect.Height / 2.0F)));                aX = 105;                aY = result.Height - (20.0F + widthrect.Height / 2.0F);                g.FillPolygon(brush, new[]                {                    new(aX, aY),                    new PointF(aX + 10.0F, aY - 10.0F),                    new PointF(aX + 10.0F, aY + 10.0F)                });                aX = result.Width - 105;                g.FillPolygon(brush, new[]                {                    new(aX, aY),                    new PointF(aX - 10.0F, aY - 10.0F),                    new PointF(aX - 10.0F, aY + 10.0F)                });                g.FillRectangle(bg, result.Width / 2.0F - widthrect.Width / 2.0F, result.Height - (widthrect.Height + 15.0F), widthrect.Width,                    widthrect.Height);                g.DrawString(width.ToString(), font, brush,                    new PointF(result.Width / 2.0F - widthrect.Width / 2.0F, result.Height - (widthrect.Height + 15.0F)));            }            return result;        }        private static void ArcToLines(List<Line> lines, Arc arc)        {            var precision = Math.Max(2, (int)(arc.Radius * 2.0F * Math.PI));            var polyline = arc.ToPolyline(precision);            var segments = polyline.Explode();            lines.AddRange(segments.Select(x => x as Line));        }        public static Bitmap DXFToBitmap(string filename)        {            Bitmap result = null;            using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read))            {                try                {                    result = ProcessImage(stream, Path.GetFileNameWithoutExtension(filename));                }                catch (Exception e)                {                    result = null;                }            }            return result;        }    }}
 |