I'm trying to design a responsive UI for my game.
I'd like that UI elements are scaled when screen resolution is below a certain threshold and repositioned otherwise.
Let's see it in an example.
I assume that the resolution of 1600 x 900 is the one below which UI elements must be scaled down keeping their aspect ratio.
In the following images, you can see the size that the red and the green panels should take at different resolutions (1600 x 900 in the former, 1280 x 720 in the latter).
On the contrary, when the screen resolution is greater than 1600 x 900 the panels should be simply reposed, without being scaled.
You can see an example, for a resolution of 1920 x 1080, in the following image.
I've been able to realize both logics, but not at the same time.
I've followed this article for repos logic (key point is to have a max size for panels) and Unity UI system tutorial for the scaling logic.
You could have 2 sets of prefab, one for each version and then swap them as needed depending on resolution.
This could be implemented by always having both canvases on the screen but only having the one shown that is supposed to be active in the current screen resolution.
Related
Just a straight forward question. I´m trying to make the best possible choice here and there is too much information for a "semi-beginner" like me.
Well, at this point, I´m trying with screen size values for my layout (activity_main.xml (normal, large, small)) and with different densities (xhdpi, xxhdpi, mhdpi) and, if a can say so myself, it is a mess. Do I have to create every possible option to support all screen sizes and densities? Or am I doing something really wrong here? what is the best approach for this?
My layouts are now activity_main(normal_land_xxhdpi) and I have serious doubts about it.
I´m using last version of android studio of course. My app is a single activity with buttons, textview and others. Does not have any fragments or intents whatsoever, and for that reason I think this has to be an easy task, but not for me.
Hope you guys can help. I don't think i need to put any code here, but if needed, i can add it.
If you want to make a responsive UI for every device you need to learn about some things first:
-Difference between PX, DP:
https://developer.android.com/training/multiscreen/screendensities
Here you can understand that dp is a standard measure which android uses to calculate how much pixels, lets say a line, should have to keep the proportions between different screensizes with different densities.
-Resolution, Density and Ratio:
The resolution is how much pixels a screen has over height and width. This pixels can be smaller or bigger, so for instance, if you have a screen A with 10x10 px whose pixels are two times smaller than other screen B with 10 x 10 pixels too, A is two times smaller than B even when both have 10 x 10 px.
For that reason exists the meaning Density, which is how much pixels your screen has for every inch, so you can measure the quality of a screen where most pixels per inch (ppi) is better.
Ratio tells you how much pixels are for height as well as width, for example the ratio of a screen of 1000 x 2000 px is 1:2, a full hd screen of 1920 x 1080 is 16:9 (16 pixels height for every 9 pixels width). A 1:1 ratio is a square screen.
-Standard device's resolutions
You can find the most common measurements on...
https://material.io/resources/devices/
When making a UI, you use the DP measurements. You will realize that even when resolution between screens are different, the DP is the same cause they have different densities.
Now, the right way is going with constraint layout using dp measures to put your views on screen, with correct constraints the content will adapt to other screen sizes
Anyway, you will need to make additional XML for some cases:
-Different orientation
-Different ratio
-Different DP resolution (not px)
For every activity, you need to provide a portrait and landscape design. If other device has different ratio, maybe you will need to adjust the height or width due to the proportions of the screens aren't the same. Finally, even if the ratio is the same, the DP resolution could be different, maybe you designed an activity for a 640x360dp and other device has 853x480dp, which means you will have more vertical space.
You can read more here:
https://developer.android.com/training/multiscreen/screensizes
And learn how to use constraintLayout correctly:
https://developer.android.com/training/constraint-layout?hl=es-419
Note:
Maybe it seems to be so much work for every activity, but you make the first design and then you just need to copy the design to other xml with some qualifiers and change the dp values to adjust the views as you wants (without making from scratch) which is really faster.
On Mac OS X, I need to convert a point measurement to pixel measurement.
The formula which I know is
pixel = point * resolution (in terms of dpi) / 72
I have few measurements which I want to convert to pixels. Although reverse cases would also be possible.
How to do this in Cocoa or Quartz?
Does it depend on axis? Means would 5 pixels in Y-axis would be same as 5 pixels in X-axis in terms of points? Or is it safe to assume that resolution is same for both X and Y axis?
Please note that I do not want to make any assumption about resolution.
You probably don't want to convert anything to pixels. OS X now works in points; so for example when you draw a rectangle you are giving its dimensions in points, not pixels.
A OS X Quartz point is related to, but not the same as, a (computer) printing point - the two used to be the same, 72 points = 1". However WYSIWYG has become "some scale of" and 72 points (note not pixels) on screen is not a physical inch as screen pixel densities have increased. However 72 points is still an "abstract" inch.
In OS X you draw in points, the OS takes care of mapping those points to the physical pixels on the screen; which roughly translates to screens up to a certain density being treated as 72ppi (pixels/inch) or 1 pixel/point, and higher density screens being treated as 144ppi or 2 pixel/point - for example these are the ppi assigned to standard and Retina screenshots.
If you really, really need to know what a point translates to in pixels you can find out, but this changes depending on what screen a window is on.
For details of all of this you can start with Points Don’t Correspond to Pixels and then read the rest of the High Resolution Guidelines for OS X that reference is part of. How to find point to backing store mapping, if you really, really need to know, is covered.
HTH
There is an opportunity for confusion when your user specifies a length in 'points' as to whether they mean typography points of size 1/72" or lenghts compared to Mac UI points, which vary with the display resolution.
In Mac OS, "points" are pixels, unless you are in high resolution mode, in which case points are 2x2 pixels. The "Points Don't Correspond to Pixels" page says "on a high-resolution display, there are four onscreen pixels for each point," indicating a 4:1 correspondence in hi-res, and 1:1 correspondence in standard res. It also notes:
Note: The term points has its origin in the print industry, which defines 72 points as to equal 1 inch in physical space. When used in reference to high resolution in OS X, points in user space do not have any relation to measurements in the physical world.
To convert a typographer's point size to something physically the same size on a Mac screen in Mac points, your formula is exactly correct. You might rename 'pixel' to Mac points:
MacPoints = (TypesettersPoints/72)*ResolutionInDotsPerInch
Best to stick with points.
First you would need to know where the point is coming from. Views, Windows and Screens all have their own coordinate systems.
You would need to do several things to translate this to the pixel grid of a given screen.
First you need to convert your point to the screen coordinates.
Then to coordinates of pixel grid of the screen.
You will also need to find out the current display properties to know if it's a retina display or not. ( makes a big difference.)
All of the methods are in NSView, NSWindow, NSScreen.
All of the functions are part of Quartz Display services. You will need ones for CGDisplay you might need ones for CGWindow.
You will also need to have your app observe notifications for display configuration changes and figure out the hard part, when a point is in a coordinate space that overlaps two screens.
I leave it to you to do the rest and decide if you really need this.
After reading posts on this site and others, I am uncertain what pixel width I should make for a background cover image. For retina devices it is recommended to create a background image x2 the size if for a non-retina device.
I want to create a background image that will cover the entire screen but this would make a retina device image 2560 x 1760 and non-retina 1920 x 1200 if accommodating large monitors.
Is this too big?
I can't keep the jpeg image file size down to 276KB and that is with the most compression I can apply without destroying the image quality
Well your question is very interesting. To address your comment about what pixel width you should design your background image for. The size of a screen for a laptop, or desktop can vary. So you'll never exactly be able to make a single "universal" image for all backgrounds. Generally diagonal display in inches decides the amount of pixels. My screen is quite large, roughly the biggest size commercially purchased by public. Which is of course 1600 x 900 pixel, 17.3" diagonal display. I wouldn't recommend designing images for any display larger because those displays are custom and more for people who do things like graphic design themselves. Visit http://nodejs.org/logos/ If you scroll down to the computer display, you can see a list of pixel ratios that nodejs designs its logos for. These are very mainstream and popular display sizes. I would recommend you do the same and use those. Hope this answer helped.
Edit: nodejs builds for quality up to 2560 x 1440. If the size of the files doesn't matter. You should easily be able to build for sizes this large. Hope this helped.
With the new screen resolution and aspect ratio of iPhone 5 it seems there are two approaches to take advantage of the new screen real estate when handling images that are full screen (or mostly full screen) images:
Include two images bg#2x.png and bg-h568#2x.png and check the device's main screen bounds to figure out which to load.
Only include the one file but make it the full iPhone 5 resolution
(There are other methods also: stretching, tiling, and / or drawing with Quartz.)
Both of these options have drawbacks:
Including two files is going to increase your app's bundle size
Loading a iPhone 5 retina image on a 4 will clip the image data when displayed on screen, but will still consume the same amount of memory resources
I am particularly interested in understanding the details of the second drawback better.
I am thinking it would save the app bundle (and my designer) if I could use this consolidating images idea further...
Let's say I have an image that take up 320pt x 480pt in portrait and 480pt x 320pt in landscape (width x height).
(EDIT: Initially I hadn't considered a couple of other important tidbits. For sake of completeness, I'm including those thoughts here)
If we create a single image file at a 480pt x 480pt resolution instead of landscape and portrait files, it would prevent the app bundle from having two files that which each contain 320pt x 320pt area of duplicate image data. However, this large square image would include four 80pt x 80pt quadrants in the corners that won't be seen. All things equal, we should still have 20% less image data in the app bundle.
Having re-read Bill's "iBooks Author Experiment", the memory requirements are very easy to figure out:
Landscape or Portrait: 640 * 960 * 4 = 2,457,600
Large Square: 960 * 960 * 4 = 3,686,400
The memory required to load the large square is 50% more then loading the image sized correctly for the screen. Clearly the savings in the app bundle don't measure up to this hit on resources!
But, what about extending this to a giant square that would encompass iPhone 5 and iPhone 4 - 568pt x 568pt? Instead of four files (iP4 landscape, iP4 portrait, iP5 landscape, iP5 portrait), there would be only one file in the app bundle (giant square). The savings could be about 60%.
What about the resources hit?
iPhone 5 Landscape or Portrait: 1136 * 640 * 4 = 2,908,160
Giant Square: 1136 * 1136 * 4 = 5,161,984
That's 110% more memory for iPhone 4, and 77.5% more memory for iPhone 5.
My original question was roughly two parts: 1. Do I understand this correctly and 2. is this tradeoff a wise one to make.
I hope my edits (spurred by Bill's answer) show that I do understand this stuff now. And, if the new found knowledge is correct, then #2 pretty much answers itself. :-)
Generally you get it.
Assuming that you have the big square image and it's some kind of tiled pattern (linen etc) then you could use ImageIO to load the cropped image at the size you need which would use some extra memory decompressing the image but once done it would consume only what is needed to fill the background.
I would suggest against scaling the image.
On the flip side though, shipping an app with 3 images (foo, foo#2x and foo-h568#2x) instead of 1 makes way more sense. The only way I'd say you should go with one image is if you are close to the 3G/LTE download size of (I think) 50MB.
May I know what are the ways to calculate the length of 1 pixel in centimeters? The images that I have are 640x480. I would like to compare 2 pixels at different places on the image and find the difference in distance. Thus I would need to find out what's the length of the pixel in centimeters.
Thank you.
A pixel is a relative unit of measure, it does not have an absolute size.
Edit. With regard to your edit: again, you can only calculate the distance between two pixels in an image in pixels, not in centimeters. As a simple example, think video projectors: if you project, say, a 3×3px image onto a wall, the distance between the leftmost and the rightmost pixels could be anything from a few millimeters to several meters. If you moved the projector closer to the wall or farther away from it, the pixel size would change, and whatever distance you had calculated earlier would become wrong.
Same goes for computer monitors and other devices (as Johannes Rössel has explained in his answer). There, the pixel size in centimeters depends on factors such as the physical resolution of the screen, the resolution of the graphical interface, and the zooming factor at which the image is displayed.
A pixel does not have a fixed physical size, by definition. It is simply the smallest addressable unit of picture, however large or small.
This is fully dependent on the screen resolution and screen size:
pixel width = width of monitor viewable area / number of horizontal pixels
pixel height = height of monitor viewable area / number of vertical pixels
Actually, the answer depends on where exactly your real-world units are.
It comes down to dpi (dots per inch) which is the number of image pixels along a length of 2.54 cm. That's the resolution of an image or a target device (printer, screen, &c.).
Image files usually have a resolution embedded within them which specifies their real-world size. It doesn't alter their pixel dimensions, it just says how large they are if printed or how large a “100 %” view on a display would be.
Then there is the resolution of your screen, as others have mentioned, as well as the specified resolution your graphical interface uses (usually 96 dpi, sometimes 120)—and then it's all a matter of whether programs actually honor that setting ...
The OS will assume some dpi (usually 96 dpi on windows) however the screens real dpi will depend on the physical size of the display and the resolution
e.g a 15" monitor should have a 12" width so depending on the horizontal resolution you will get a different horizontal dpi, assuming a 1152 pixel screen width you will genuinely get 96 dpi