Centimeters to Pixels Conversion - java

how to convert
1 cm to ?px
this conversion used in html parser
% conversion is -> (allToPx[0]) * 16)/100) px
pt conversion is -> (allToPx[0]) * 16)/12) px
em conversion is -> (allToPx[0]) * 16)/1) px
but how to convert in cm ?

You have to figure out the pixel density for the display you work on. This might be drastically different. You have to get these data:
width of screen
height of screen
vertical pixels
horizontal pixels
Then you can calculate what the actual size of a given pixel vertically and horizontally...
But obtaining this kind of information is not always possible. You might have to use some platform dependant trickery to get these, if even possible... Also, you didn't specify what kind of UI library you use. That might be of help for us to be able give advice.

There is no cm conversion as the size of the elements in cm depends heavily on the screen density (pixels per inch or cm), which you can't access on most devices

It would not be impossible to convert cm to px since they are not of the same unit types.
cm is an absolute length unit while px is a relative length unit
Its just like saying, "Can I convert kilos to hours?"
Use this as reference: http://msdn.microsoft.com/en-us/library/ms537660(v=vs.85).aspx

Related

Drawing in greyscale produces color shift

I'm working on elevation map hierarchy, quad tree, and for that I need to process elevation dataset in form of 16bit grayscale images into different images in various levels. That is for the most part downsampling input data.
Consider input tile image of 14401x10801 in size, which is supposed to be drawn into part of an image 512x512.
Draw call looks something like this:
Graphics2D g2d = (Graphics2D) dstImage.getGraphics();
...
BufferedImage clip = sourceImage.getSubimage(srcX, srcY, srcWidth, srcHeight);
g2d.drawImage(clip , dstX, dstY, dstWidth, dstHeight, null);
where
srcX = srcY = 0
srcWidth = 14401
srcHeight = 10801
dstX = dstY = 0
dstWidth = 171
dstHeight = 128
The area being filled is correct in relative terms, meaning peaks are where they are supposed to be. The issue is, that values do not exactly correspond to what you'd expect. Specifically, pixel 0,0 in dst is definitely sea with zero elevation, yet value 64 is drawn in there.
Looking at contents of src image
sourceImage.getSubimage( 0, 0,
(int)(srcWidth/(double)dstWidth),
(int)(srcHeight/(double)dstHeight));
should yield more or less values from src image that go into pixel 0,0 in dst. These are all zero, so I suppose the issue is not in some peak swaying the value up. What is more perplexing, all pixels that should be zero are set to 64.
For purpose of this processing (as java cannot handle negative values in 16 bit grayscale) all pixels are elevated by 16384. Elevating these by mere 1000 results in error -229 instead of 64. Value change is simple "add to all inputs" -> "process" -> "subtract from all outputs".
I hoped to avoid all the resampling, clipping, and efficiency problems by simply doing all the work over images, but so far it seems java does some obscure color mapping.
Any ideas what I might be doing wrong?
So I poked the code around a bit, and out of sole desperation started turning off things that should not, but might, have an impact. The culprit turned out to be
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
This hint does not ... hint ... how on earth one could get from average over 84 times 16384 something else than 16384, but hey, who am I to judge.
Documentation for this hint states
The RENDERING hint is a general hint that provides a high level
recommendation as to whether to bias algorithm choices more for speed
or quality when evaluating tradeoffs. This hint could be consulted for any rendering or image manipulation operation, but decisions will usually honor other, more specific hints in preference to this hint.
not very helpful either.
I did already encounter some discouragement from use of rendering hints in java2d, and it seems there indeed is something about that.

Java Tookit Screen Resolution - How can I use it?

When using int resolution = Toolkit.getDefaultToolkit().getScreenResolution(); to get my monitor's resolution, the integer resolution returns 96. What does this mean, how could it be used, and, if possible, could I get the resolution in a 4:3, 16:9, etc. format?
getScreenResolution() return dots-per-inch (DPI). If you want the size of the screen, just use getScreenSize().
Here's a quote that gets you the basic idea of DPI vs. pixels:
So, if you have a 600 pixel x 600 pixel image at 300DPI, it will output at 2 inches square. If you change this images DPI to 150, this will mean it will output at 4 inches square. So, as you can see, changing the DPI of an image changes it output size.
You can find rest of the explanation here.

