3

I have a design with widths, heights, paddings... in millimeters. I'm now trying to figure out how to convert those numbers to the logical pixel system Flutter uses.
I found the docs for the device pixel ratio but I'm not sure how to interpret that number and I quote:

The Flutter framework operates in logical pixels, so it is rarely necessary to directly deal with this property.

So I am not sure if this is the way to go.
My question comes down to this: Is there an easy way to calculate from millimeter to logical pixels that works for both Android and iOS?

Hrishikesh Kadam
  • 35,376
  • 3
  • 26
  • 36
Bram Vanbilsen
  • 5,763
  • 12
  • 51
  • 84

4 Answers4

6

Flutter's unit is DP or dip (aka density independent pixels). Like it's name is implying, it's independent from the screen pixel ratio.

What's the difference with millimeters ? None really important. Converting mm>dp or dp>mm is similar to mm>inch/inch>mm.

The relationship between them is fairly simple :

1 inch = 25.4 mm = 160.0 DP

Which means 1 mm = 6.299 DP

Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
5

I would say the current accepted answer is not really accurate.

You can print the number of logical pixels for real phones, like this:

maxWidth = MediaQuery.of(context).size.width; 
maxHeight = MediaQuery.of(context).size.height; 
print("maxWidth = $maxWidth / maxHeight = $maxHeight");

I would appreciate if someone with real iPhones and iPads could run this code and tell me the resulting maxWidth and maxHeights. So far, with Android phones, I've compiled the results comparing with the real phone sizes. What I got is this:

  • Galaxy S6 ➜ 5.668537826 dp/mm for height, and 5.668537826 dp/mm for width.
  • Galaxy S7 ➜ 5.668537826 dp/mm for height, and 5.668537826 dp/mm for width.
  • Galaxy S9 ➜ 5.223614747 dp/mm for height, and 5.585946405 dp/mm for width.
  • Pixel XL ➜ 5.612956709 dp/mm for height, and 6.007177748 dp/mm for width.

See my spreadsheet here: https://docs.google.com/spreadsheets/d/1zmGyeKSf4w4B-bX4HSY4oSuh9RkIIkFwYSd3P9C7eX8/edit?usp=sharing

Update:

Hrishikesh Kadam
  • 35,376
  • 3
  • 26
  • 36
Marcelo Glasberg
  • 29,013
  • 23
  • 109
  • 133
  • Then submit a bug. Because it is supposed to be fixed. Maybe the pixelratio fetched by Flutter is incorrect, leading to invalid numbers. – Rémi Rousselet Jun 01 '18 at 16:33
  • So far, the only place in the docs I found a reference to this is here: https://docs.flutter.io/flutter/dart-ui/Window/devicePixelRatio.html. It says there are roughly 3.8 logical pixels per millimeter. Which is obviously VERY wrong in practice. – Marcelo Glasberg Jun 01 '18 at 16:43
  • Also found it here: https://developer.android.com/training/multiscreen/screendensities#TaskUseDP which says: "One dp is a virtual pixel unit that's roughly equal to one pixel on a medium-density screen (160dpi; the "baseline" density)." – Marcelo Glasberg Jun 01 '18 at 16:57
  • The unit is constant. It's not like pixels. There's no such "Samsung/Google phones have a different dip". That's not possible. – Rémi Rousselet Jun 01 '18 at 17:13
  • Remi, the Wikipedia article you linked says it is 160 dpi, but the SOURCE of the Wikipedia article you linked says it is "roughly" 160 dpi. So the unit is not constant, and the Wikipedia article is wrong. And the reality is that logical pixels are different for each phone, when measured. The reality determines what is possible, not Wikipedia. – Marcelo Glasberg Jun 01 '18 at 18:03
  • 160 DP is equal to 1 inch. That's the specs of the unit. It never ever change. That's the whole purpose of using that unit. – Rémi Rousselet Jun 01 '18 at 19:57
  • DP to px/inch/mm converter based on pixel density : http://angrytools.com/android/pixelcalc/ – Rémi Rousselet Jun 01 '18 at 20:11
0

Logical pixel is the ratio of dots per unit distance(mm), so you have to change your question to How many dots per mm represents 1 logical pixel?

As it is mentioned here

Flutter follows a simple density-based format like iOS. Assets might be 1.0x, 2.0x, 3.0x, or any other multiplier. Flutter doesn’t have dps but there are logical pixels, which are basically the same as device-independent pixels. The so-called devicePixelRatio expresses the ratio of physical pixels in a single logical pixel.

And as mentioned 1.0x logical pixel ratio represents mdpi in Android density qualifiers. And according to this, mdpi ≃ 160DPI and as dpi represents the number of individual dots that can be placed in a line within the span of 1 inch (2.54 cm) so:

160dpi = 160 dots per inch = 6.299 dots per mm

And as mdpi ≃ 160DPI and 1 logical pixel represents mdpi so:

1.0x logical pixel ratio ≃ 6.299 dots per mm
MahMoos
  • 1,014
  • 9
  • 16
0

To display a widget at a real size.

double millimeterToSize(double millimeter) => millimeter * 160 * 0.03937;
lsaudon
  • 1,263
  • 11
  • 24