Resolved Help with DrawImage(Image image, int x, int y)

tim8w

Well-known member
Joined
Sep 8, 2020
Messages
129
Programming Experience
10+
I have a Rectangle which is defined as (0,40,475,244) into which I want to draw a 128x128 Image. I am calling DrawImage as follows:

C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);

The resulting Image ends up drawing in the wrong place.

1613196276693.png


Should have been more like this:

1613196338589.png


I know it must be something obvious, but I can't see what's wrong with the calculation of the Image location...
 
Solution
I managed to reproduce your problem.

Cracking open the .png file, it looks like it is formatted for 72 dpi, while Windows defaults to 96 dpi. So you'll need to let Windows scale the image into the appropriate area. Something like:
C#:
var ptImage = new Rectangle()
{
    X = rect.Width / 2 - _img.Width / 2 + rect.Left,
    Y = rect.Height / 2 - _img.Height / 2 + rect.Top,
};

g.DrawImage(_img, new Rectangle(ptImage, _img.Size));

In the image below, notice the bigger image drawn by DrawImage(Image, Point), and then painted over by the DrawImage(Image, Rectangle) which is right in the green rectangle where we expected the image to be drawn into.

Screenshot_1.png
Please provide a FULL and CLEAR explanation of the problem. You say that you have a Rectangle. OK then. How exactly does that relate to the code? What is this in that code? We need ALL the relevant information.
 
Please provide a FULL and CLEAR explanation of the problem. You say that you have a Rectangle. OK then. How exactly does that relate to the code? What is this in that code? We need ALL the relevant information.
Sorry, the Rectangle describes the panel below the header. I am trying to center the Image in that Rectangle.
 
When there's an offset you have to calculate centers of widths/heights and then offset the location.
 
When there's an offset you have to calculate centers of widths/heights and then offset the location.
I realize that. That's what I've done here:

C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);

But as you can see in the pictures above, it doesn't position it correctly even though it appears that the calculation is correct. The Panel Rectangle is (0,40,475,244) and the Image is 128x128. The resulting Start Point for the DrawImage is (173, 38). When it draws the Image, it appears to be off center. The X position appears to be too far right by about 23 and the Y position appears to be too high by about 16. Is there some pixel conversion that I'm not taking into account? The hosting Form AutoScaleMode is set to "None".
 
Result is (173,58), it should be (173,98), adding Y offset 40. That doesn't explain X problem, maybe you can post something we can run to reproduce it.
 
Are you sure that the image really is 128x128? What values are you getting in the debugger for this.BackgroundImage.Size.Width and this.BackgroundImage.Size.Height?
 
Are you sure that the image really is 128x128? What values are you getting in the debugger for this.BackgroundImage.Size.Width and this.BackgroundImage.Size.Height?
The size is definitely 128x128. So when I subtracted the actual position of the Panel (21,22) on the form in X, ie subtract off 21 from the final position calculated, it aligns perfectly in X. If I need to do that for the X, wouldn't I have to do the same for the Y?
 
Try running the following:
C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);
g.DrawRectangle(new Pen(Color.Green, 3), new Rectangle(pImage, this.BackgroundImage.Size));

Then take a screenshot and post it to this thread. I'm wondering if the image is 128x128, but the actual contents of the image is not actually edge to edge.
 
Try running the following:
C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);
g.DrawRectangle(new Pen(Color.Green, 3), new Rectangle(pImage, this.BackgroundImage.Size));

Then take a screenshot and post it to this thread. I'm wondering if the image is 128x128, but the actual contents of the image is not actually edge to edge.
 

Attachments

  • 1613268422553.png
    1613268422553.png
    27.3 KB · Views: 18
Looks to me that tells you that the image only contains the red arrow in the lower right corner of the entire image area.
 
OK. Let's start this over. I have a Panel with the following size: (0,40,475,244). The top 40 pixels are taken up by the header, so I don't want them be be considered when I center an Image in the lower section of the panel. The test image I am using is 128x128. The Image does not take up the entire 128x128. It is short on the Top and Bottom and just a little short on the Left and Right. So the area I want to center the image is (0,40,475,204) (The original panel minus the 40 pixel header)

The calculation I tried is:

C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);

where rPanel is (0,40,475,204) and this.BackgroundImage.Size = (128,128)


When I use this calculation, the image is not centered. It is shifted up and to the right.

1613276677753.png


I would like it centered something like this:

1613276757421.png
 
The test image I am using is 128x128. The Image does not take up the entire 128x128. It is short on the Top and Bottom and just a little short on the Left and Right.
But that is not the story being told by that green rectangle drown at the same location as your image. It is showing the image is practically stuck at the lower right corner of the 128x128 area.
 
Ah! So the image not only contains the arrow, but the box that looks like window chrome around it.

Now that's really messed up if the green rectangle is that far off from the image.

Do you change any of the graphics context's translate or origin values? What happens when you add g.Transform.Reset() before drawing the image and the green rectangle?
 
Back
Top Bottom