Android Question [absolutly NOT solved] About dpi (night question!)

LucaMs

Expert
Licensed User
Longtime User
The display of my laptop has 92 dpi: how many dips are they on a smartphone?

I know, it depends on the characteristics of the display of the smartphone.
But I guess there is a way to make this calculation.

I'm sure that some super expert (Klaus ;) ) already has the answer.

[I forgot one important thing: actually, I would need to know the relationship between the pixels on my laptop and dips.]
 

LucaMs

Expert
Licensed User
Longtime User
Probably that is really a night question!

Probably i should just take in account the relationship: 92dpi (laptop) : 160dip (android - for standard variant)


Probably...but it is not right!

I drew a picture on my laptop which has rows 28 pixels high.

Now, I want to write on that picture, but on the Android device.

The emulator scale = 1, then 160dip. My laptop (current resolution) has 92dpi.

So I thought: 28pxs : 92dpi = X : 160dip
then X = 28 x 160/92

The factor 160/92 multiplied by the number of pixels (28).

Those 28 pixels should therefore be worth 48.6956dpi, but it is not:
the written lines are too close together, the right value should be higher.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Usually a PC has 72dpi (some time 96) but dpi is irrelevant on screens. It only matters when printing.

A 100px x 100px image is always 100px x 100px on a pc screen.