How to normalize RGB value with reference RGB values

I want to get RGB values of an image in many lighting conditions. To get a somehow neutral scenario, I want to normalize the RGB values with RGB values of some predefined images.
Let me explain. I have 6 predefined images and I know their exact average RGB values. Now I will take the picture of the unknown image in different lighting conditions. I will also take the pictures of predefined 6 images in same conditions. Now my goal is to define a normalization formula by comparing the known reference rgb values of the predefined images to the values computed from the camera picture. with this normalization parameter I will calibrate the RGB value of the unknown picture. So that I can get average RGB value from the unknown picture in a neutral manner irrespective of the lighting condition.
How can I achieve this easily in Java.
Is the reason you are doing this to truly normalize RGB, or are you trying to normalize the images to have similar brightness. Because if your goal is simply the brightness, then I would convert to a color standard that has a brightness component, and normalize only the brightness component.
From there you can take the new image in the different color component standard and convert back to RGB if you like.
The steps (but not in java):
1) Convert - RGBImage --> YUVImage
2) Normalize RGBImage using the Y component
3) Convert - Normalized(YUVImage) --> Normalized(RGBImage)
In this way you can implement Normalization on the brightness using the algorithm described here.
ELSE, you can average the averages for each channel and use those as the numerator for the normalization factors for your new images calculating each channel separately.
For differing lighting situations, a linear RGB correction is all that is required. Simply multiply each of the R,G,B values by a constant derived for each channel.
If there was only one reference color, it would be easy - multiply by the reference color, and divide by the captured color. For example if your reference color was (240,200,120) but your image measured (250,190,150) - you would multiply red by 240/250, green by 200/190, and blue by 120/150. Use the same constants for every pixel in the image.
With multiple colors to match you'll have to average the correction factors to arrive at a single set of constants. Greater weighting needs to be given to the brighter colors, for example if you had a reference of (200,150,20) and it measured (190,140,10) you'd be trying to double the amount of blue which could be very far off. The simplest method would be to sum all the reference values and divide by the sum of the measured values.

what values of an image should I use to produce a haar wavelet?

