Search code examples
c#canvasbitmapgrasshopperrhino-commons

Where to place the coordinates of text in a C# graphic bitmap


I wrote a C# Render method that renders a heatmap onto a Grasshopper canvas. Grasshopper is a Rhino plugin that allows for a simple GUI programming interface.

protected override void Render(Grasshopper.GUI.Canvas.GH_Canvas canvas, Graphics graphics, Grasshopper.GUI.Canvas.GH_CanvasChannel channel) {

            base.Render(canvas, graphics, channel);

            if (channel == Grasshopper.GUI.Canvas.GH_CanvasChannel.Wires) {
                var comp = Owner as KT_HeatmapComponent;
                if (comp == null)
                    return;

                List<HeatMap> maps = comp.CachedHeatmaps;
                if (maps == null)
                    return;

                if (maps.Count == 0)
                    return;

                int x = Convert.ToInt32(Bounds.X + Bounds.Width / 2);
                int y = Convert.ToInt32(Bounds.Bottom + 10);

                for (int i = 0; i < maps.Count; i++) {
                    Bitmap image = maps[i].Image;
                    if (image == null)
                        continue;

                    Rectangle mapBounds = new Rectangle(x, y, maps[i].Width, maps[i].Height);
                    //Rectangle mapBounds = new Rectangle(x, y, maps[i].Width * 10, maps[i].Height * 10);
                    mapBounds.X -= mapBounds.Width / 2;

                    Rectangle edgeBounds = mapBounds;
                    edgeBounds.Inflate(4, 4);

                    GH_Capsule capsule = GH_Capsule.CreateCapsule(edgeBounds, GH_Palette.Normal);
                    capsule.Render(graphics, Selected, false, false);
                    capsule.Dispose();

                    graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
                    graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
                    graphics.DrawImage(image, mapBounds);
                    graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Default;
                    graphics.DrawRectangle(Pens.Black, mapBounds);

                    y = edgeBounds.Bottom - (mapBounds.Height) - 4;
                }
            }
        }

Currently, this render methods draws an image like this onto the canvas:

enter image description here

With that said, I would like to put some title text on top, and put in labels for the X and Y axis, like a standard heat map graph. However, my understanding of the graphics component is too limited, and I would like to request the assistance of you guys.

I did some research, and it seems the drawText() method could do what I want: c# write text on bitmap

But I am unsure where to specify the coordinates while at the same time leaving some space on the top of the displayed graph to put the title text.


Solution

  • The coordinate system that GDI+ uses starts from the topleft corner which is (0,0) The bottom right corner (fullimagewidth,fullimageheight)

    enter image description here

    so if you need to draw on the topleft corner of the image use

    //Position
    PointF drawPoint = new PointF(0F, 0F);
    // Draw string to screen.
    e.Graphics.DrawString("hey", drawFont, drawBrush, drawPoint);