Converting pixels to cm?
Hi all,
I have this code:
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension screen = tk.getScreenSize();
if(((height=screen.getHeight())>=768)&&
((width=screen.getWidth())>=1024))
{
//Do nothing. Variables width and height already set inside if condition.
}
where variables height and width are in pixels.
However in another part of my program i want to set the position of a JLabel . From what i understand the setPosition method requires cm.
Can anyone tell me how to convert pixels to cm in a safe way.
Thanks in advance.
Which setPosition method?
If you are placing components on the screen, you always use pixel values.
My mistake. I meant the setLocation method instead of setPosition
uses pixels, not cm. There is no safe 1:1 conversion, the number of pixels per centimeter (generally measured by pixels per inch, or DPI (dots per inch)) can vary from computer to computer.
At any rate, it uses pixels.
Sometimes it would be nice to be able to work in physical units like centimeters or what have you,
put I haven't found how to do this accurately in the java API.
It can't be that hard -- Window's APIs have let you do this forever. Maybe some other platforms don't support it...
> My mistake. I meant the setLocation method instead of
> setPosition
Hmm, that method probably does not do what you want it to do. It assumes coordinates in the parent component's coordinate space. E.g. if you put a JLabel into a JFrame's contentPane, setLocation(0, 0) will position the label at the contentPane's upper left corner and not in the upper left corner of the screen.
Instead of using setLocation, you should work with LayoutManagers, see the various implementations of java.awt.LayoutManager2. If you are new to that kind of stuff, you probably should read a SWING tutorial first, e.g. http://java.sun.com/docs/books/tutorial/uiswing
Hippo, ?
How would Windows possibly do this?
Granted its possible I could be wrong, but a year ago I worked
on an CAD type system and looked this stuff up. From what I gathered
monitor drivers dont have a universal specification for providing
their size and screen ratio (4:3, 5:4) - and I dont think most
monitors provide that information at all.
@OP, all you need is to save a file or prompt the user for their screen
size and screen ratio. from there its just grade school algebra.
> Hippo, ?
> How would Windows possibly do this?
It's been a while, but I remember you could set your units to pixels, or
to hundreths of a cm, etc... Do you think it was just assuming 96 pixels/inch?
>> Do you think it was just assuming 96 pixels/inch?
Doesnt that sound like Microsoft to you, lol?
There are about 4 very common different screen ratios in use today
I really think the monitor industry should add size/ratio to their
drivers. Not a big deal though I guess.
Maybe MS should add a utility for us to enter that info manually.
Maybe thats asking too much...
Pirate Maniac,
Here you go. ALl you have to fill in during execution time is the screen
size (which is actually a measurement of the diagonal) and screen
ratio (that is NOT always equal to the resolution ratio, for example:
1024/768 = 4:3 but that doesnt mean the screen is 4:3).
I have a goofy Samsung 19" LCD tv/monitor with a 5:4 ratio so when
im at 1024x768 my horiz and vert pixles arent even.
So if i draw a 100x100 pixel rectangle in a CAD program its not a
square, lol. Leave it to Samsung that the only 5:4 resolution is the
highest unusable setting, lol.
import java.awt.Dimension;
import java.awt.Toolkit;
public class PixelsToCMs{
public static void main(String[] args){
// pythagorean theorem: a^2 + b^2 = c^2
// h = horiz, v = vert, d = diag, r = ratio
// h^2 + v^2 = d^2
// h^2 + (r*h)^2 = d^2
// h^2 (1 + r^2) = d^2
// h = sqrt( d^2 / (1 + r^2) )
double diag = 18;
double ratio = RATIO_4_3;
double horiz = Math.sqrt((diag * diag) / (1 + (ratio * ratio)));
double vert = ratio * horiz;
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
double h_pixels = (double)screen.getWidth();
double v_pixels = (double)screen.getHeight();
double h_pixels_per_cm = h_pixels / (horiz * INCH_TO_CM);
double v_pixels_per_cm = v_pixels / (vert * INCH_TO_CM);
System.out.println("Horiz: " + horiz);
System.out.println("Vert: " + vert);
System.out.println("Horiz Pixels: " + h_pixels);
System.out.println("Vert Pizels: " + v_pixels);
System.out.println("Horiz Pixels Per CM: " + h_pixels_per_cm);
System.out.println("Vert Pixels Per CM: " + v_pixels_per_cm);
}
public static final double RATIO_4_3 = 3.0 / 4.0;
public static final double RATIO_5_4 = 4.0 / 5.0;
public static double INCH_TO_CM = 2.54;
}
> feed me dukes!
no. You forgot to take into account that the diagonal given as the size of most screens isn't the size of the visible screen area, and even if it is isn't the size of the image projected onto that visible screen area.
I didn't read the rest of your code but you may have made more omissions :)
Indeed you can in some applications set a size in centimeters, but that's NOT centimeters on screen.
It's the size in centimeters the object will be when printed at the specific resolution set for that same object.
> Sometimes it would be nice to be able to work in
> physical units like centimeters
Like where? This is a handicap if you have to port your code.
> It can't be that hard -- Window's APIs have let you
> do this forever.
Windows API?
> > It can't be that hard -- Window's APIs have let you
> > do this forever.
>
> Windows API?
The C WINAPI. Ever use MFC?
>> no. You forgot to take into account ...
blah blah blah, lol. theres also quantum tunnelling, the spooky effect
at a distance, uncertainty, the lochness monster, and dracula.
i have a flat screen LCD and ive never had those numbers give me
any problems. and anyway your post is = NULL if you just measure the
diagonal of the visible screen instead of using the number on the box. ; )
Geometry is never wrong my friend, lol.
plus if the OP really needs granularity between 26.7 pixels per cm and
26.3 pixels per cm then he probably has bigger problems!
Also, yes as you said there is a difference between screen size and
printing size but I was fairly certain this thread was about screen size.
> It can't be that hard -- Window's APIs have let you
> do this forever.
Do what? Work in cm? This has nothing to do with the operating system. Photoshop will let you work in cm I'm sure. But if you're thinking Java (or any system) can magically predict how many cm (on screen or printed on paper) given a number of pixels then you don't understand the problem.
You can work in cm or other physical measurements in Photoshop because you are (can be) working in the terms of printing. Which means you can have a physical print of X by X cm. But that still always has a pixels per inch/cm/etc. resolution to go along with it. It doesn't exist within a vacuum.
Generally, screens can be any given number of pixels in an inch. Windows always had a setting that you could define that value, usually 96 ppi, or 72 on Macs. It's that value that is being considered in any other APIs (Windows MFC or whatever) that goes into saying 1 unit = X pixels.
Why Java doesn't have something in a printing API that does let you define things that way, I don't know. It could prove useful. But I think originally it's all about pixels cuz it was all about the screen.
> > > It can't be that hard -- Window's APIs have let
> you
> > do this forever.
>
> Windows API?
>
> The C WINAPI. Ever use MFC?
Yes. I was supposed to be a part of a project quite sometime back which involved MFC. Walked out after realizing it's a piece of ****. MFC and windows. I just couldn't put these together.
funny how there's no "MFC for Dummies"
> funny how there's no "MFC for Dummies"
What's even scarier is that there is:
http://www.dummies.com/WileyCDA/DummiesTitle/productCd-0764517953,page-tableOfContents.html
It's book VII.
Except how they think they can cover MFC in 100 pages or so, I don't know. That "7 books in 1" on C++ is only 864 pages total.
Message was edited by:
bsampieri
> Except how they think they can cover MFC in 100 pages
> or so, I don't know.
I'm scared to look. They probably lead you through a few wizards. Hey, I just built an MDI project!
> Windows always had a setting that you
> could define that value, usually 96 ppi, or 72 on
> Macs. It's that value that is being considered in
> any other APIs (Windows MFC or whatever) that goes
> into saying 1 unit = X pixels.
ugh.
windows cant possibly be giving you the correct values if it doesnt
know the screen dimensions.
> > Windows always had a setting that you
> > could define that value, usually 96 ppi, or 72 on
> > Macs. It's that value that is being considered in
> > any other APIs (Windows MFC or whatever) that goes
> > into saying 1 unit = X pixels.
>
> ugh.
> windows cant possibly be giving you the correct
> values if it doesnt
> know the screen dimensions.
You're right, it doesn't... it gives you the value assuming 96 ppi or whatever it's set to.
The point of the setting was that it's irrelevant what the screen's real resolution is, I think. The problem is that with CRT monitors, at least anything from the last 10-15 years or so, is that they can support any size pixels (within a range). 800x600 could take the same physical space as 1280x1024, so the latter would have smaller pixels, and more per inch.
LCDs obviously changes that (for the most part... at least there is a native resolution) a bit. But not perfectly, if you don't have the settings right. However different monitors can have different dot pitches.
So unless there is some way to automatically detect all that info from the monitor and based on the screen settings, one can only rely on a general value (96 or 72). I'm not sure if dot pitch is included in a monitor's info, but I guess it can be inferred from physical size and resolutions if both are available (I know a PC can know the possible resolution settings at least).
Of course, none of this explains why a couple receptionists here have a 19" monitor with the resolution running 640x480 (seriously). It looks like a PC version of one of those novelty giant button phones.
This will return DPI
int dpi = toolkit.getScreenResolution();
Should be straightforward to convert to CM after that..
(T)
Wow. Its like talking to a d@mn wall.
That method cant possibly be helpful considering it only returns one
number (and an int at that). Your horizontal and vertical DPI can be
different (and for me and all others unlucky enough to have a 5:4
screen w/ 1024x768 they ALWAYS are).
Moreover for the Nth time: How can software give you the correct values
if it doesnt know the dimensions of your actual physical screen?
Can everyone in this thread do me a favor?
Cut out a 1 inch by 1 inch piece of paper.
Run my code. Draw a rectangle on screen.
Hold your cutout to the screen. Thats math and common sense in action right there.
> Wow. Its like talking to a d@mn wall.
Eh?
> That method cant possibly be helpful considering it
> only returns one
> number (and an int at that).
You are right we could have held 96 in a byte.
> Your horizontal and
> vertical DPI can be
> different (and for me and all others unlucky enough
> to have a 5:4
So now we realize this lack of consideration.
> screen w/ 1024x768 they ALWAYS are).
>
> Moreover for the Nth time: How can software give you
> the correct values
> if it doesnt know the dimensions of your actual
> physical screen?
Package java.Psychic?
> Can everyone in this thread do me a favor?
A bigger favor to all would be post a valid working code.
> Cut out a 1 inch by 1 inch piece of paper.
> Run my code. Draw a rectangle on screen.
> Hold your cutout to the screen. Thats math and common
> sense in action right there.
Common also sense tells you that the earth is flat; please consider that not everyone here is a genius programmer . if you can't handle people not knowing something that is apparently obvious to you, then perhaps you lack the requisite patience volunteering help requires.
Other than that I was assuming a 1 to 1 screen ratio and considering this is deficient I would let the use decide as you suggested from a list of common sizes as you suggested.
Nuff said on that :)
(T)
> You are right we could have held 96 in a byte.
The point was that the value could be fractional - so an integral
value is unsatisfactory.
> A bigger favor to all would be post a valid working code.
Reply #9. Did you even read this thread?
> not everyone here is a genius programmer
Genius is overrated. Applying common sense and grade school
geometry would have been sufficient.