Image Is Not Drawn at the Correct Spot

Image is not drawn at the correct spot

You are loading an Image, then a copy of this source is created using:

Bitmap bitmap = new Bitmap();

When you create a copy of an Image this way, you sacrifice/alter some details:

Dpi Resolution: if not otherwise specified, the resolution is set to the UI resolution. 96 Dpi, as a standard; it might be different with different screen resolutions and scaling. The System in use also affects this value (Windows 7 and Windows 10 will probably/possibly provide different values)

PixelFormat: If not directly copied from the Image source or explicitly specified, the PixelFormat is set to PixelFormat.Format32bppArgb.

From what you were saying, you probably wanted something like this:

var imageSource = Image.FromStream(new MemoryStream(File.ReadAllBytes(@"[SomeImageOfLena]"))), true, false)
var imageCopy = new Bitmap(imageSource.Width + 100, imageSource.Height, imageSource.PixelFormat))

imageCopy.SetResolution(imageSource.HorizontalResolution, imageSource.VerticalResolution);
using (var g = Graphics.FromImage(imageCopy)) {
g.Clear(Color.Black);
g.CompositingMode = CompositingMode.SourceCopy;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imageSource, (imageCopy.Width - imageSource.Width) / 2, 0);

pictureBox1.Image?.Dispose();
pictureBox2.Image?.Dispose();
pictureBox1.Image = imageSource;
pictureBox2.Image = imageCopy;
}

This is the result:

(The upper/lower frame black color is actually the Picturebox background color)

Corrected DPI

When the original Image Dpi Resolution is different from the base Dpi Resolution used when creating an Image copy with new Bitmap(), your results may be different from what is expected.

This is what happens with a source Image of 150, 96 and 72 Dpi in the same scenario:

Original DPI

Another important detail is the IDisposable nature of the Image object.

When you create one, you have to Dispose() of it; explicitly, calling the Dispose method, or implicitly, enclosing the Image contructor in a Using statement.

Also, possibly, don't assign an Image object directly loaded from a FileStream.

GDI+ will lock the file, and you will not be able to copy, move or delete it.

With the file, all resources tied to the Images will also be locked.

Make a copy with new Bitmap() (if you don't care of the above mentioned details), or with Image.Clone(), which will preserve the Image Dpi Resolution and PixelFormat.

Canvas context.drawimage doesn't draw on the right coordinates

You probably forgot to define a size for the canvas bitmap, and is only using CSS to set the size. Remember that canvas size must set implicit as CSS does not affect its bitmap size.

<canvas id="myCanvas" width=500 height=500></canvas>

If not your bitmap which defaults to 300x150 will be stretched to whatever you set with CSS which means your coordinates will be scaled as well.

CSS should be skipped for this but if you absolutely want to use it set width and height in CSS to the same size as defined for your canvas element.

The mouse position you get will be relative to the window so you need to subtract the canvas position to make it relative to canvas element. You probably have this working already and iHank's example should work, although I would not obtain the context each time:

var canvas = document.getElementById('myCanvas'),    ctx = canvas.getContext('2d');
canvas.addEventListener('click', mouseClick, false);
ctx.strokeRect(0, 0, canvas.width, canvas.height);
function mouseClick(e) {
var rect = canvas.getBoundingClientRect(), x = e.clientX - rect.left, y = e.clientY - rect.top; // draw image here, for demo - drawn from corner not center: ctx.fillRect(x, y, 5, 5); }
Canvas: <canvas id="myCanvas" width=500 height=180></canvas>

The image gets drawn at the wrong position

Of course you must draw a cursor in a relative position - not global:

    p = m.getPointerInfo();
Point location = p.getLocation();

gives you mouse position on screen (global).
Mouse position in your image coordinates (relative) would be something like:

    int x = (int) (p.x - recordingArea.getX()); //for int y similar
if(x < 0 || y < 0 || y >= maxHeight || x >= maxWidth) { // don't draw cursor }

The image drawn in pygame does not match the location it is given

The image has a size. it may happen that the image is out of the window at the right or at the bottom. The origin of the blit puts the the top left corner of the image to the specified position.

If you wan that the image is centered at (x, y), the you have to get a pygame.Rect with the size of the image (get_rect) and set the center of the rectangle to the specified position (keyword argument). Use the rectangle to specify the position for the blit operation.

img_rect = targetpng.get_rect(center = (x, y))
game_display.blit(targetpng, img_rect)

Th image has a size, thus the random position for the image has to be in range [image_size/2, window_sizw - image_size/2].

The width and height of a pygame.Surface can be get by get_width()/get_height() or get_size(). For instance:

img_size = targetpng.get_size()
x = random.randrange(img_size[0]//2, display_width - img_size[0]//2)
y = random.randrange(img_size[1]//2, display_height - img_size[1]//2)


Related Topics



Leave a reply



Submit