I currently have a Java program that will get the rgb values for each of the pixels in an image. I also have a method to calculate a Haar wavelet on a 2d matrix of values. However I don't know which values I should give to my method that calculates the Haar wavelet. Should I average each pixels rgb value and computer a haar wavelet on that? or maybe just use 1 of r, g,b.
I am trying to create a unique fingerprint for an image. I read elsewhere that this was a good method as I can take the dot product of 2 wavelets to see how similar the images are to each other.
Please let me know of what values I should be computing a Haar wavelet on.
Thanks
Jess
You should regard the R/G/B components as different images: Create one matrix for R, G and B each, then apply the wavelet to parts of those independently.
You then reconstruct the R/G/B-images from the 3 wavelet-compressed channels and finally combine those to a 3-channel bitmap.
Since eznme didn't answer your question (You want fingerprints, he explains compression and reconstruction), here's a method you'll often come across:
You separate color and brightness information (chrominance and luma), and weigh them differently. Sometimes you'll even throw away the chrominance and just use the luma part. This reduces the size of your fingerprint significantly (~factor three) and takes into account how we perceive an image - mainly by local brightness, not by absolute color. As a bonus you gain some robustness concerning color manipulation of the image.
The separation can be done in different ways, e.g. transforming your RGB image to YUV or YIQ color space. If you only want to keep the luma component, these two color spaces are equivalent. However, they encode the chrominance differently.
Here's the linear transformation for the luma Y from RGB:
Y = 0.299*R + 0.587*G + 0.114*B
When you take a look at the mathematics, you notice that we're doing nothing else than creating a grayscale image – taking into account that we perceive green brighter than red and red brighther than blue when they all are numerically equal.
Incase you want to keep a bit of chrominance information, in order to keep your fingerprint as concise as possible, you could reduce the resolution of the two U,V components (each actually 8 bit). So you could join them both into one 8 bit value by reducing their information to 4 bit and combining them with the shift operator (don't know how that works in java). The chrominance should weigh less in comparison to the luma, in the final fingerprint-distance calculation (the dot product you mentioned).

Shape at "Actual Size"

What's the easy way to render a shape in Java to its "actual size". For example, I have a tube with a diameter of 1" and I want to depict it on screen as the outline of a 1" circle. The Graphics2D method drawOval(int x, int y, int width, int height) takes a height and width in pixels. What are the steps to translate a pixel size into the size rendered on screen?
Thanks in advance.
The getNormalizingTransform() method of the class GraphicsConfiguration looks like it has some potential
http://java.sun.com/javase/6/docs/api/java/awt/GraphicsConfiguration.html#getNormalizingTransform()
The java.awt.Toolkit will tell you the size of a pixel, and the pixel dimensions of the screen. This is based on information from the underlying system, however, which may sometimes be misconfigured.
So, to draw a 1" circle, you'd use a diameter of 1.0 * tk.getScreenResolution(), a 2.5" circle is 2.5 * tk.getScreenResolution(), etc.
You should be aware that, even though you might be able to find out about the screen size and resolution, you still can't be sure of the actual size of the displayed picture. If the user has a CRT screen, the screen is likely to be a bit smaller than the actual screen size.
Therefore, if you really need accurate results, the only way is to let the user adjust a ruler displayed on the screen interactively and compare it with an actual ruler.
In theory you can do it this way. The java.awt.Toolkit will tell you the size of a pixel, and the pixel dimensions of the screen. So, to draw a 1" circle, you'd use a diameter of 1.0 * tk.getScreenResolution(), a 2.5" circle is 2.5 * tk.getScreenResolution(), etc. Or you can use the GraphicsConfiguration.getNormalizingTransform() method which adjusts the resolution to a 'fixed' size.
Unfortunately both of these methods rely on the underlying system knowing (and telling you) the actual resolution of your screen. In practice this very rarely occurs. All sorts of things can affect the actual size of a pixel. The actual size and make of monitor is one, and some monitors even allow you to adjust the size of the image on the screen.
This article http://www.developer.com/java/other/print.php/626071 discusses this.
Printers are generally better at telling you their real resolution. If you absolutely must have a picture which is the correct size, send it there.
Acknowledgements to the various answers from which I synthesized this one.
The problem you're going to have is Pixels are not always the same size. For example a 100 x 100 pixel square is going to be different sizes on a 17" 1280 x 1024 monitor and a 19" 1280 x 1024 monitor.
I don't believe there is an API which tells you the physical size of a display.
Asking the user the size of their monitor might not help as a lot of people simply won't know.
You could display a number of lines on screen and get the user to click which one is closest to 1 inch and scale all your rendering to that, but it's a bit clumsy.
Well, you would need the size of the monitor and resolution. Let's say the monitor is 17" with a 1280:1024 aspect ratio.
The screen size is the hypotenuse, so you would need to find the number of pixels on the hypotenuse. Simple geometry later, you can get the pixels/inch calculation.
1280px^2 + 1024px^2 = c^2, c ~= 1639.2px. So it's 1639.2px/17inch = 96.4px/inch for a 17 inch monitor with 1280x1024 resolution. This would have to be entered by the user.
I was under the impression that simply getting the screen resolution from Toolkit was not enough. I think you need to do something more along the lines of
float scalingFactor = Toolkit.getDefaultToolkit().getScreenResolution() / 72f;
Making a 1" square
int width = 1.0 * scalingFactor;
and a 2.5" square
int width = 2.5 * scalingFactor;
All of this being that Java2D assumes a 72 dpi screen resolution, and if the system is set differently you need to scale up to correct for this.
This is a curious question, one I haven't thought of. Off the top of my head, you would probably need to know a combination of screen size (17", 21", etc.), screen resolution ("800x600, 1280x1024, etc.) and DPI of the screen (72, 96, 120, etc.).
Through various api's, you can determine the screen resolution, and maybe the dpi... but good luck with the screen size. And even with all that, you're still not guaranteed to produce the correct size on screen.

Categories