Flutter MediaQuery.of(context).size.width values are different than real screen resolution - flutter

in my Flutter application I am trying to get the real screen width (that can naturally be different on each device).
I am using MediaQuery.of(context).size.width but I've noticed that the values returned do not match the real screen resolution.
For instance,
On an simulator iPhone 11 Pro Max (that has resolution 2688 x 1242) I get MediaQuery.of(context).size.width= 414
On an emulator Nexus XL (that has resolution 1440 x 2560) I get MediaQuery.of(context).size.width = 411.42857142857144
On a real device iPhone 7 (that has resolution 1,334 x 750) I get MediaQuery.of(context).size.width = 375
Does anyone know why the value returned by MediaQuery differ from the real screen resolution in pixels?
Thanks

According to the size property's documentation :
The size of the media in logical pixels (e.g, the size of the screen).
Logical pixels are roughly the same visual size across devices.
Physical pixels are the size of the actual hardware pixels on the
device. The number of physical pixels per logical pixel is described
by the devicePixelRatio.
So you would do MediaQuery.of(context).size.width * MediaQuery.of(context).devicePixelRatioto get the width in physical pixels.

Related

Unity's Screen.width / Screen.height doesn't reflect my android device size

I'm using Galaxy22 Ultra so
on unity,
Debug.Log(Screen.width+"///????/"+Screen.height);
Debug.Log(Screen.currentResolution);
both says
width : 1080
height : 2316
which is not even reflect cellphone's ratio...
if width is really 1080pixel then height should be maybe 3 or 4 times bigger.
how can I get real pixel size of width and height
seems likely Galaxy S22 Ultra native resolution is 3088 x 1440. But the OS maybe reduce it to standard resolution 1080 width, this would be 75% of original size.
Thus 3088 x 1440 (75%) will be 2316 x 1080 correctly.
Screen.width // this only return your rendering screen width
Usually, some mobile will optimised the performance by reducing rendering result from native resolution.
And surely your phone screen ratio won't be 3:1 or 4:1. Normally they are between 16:9(or 1.7:1) to 21:9(or 2.3:1).

Images being upscaled in Flutter

I have images stored as blobs in SQLite. Other tools like DB Browser for SQLite show the images themselves are not upscaled.
I scaled them down from an original image with the following code.
final thumbnailData = encodeJpg(copyResize(
decodeImage(imageData),
width: 400,
interpolation: Interpolation.average
));
When displayed in Flutter they are noticably upscaled.
#override
Widget build(BuildContext context) {
return Image.memory(_getThumbnailData());
}
Image.memory() has a scale argument that defaults to 1.0. Setting it manually to be sure doesn't help either.
I have to set it to some guesstimated value like 2.0 to get the correct scale but I don't understand why and wether 2.0 is actually "unscaled" or still slightly off.
How can I tell Flutter to display the images as they are?
Flutter uses logical pixel instead of physical pixels.
Device pixels are also referred to as physical pixels. Logical pixels are also referred to as device-independent or resolution-independent pixels.
How to convert between physical pixels and logical pixels?
To convert between physical pixels and logical pixels, you can use devicePixelRatio.
The number of device pixels for each logical pixel. This number might not be a power of two. Indeed, it might not even be an integer. For example, the Nexus 6 has a device pixel ratio of 3.5.
MediaQuery.of(context).devicePixelRatio

Get physical size of screen in flutter

I am building a flutter application that needs precise measurements of the screen in cm / inches.
According to the docs,
By definition, there are roughly 38 logical pixels per centimeter, or about 96 logical pixels per inch, of the physical display. The value returned by devicePixelRatio is ultimately obtained either from the hardware itself, the device drivers, or a hard-coded value stored in the operating system or firmware, and may be inaccurate, sometimes by a significant margin.
I have tried using these ratios in my application but they are not even close.
Is there a way to accurately calculate the dimensions of the screen?
Flutter's pixel coordinates are given in logical pixels rather than physical pixels. However, MediaQuery will give you the conversion ratio.
var mediaQuery = MediaQuery.of(context);
var physicalPixelWidth = mediaQuery.size.width * mediaQuery.devicePixelRatio;
var physicalPixelHeight = mediaQuery.size.height * mediaQuery.devicePixelRatio;
(Note that this code can only be run in a place where a BuildContext object is available, such as a build method or a StatefulWidget's companion State class.)

How logical pixels translate to physical pixels

First question:
If I create a Container widget with width set to 50 (logical pixels), how many physical pixels will this widget occupy eventually?
It is correct to assume the answer will be 50*devicePixelRatio and it will be rounded off to an integer value?
Second question:
This question technically arises from the first question. Let say we have 2 devices and each has the same screen width , same resolution but different screen height. In theory, the width value in logical pixels should be the same for both devices right.
However, one devicePixelRatio will be higher. Hence, the eventual width value in physical pixels will be different and this might cause one of the Container to overflow since my assumption is that the eventual Container widget width will be multiplied by the devicePixelRatio.
It is correct to assume the answer will be 50*devicePixelRatio and it will be rounded off to an integer value?
Yes
This question technically arises from the first question. Let say we have 2 devices and each has the same screen width , same resolution but different screen height. In theory, the width value in logical pixels should be the same for both devices right. However, one devicePixelRatio will be higher. Hence, the eventual width value in physical pixels will be different and this might cause one of the Container to overflow since my assumption is that the eventual Container widget width will be multiplied by the devicePixelRatio.
Let's say
dvp = 1 for first device and dvp = 2 for second. So a width of 50 in first phone will be
1 * 50 = 50 device pixels
And for second device it would be
2 * 50 = 100 device pixels
But it does NOT mean Container width is going to be 2x on second phone and you may run in overflow error. Not at all!!!
Actually in first phone 50 device pixels are used to create 50 logical pixels box(less sharpness) and in second phone 100 device pixels are used to create 50 logical pixels box(more sharpness)

use ppi to get logical resolution

I am trying to emulate the Samsung Galaxy Tab S 10.5 , and I have no idea what the screen resolution is to create an emulator. This model seems to be left off any list I found.
Full Spec & Details http://www.gsmarena.com/samsung_galaxy_tab_s_10_5-6438.php
The screen has been given the specs:
2560 x 1600 pixels, 10.5 inches (~288 ppi pixel density)
If I use 2560 x 1600 pixels as the screen size, its obviously too big. How can I work out its Device pixel Ratio? Does the ppi have anything to do with it?
The Nexus 10 is 1280 x 800, but how can I get an exact for this or any device?
EDIT
Looking at the Nexus 10 (also made by samsung), it has the same 2560 x 1600 pixels, a Device pixel Ratio of 2, a slightly smaller screen, and a slightly bigger ppi of 300. So it would make sense this tab would also be Device pixel Ratio of 2. But is there a way to work out Device pixel Ratio from specs?