But sadly i´m not able to give you an solution to calculate the imagesize for Android screens :(
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I have:

loaded a layout: 1024x600 Scale 1, which contains only one button;

created (PC) a simple image 1024px x 600px (WxH), with 10 rows of 60px;
loaded it as a background of the Activity:
B4X:
Private db As BitmapDrawable
    db.Initialize(LoadBitmap(File.DirAssets, "rows.png"))
    Activity.Background = db

scaled the Activity:
B4X:
Scale.SetReferenceLayout(1024, 600, 1, True, False)
    Scale.ScaleAll(Activity, True)
(the two Boolean parameters are respectively FullScreen and ShowTitle);

in spite of the Scale, I placed the button:
B4X:
btnAppExit.Left = 50%x - btnAppExit.Width / 2
    btnAppExit.Top = 100%y - btnAppExit.Height

wrote 10 lines of text.
B4X:
Private Sub WriteText
    Private cnv As Canvas
    cnv.Initialize(Activity)
  
    Private X,Y As Float
    Private RowHeight As Float
    RowHeight = 60dip
    X = 5dip
    Y =  RowHeight - 1dip
  
    cnv.DrawText("First text", X, Y, Typeface.DEFAULT, 22 * Scale.GetScaleTxt, Colors.Blue, "LEFT")
    For r = 1 To 9
        Y = Y + RowHeight
        cnv.DrawText("Other " & r, X, Y, Typeface.DEFAULT, 22 * Scale.GetScaleTxt, Colors.Blue, "LEFT")
    Next
End Sub


These are the results on two emulators:
5554 = 1024x600 Scale 1
5556 = 1024x600 Scale 1.5

upload_2014-6-28_11-41-5.png


The jpg background adapts automatically, without any intervention.

Part (50%?) of the button is out. [It is only too little, but in the right position.]
 

Attachments

  • lm rows.zip
    12.1 KB · Views: 188
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Probably I found the errors.

One is a little error in the SetReferenceLayout of Scale module.

The second should be that Canvas functions probably internally uses Dip, so I should use absolute values; no dip, no other scale factors.

Setting 60 for RowHeight in the first example, all it's ok, on both emulators (scale 1 and scale 1.5)
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I would do it that way:
B4X:
Private Sub WriteText
    Private X,Y As Float
    Private RowHeight, TextSize As Float
    Private lv As LayoutValues
  
'    RowHeight = 60dip
    RowHeight = Activity.Height / 10
    X = 5dip
    lv = GetDeviceLayoutValues
    TextSize = RowHeight / lv.Scale * 0.8
    Y =  RowHeight *  0.75
  
'    cnv.DrawText("First text", X, Y, Typeface.DEFAULT, 22 * Scale.GetScaleTxt, Colors.Blue, "LEFT")
    cnv.DrawText("First text", X, Y, Typeface.DEFAULT, TextSize, Colors.Blue, "LEFT")
    For r = 1 To 9
        Y = Y + RowHeight
'        cnv.DrawText("Other " & r, X, Y, Typeface.DEFAULT, 22 * Scale.GetScaleTxt, Colors.Blue, "LEFT")
        cnv.DrawText("Other " & r, X, Y, Typeface.DEFAULT, TextSize, Colors.Blue, "LEFT")
    Next
End Sub

This works on different screen sizes.
The RowHeight is defined by Activity.Height / NumberOfLines
And the TextSize is calculated in function of the RowHeight.
You can play with the two factors 0.8 and 0.75
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I would do it that way:

This works on different screen sizes.
The RowHeight is defined by Activity.Height / NumberOfLines
And the TextSize is calculated in function of the RowHeight.
You can play with the two factors 0.8 and 0.75

Thanks for your interest, Klaus (not, from now I WANT write: eng. Klaus!)

Your code surely solve that case, but what I'm trying to understand is the relationship between pixels (PC) and dpi (Android).

In fact, I could not solve the second example in that way.


Thanks again.

[P.S. your solution is like to use percentages, wich is the best solution almost in every case, I think, but, maybe I'm wrong, it would be useful or necessary a function to calculate the relationship between the pixels of the two different devices, pc and android]
 
Last edited:
Upvote 0

klaus

Expert
Licensed User
Longtime User
What exactly do you want to do ?
What relationship do you expect between the PCC and your device ?
In your example it would be more efficiant to draw the lines directly onto the device instead of using a bitmap, even for a somewhat more complex layout.

In your example you have a bitmap with following dimensions: 1024px x 600px, but you set it 100%x and 100%y so it is for sure mostly not the same on any device screen.
If you have an Activity different from the given size values your code won't work.
The example I posted adjusts the TextSize acording to the 'line height', independant of the screen size and its density.
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Unfortunately, I fear that the language is a problem.
I tried to explain in the various posts.

The example of the lines is just one example: in fact, I've posted another to make it clear that I did not need to solve the first.

I try to explain.

Take the house map. We could know all the dimensions of the walls of the rooms, in pixels. Let us assume, by hypothesis, to have a device with the exact dimensions of the map and density 160dpi.

Let's say that I want to draw a rectangle in one of the rooms of the same size of the room.

The sides of the room are in pixels of the PC but I will have to draw in dpi.

If the room has a side of 100 pixels, how much should be the side drawn into the device? 100dpi? I do not think so.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Other example: I want to draw a rectangle on the terrace.

Terrazzo - terrace (pixels):

Hor. internal sides:
50,56 to 212,56 (top)
50,538 to 212,538 (bottom)

Ver. internal sides:
50,56 to 50,538 (left)
212,56 to 212,538 (right)


Emulators:
5554 1024x600 - 160
5556 1024x600 - 240
5558 800x1280 - 213 (rotated)

5554 empty:
upload_2014-6-29_1-28-19.png



Using absolute values:
upload_2014-6-29_1-30-58.png



Using Scale.GetScaleX and Scale.GetScaleY:
upload_2014-6-29_1-32-5.png
 

Attachments

  • lm apartment.zip
    165.3 KB · Views: 209
Upvote 0

klaus

Expert
Licensed User
Longtime User
The scales are simply:
ScaleX = 100%x / 1024
ScaleY = 100%y / 600


Attached you find a modified version of your project.
It has a cursor to measure the coordinates on the graphic with original pixel and meter scale.
 

Attachments

  • lm apartment_NEW.zip
    162.1 KB · Views: 191
  • Appartment.png
    Appartment.png
    73.8 KB · Views: 166
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Great job, eng. Klaus (as usual ;))

I think (hope) that this is an interesting topic.

I have some doubts and questions.

1) My serious mistake. I can not put the image in full screen on any screen, of course, given the different proportions.
Using that image, the error is not very evident, but it is by drawing a circle (into the image file).
I need to study your code better, but perhaps it can be also in your project.
I should size the image in relation to the side of the panel which differs less. (I can not explain well, unfortunately).

2) I have to search the site: how to know the size of the image in the file? You have used literals 1024 x 600, but, for the moment, I do not know how to get them in code.

3) how you calculated that ScalePixelMeter? :D

4) the cursor with the mouse works fine on the emulator; you (we) should invent something for fingers. That is, you can not see the cross, under the finger (can I define it "offset"?)


(for me all this is for educational purposes only. It is not a necessity or a project, so we can proceed slowly ;))


Thank you again for your interest, eng. Klaus.
 
Upvote 0
Top