Get the true size in pixels of image that uses canvas scaler.

I wanted to give an update to this thread. I found the definite issue. The problem is in the Unity editor screen scaling is automatically applied if you’re using the stand alone mode.

The issue is I wanted the true size of the image according to it’s actual pixel size on screen. The actual pixel size and what’s being returned by multiplying the image width by the canvas X scale differ because the Unity editor applies scaling.

That’s why actual image width was 312 but showing as 960 according to the formula. A simple mistake on my behalf but it through me for a loop.

Hi, I thinked about the same.

Here is what I’m using and it’s working perfectly:
Vector2 sizeDelta = GetComponent().sizeDelta;
Vector2 canvasScale = new Vector2(canvas.transform.localScale.x, canvas.transform.localScale.y);

Vector2 finalScale = new Vector2(sizeDelta.x * canvasScale.x, sizeDelta.y * canvasScale.y);

If the object also have a scale I don’t know if it should be multiplied. Hope it helped.

4 Likes

I actually figured it out. It has to do with the scale mode setting as well. There are several different options so the formula changes for each one. You have to multiply the x and y by the scale factor and if you have it set to match width/height you need to scale in the percent to whatever the current settings are.

It’s definitely not direct. There should be a more direct way to do this.

Multiplying by Canvas.scaleFactor should be all that is needed, bypassing CanvasScaler entirely.

3 Likes

Exactly what I was missing to make my tooltip work, thank you!

that is not entirely true, as this works only if the aspect ratio stays the same between reference resolution and the target-display.
If your application runs on different mobile devices, the aspect ratio is different for many devices and the reported scaling-factor only matches one dimension. Especiall between devices like iPad and something like Pixel3 the aspect ratio differs a lot and causes serious scaling problems, and Im still looking for a good solution to get around this problem.

1 Like

@RichardNemeth This is working fine. Thanks for your reply i really appreciate for you work

That did the trick. Thanks dude. I’ve been searching for hours. :smile:

so what is the resulting answer guys?

This will only work if all your anchors are at the same coordinate, if they’re not, you’ll get an unusable sizedelta value, or even 0 if anchors are at the corners of the rect.

here you go, this method will give you bounds of UI.

public static Vector2 GetBoundsOfUI(RectTransform UI)
{
Vector2 MaxPoint;
MaxPoint.x = Mathf.Lerp(0, Camera.main.pixelHeight,UI.anchorMax.x);
MaxPoint.y = Mathf.Lerp(0, Camera.main.pixelHeight,UI.anchorMax.y);

Vector2 MinPoint;
MinPoint.x = Mathf.Lerp(0, Camera.main.pixelHeight,UI.anchorMin.x);
MinPoint.y = Mathf.Lerp(0, Camera.main.pixelHeight,UI.anchorMin.y);

return MaxPoint-MinPoint;
}

I think i found a batter way, if you simply want the size in pixel you can get those by RectTranform.rect.size.
It worked well for me.

For anyone else who sees this thread, there is an API method for this: GetWorldCorners. This gives you the screen space corners (for an Overlay canvas).

There is a lot of conflicting information here.

@Robert7501 an overlay or Camera canvas will always have the same scale for X and Y. A CanvasScaler never changes the aspect ratio of a pixel, only the ratio of the canvas width and height.

The Canvas aspect ratio is set by:

  • the screen when in Overlay mode
  • the camera when in Camera mode
  • the RectTransform component when in World mode

Again, the CanvasScaler by itself is incapable of skewing/stretching/squashing pixels

@SpicyCatGames you are entirely correct, SizeDelta does not give the actual pixel width of a RectTransform, only the offset compared to the anchor points.

The actual solution, assuming nothing but the Canvas is scaled, and no rotations are used, is:

rectTransform.pixelRect.size * rootCanvas.scaleFactor

For an image, it is simply

image.canvas.scaleFactor * image.rectTransform.pixelRect.size