Search code examples
c#bitmapbackgroundmarginzedgraph

BackgroundImage with margins


I am making an audio spectrogram which is basically a Bitmap. To display the axes (graph) I am using ZedGraph which is there basically just to show axes, as said. Kind of a helper control. I am then displaying the Bitmap on it. This works good when the window is default sized - however, when I maximize it I loose proportions (see pictures below). It is hard (impossible?) to do it using anchoring.

Now I am wondering about other options which would maintain proper positioning. Is it possible to set the BackgroundImage for a Control (in my case ZedGraphControl) AND set it's margins? If not, what would be my best bet?

Default window size (everything OK): enter image description here

Maximized window (Bitmap not filling the ZedGraphControl): enter image description here


Solution

  • In my opinion there are two solutions. The first one is painting the waveform bitmap onto the control yourself (thus using the full available space but somewhat stretching your bitmap). The second one is building some panels around your control and resize them accordingly (makes the graph always appear in the correct aspect ratio but wastes screen space and is more complicated).

    1 I don't know how zedgraph works, but I porpose the following. From what you're writing it is a user control. What I would do is listen to its onPaint method. You are given a graphics object which you can freely use to draw anything (including a bitmap) on the control. Refering to the control's size you can easily draw your bitmap with the corresponding aspect ratio.

    2 Create a container to hold your graph control and add four panels, one for top, bottom, left and right. Just like on this image:

    You can now resize these according to the aspect ratio you need. To do so you have to listen to two events, the ResizeEnd event (which is called whenever the user finishes resizing your control) and an event to listen if the form was maximized (example). The code that needs to be executed is the following:

            private void AdjustPanels(object sender, EventArgs e)
            {
            double desiredAspectRatio = 1;
    
            // I am using the form itself as a reference to the size and aspect ration of the application.
            // you can, of course, use any other control instead (e.g. a panel where you stuff all the other panels
            int width = this.Width;
            int height = this.Height;
            double formAspectRatio = (double)width / (double)height;
    
            int marginLeft=0, marginRight=0, marginTop=0, marginBottom=0;
    
            if (desiredAspectRatio > formAspectRatio)
            {
                // high aspect ratios mean a wider picture -> the picture we want is wider than what it currently is
                // so we will need a margin on top and bottom
                marginLeft = 0; marginRight = 0;
                marginTop = (int)((height - desiredAspectRatio * width) / 2);
                marginBottom = (int)((height - desiredAspectRatio * width) / 2);
            }
            else
            {
                marginTop = 0; marginBottom = 0;
                marginLeft = (int)((width - desiredAspectRatio*height)/2);
                marginRight = (int)((width - desiredAspectRatio * height) / 2);
            }
    
            pnlTop.Height = marginTop;
            pnlBottom.Height = marginBottom;
            pnlLeft.Width = marginLeft;
            pnlRight.Width = marginRight;
        }
    

    Of course you will have to replace the value of "desiredAspectRation" with the aspect ratio of your waveform image. If you need further help just send me a private msg with your email address and I'll send you the complete Visual Studio solution.