Calculate logical pixels from millimeters - dart

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?

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

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:
Android docs (https://developer.android.com/training/multiscreen/screendensities#TaskUseDP) say "One dp is a virtual pixel unit that's roughly equal to one pixel on a medium-density screen (160dpi; the "baseline" density)". That's obviously not true in practice for Samsung and Google phones. Or it is, if you pay attention to the word "roughly".
Flutter docs (https://api.flutter.dev/flutter/dart-ui/FlutterView/devicePixelRatio.html) say it's 3.8 logical pixels per mm, which is obviously very false.

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

To display a widget at a real size.
double millimeterToSize(double millimeter) => millimeter * 160 * 0.03937;

Related

Dynamically find a value in between a range of Values in Google Sheets

In google sheets, I have a data set that identifies historical pricing multiplyers for a product in certain size ranges. I'm using square inches in this case. The data is set up in a table like this:
Data set
What I've done is create a formula that allows me to specify any width, height and quantity, find the current square inches, then find the corresponding price for this specific sized product based on where it falls on the range of sizes that I've provided in the data set.
For example, if the square inches equals 150, the price for this size is .6 (or 60 cents) per square inch. (90)
I've already solved this. This is the formula I have:
=(A10*B10)*C10)*(filter(C2:C6,A2:A6<=((A10*B10)*C10),B2:B6>((A10*B10)*C10))
In this example, A10 = height, B10 = width, and C10 = quantity
So, like I said, this works just fine. My problem is that a product with a square inch value of 105 will ultimately have the same cost per square inch as a product with a square inch value of 214. It's only after it crosses the 250 square inch threshold that my cost per square inch will change.
Is there a way to dynamically find the appropriate multiplyer, so that, for instance, a square inch value of 175, would have a multiplyer between .8 and .6 since it falls in the middle of 100 square inches and 250 square inches?
I will try to assume that you have some kind of calculator for calculating coefficients.
If value of the area in C13 then in A16:C17 we can get the calculate range. Put in to A16
=ARRAY_CONSTRAIN(OFFSET(A2:C6,MATCH(C13,A2:A6,1)-2,0),2,3)
After that we can calculate part of price
=IF(ISNUMBER(A16),C16-(C16-C17)*(C13-A17)/(B17-A17),C17)
One formula solution
=VLOOKUP(C13,B2:C6,2)-
(VLOOKUP(C13,B2:C6,2)-VLOOKUP(C13,A2:C6,3))*
(C13-VLOOKUP(C13,A2:C6,1))/
(VLOOKUP(C13,A2:C6,2)-VLOOKUP(C13,A2:C6,1))
The best solution is use a TREND. It's very clear.
=TREND(
OFFSET(B2,MATCH(C13,B2:B3)-1,1,2,1),
OFFSET(B2,MATCH(C13,B2:B3)-1,0,2,1),
C13
)
My sample
References
VLOOKUP
ARRAY_CONSTRAIN
OFFSET
TREND
I trust you'll forgive me if I don't explain the math involved, but this formula should produce the result you want:
=(A10*B10*C10)*(VLOOKUP(A10*B10*C10,A2:C6,3,TRUE)+(((A10*B10*C10)-VLOOKUP(A10*B10*C10,A2:A6,1,TRUE))*(ABS(VLOOKUP(A10*B10*C10,A2:C6,3,TRUE)-INDEX(C2:C6,MATCH(VLOOKUP(A10*B10*C10,A2:C6,3,TRUE),C2:C6,0)-1))/(VLOOKUP(A10*B10*C10,A2:B6,2,TRUE)-VLOOKUP(A10*B10*C10,A2:A6,1,TRUE)))))

JPEG2000 : Can number of tiles in X direction be zero?

According to JPEG2000 specs, Number of tiles in X and Y directions is calculated by following formula:
numXtiles =  (Xsiz − XTOsiz)/ XTsiz
&
numYtiles =  (Ysiz − YTOsiz)/ YTsiz
But it is not mentioned about the range of numXtiles or numYtiles.
Can we have numXtiles=0 while numYtiles=250 (or any other value) ?
In short, no. You will always need at least one row and one column of tiles to place your image in the canvas.
In particular, the SIZ marker of the JPEG 2000 stream syntax does not directly define the number of tiles, but rather the size of each tile. Since the tile width and height are defined to be larger than 0 (see page 453 of "JPEG 2000 Image compression fundamentals, standards and practice", by David Taubman and Michael Marcellin), you will always have at least one tile.
That said, depending on the particular implementation that you are using, there may be a parameter numXtiles that you can set to 0 without crashing your program. In that case, the parameter is most likely being ignored or interpreted differently.

How are the keys CIDetectorMinFeatureSize and CIDetectorAspectRatio used for CIDetector?

How is CIDetectorMinFeatureSize supposed to be used when setting up a CIDetector for either face or rectangle recognition? The description at Apple does not tell me anything:
A key used to specify the minimum size that the detector will
recognize as a feature.
The value for this key is an NSNumber object ranging from 0.0 through
1.0 that represents a fraction of the minor dimension of the image.
The documentation says it ranges from 0.0 to 1.0 and then I look at the WWDC slides of session 514 and they set the value to "100"...?
It is as much a secret to me as the (undocumented?) CIDetectorAspectRatio.
Let's say I'm trying to detect an A4 paper sheet which is 30cm x 21cm and has an aspect ratio of 1.4 - what would I set for the two keys?
CIDetectorAspectRatio is used by CIRectangleDetector to constrain the search. In your example, the value of the CIDetectorAspectRatio key should be #(1.43).
The CIDetectorMinFeatureSize is also used to constrain the search. Only a rectangles greater than the specified fraction of the input image size will be returned
In the documentation you can find about "CIDetectorAspectRatio" :
An option specifying the aspect ratio (width divided by height) of rectangles to search for.
The value of this key is an NSNumber object whose value is a positive floating-point number. Use this option with the CIDetectorTypeRectangle detector type to fine-tune the accuracy of the detector. For example, to more accurately find a business card (3.5 x 2 inches) in an image, specify an aspect ratio of 1.75 (3.5 / 2).
Available in iOS 8.0 and later.
enter link description here

Relation between Pixels and Points in blackberry

I need to know the relation between points and pixels and how it affects different BB 7.0 and lower version devices.
I have a project which parses values of width and height of components to be displayed in points and I have converted them into pixels and shown on different devices using the following formula.
fldwidth = fldwidth*Display.getWidth()/100
fldheight = fldheight*Display.getHeight()/100
where initially the values of fldwidth and fldheight has pt values in decimal.
Am I correct
A point is, by definition, 1/72 of an inch - see Wikipedia Point_(typography)
The size of pixel is dependent on the screen resolution on the device. Just to be clear, this is resolution normally stated in dots per inch (dpi). This is not the common usage for the term resolution which is the pixel height and width of the screen. People use resolution in this way incorrectly. Resolution is the density of dots on the screen, not the number of pixels on the screen.
The point here is that there is NO relationship between the number of pixels displayed on the screen with the number of pixels that are required for a point. You can not use the conversion that you are attempting.
To determine the number of pixels that match 1 point, you must get the resolution of the screen. BB provides two methods for this:
Display.getHorizontalResolution();
Display.getVerticalResolution();
Fortunately, these will give you the same value on all BBOS (Java) devices, as all BBOS devices have the same vertical and horizontal resolution.
The value supplied is the number of pixels in one metre. So all you need to do is determine how many 1/72s of an inch there are in 1 metre, divide one of these values by that number, and then you have the number of pixels in a point.
Because of integer arithmetic, when doing this calculation, I would multiply by the point size you are trying to achieve before doing the division. For example:
int pixelSizeReqd = pointSizeReq *
Display.getHorizontalResolution() / pointsInOneMetre;
And by the way, just call Display.getHorizontalResolution() once and reuse the returned value. I am not sure about getHorizontalResolution(), but I do know that some Display methods, for example, getHeight() and getWdith() are 'expensive' so should be avoided if possible. The value is not going to change anyway!
Update following this comment:
Can you explain in an example . Suppose I got a device 8520 (320x240 resolution) i have a point (say 57pt) what would be its corresponding pixel value as per your formula ... int pixelSizeReqd = pointSizeReq * Display.getHorizontalResolution() / pointsInOneMetre
Answer:
Note that the 8520 has a screen size of 320 x 240. That is not its screen resolution for the purposes of this discussion. Got that?
You want a size of 57 points. So the calculation is:
int pixelSizeReqd = 57 * Display.getHorizontalResolution() / pointsInOneMetre;
You shouldn't replace Display.getHorizontalResolution() with a figure - it will be different on different devices and there is no need for you to try to fix this value for yourself.
How many points are there in 1 metre? You can do the math, convert a 1/72 inch into metres and then divide 1 metre by this. Or you can type into Google "how many points in a meter" and get the answer 2,834.64567. We don't need the accuracy, so we just use integer arithmetic to give us this:
int pixelSizeReqd = 57 * Display.getHorizontalResolution() / 2834;
Job done - that wasn't too hard was it?

How to get font size in delphi

I am looking for a function which should take parameters as Font name, sample character, width, height of the sample character and should return Font Size.
It must look like this:
GetFontSize(<Font Name>, <Sample Character>, <Sample Character Width>,
<Sample Character Height>)
which must return the font size,
Is this possible in delphi?
You may want to take a look at this page that discusses font size and points.
It uses the following to convert between the points and pixel size:
Arial 12pt at 96 dpi:
font size in points 12
font size in pixels = ------------------- × 96 dpi = ---- × 96 = 16 pixels
72 points per inch 72
You could use that for your conversion. You just need to be aware of possible differences in your screen dpi as Blorgbeard stated. Points are usually used to describe the size on paper. You need to decide how you want to map that to the screen. For example many programs will allow you to set a zoom level. That does not change the printed size on paper but does affect the pixel height on the screen.
Depending on what you are trying to accomplish you may need to get the actual sizes of the font. If you are trying to find out exactly how the font is put together take a look at Obtaining Font Metrics The code on that page uses the .Net libraries but it has a good explanation. If you want to get the Text Metrics in Delphi you would use the GetTextMetrics function.
As Rob stated in his comment you can draw text at a specific height by setting the Font.Size property to the negative height in pixels. Windows will then draw the text out at that height. In that case you don't need a specific letter or the width as you have in your prototype function. For a given font size each letter will have a different height and width. I.E. capital letters will be taller than lower case letters and letters like "W" will be wider than letters like "i".
I'm only aware of methods to do the opposite - that is, to get pixel sizes from point sizes.
The only way I can think of is to set up a TCanvas, and repeatedly call GetTextExtent on it, changing the font size each time, until you get a size that's acceptably close to what you want.
Depending on how accurate you need this, you could just convert your desired height in pixels to points - a point is 1/72 of an inch, and your screen is probably 96 pixels per inch (but check GetDeviceCaps to get the real figure). See this question.
That would get you a font size pretty close to the pixel size you want.

Resources