resizing an image issue - java

I have a problem with resizing an image.
First of all at the start I have an image for example in 1920x1080. The user input is the percentage of resizing the current image, for example when input is 25% the final resolution of the image is 960x540.
Explanation:
1920x1080 = 2 073 600
25% from 2 073 600 = 518 400
960x540 = 518 400
I already have the function for resizing an image , but i dont know how to CALCULATE the values WIDTH and HEIGHT for an resized image.
I the example it is 960x540. (if it can help you, images has ratio 3:2,4:3,16:9 ....)
Any help ?

You have the following information given to you:
width = 1920
height = 1080
area = 2073600
ratio = width / height =~ 1.77778
Now, suppose for example that you want to calculate a new width and height when the area shrinks to 25% of its current size. Well then we know the following things:
area = 0.25 * 2073600 = 518400
height = h (Variable, because it is unknown at the moment)
width = w (Variable, because it is unknown at the moment)
ratio = 1.77778 (Ratio should stay the same or image becomes warped/stretched)
So you have
w / h = 1.77778 (Your unknown new width divided by unknown height equals ratio)
w * h = 518400 (Your unknown width times unknown height equals area)
Now you can solve it relatively easily mathematically. It is simply two equations with two variables.
w = 1.77778 * h (from first equation)
(1.77778 * h) * h) = 518400 (by plugging above into second equation)
h =~ 540
w =~ 960
Does that make sense?

Related

How to fix int rounding when drawing tiles on a board using Swing

I'm currently trying to make the Puzzle-15 in java.
I use a list of BufferedImage as the tiles and use g2d to paint them at coordinates (x,y).
I calculate how big each tile should be by:
int borderSize = 4;
int boardSize = 400 - 4*2;
int tilesPerRow = 40;
int tileSize = boardSize/tilesPerRow; // This will be floored to 9.
Then when the image is painted it only paints tiles 9*40. 360 pixels.. So there are 32 pixels left over. You can clearly see how ugly that is if you look at the image i've added down below.
I've tried to use affineTransform, but i can't make it work.
I hope one of you have a great idea:)
Heres my two approaches:
if you want x1 to be 10 and x2 to be 9 for a total of 392
you have 10*x1+9*x2=392
x1+x2=40
you solve the equations and get x1 and x2
B:
you magnify the space to 3920 and have 98 pixels per tile: 40*98
then you rescale down to 392 - it's a uniform scaling by 10 and the scaling is up to the graphics system

Set button size with pixels

In my application I control the size of my button proportionally with the screen size:
int screenWidth = displaymetrics.widthPixels;
int screenHeight = displaymetrics.heightPixels;
int buttonWidth = (int) (screenWidth * 0.07);
int buttonHeight = (int) (buttonWidth * 1.2);
The button takes the same space (for example 5 %) of the device's screen size. What I want now is that the button's text takes the same space of the button area on every device.
I tried this:
int textSize = (int) (buttonHeight * 0.145);
myButton.setTextSize((float) (textSize));
I don't know why but on bigger screens (such as tablets) the text uses a lot less space of the button than on smaller screens.
Thanks !
Maybe
Try specifying the unit of measurement like this:
myButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, (float) (textSize));
setTextSize uses sp units by default instead of px, so that might be causing your issue!

Displaying an exp bar properly

I have recently started messing around with LWJGL and I was making a little game to test some stuff in. I wanted to try to make an EXP bar and thought that it would be fairly easy. I got almost done with it until I ran into a large issue. That issue is properly displaying the exp bar filling up on the screen.
The game window is 1280 pixels in width and 720 pixels in height. The EXP bar is on the very bottom of the window 10 pixels high and stretches across the entire width of the window. As your level increases, the amount of exp needed to level up also increases. I need some help displaying the amount of exp that you currently have. When you first start you need 100 exp to level up. For example, say I have 50 exp. I need to show the exp bar 50% filled. I am asking for a formula to do this.
I tried looking around the internet for an answer but none of them worked, even though a few seemed like they would work just fine.
Current code to render the filled exp:
glColor3f(1f, 0f, 1f);
glBegin(GL_QUADS);
glVertex2i(x, y); // Upper Left
glVertex2i(x, y); //Upper Right
glVertex2i(x, y + height); //Bottom Right
glVertex2i(x, y + height); //Bottom Left
glEnd();
Find what percentage of the experience the player has, and multiply it by the bar's maximum width.
int currentXP;
int lastLevelXP;
int nextLevelXP;
int xpBetweenLevels = nextLevelXP - lastLevelXP;
int xpSinceLevelUp = currentXP - lastLevelXP;
float percentageOfXP = xpSinceLevelUp / (float) xpBetweenLevels;
int barWidth = (int) (percentageOfXP * maxWidth); // maxWidth would be the screen's width
// rendering must use 4 unique points
glColor3f(1f, 0f, 1f);
glBegin(GL_QUADS);
glVertex2i(x, y);
glVertex2i(x + (percentageOfXP * maxWidth), y);
glVertex2i(x + (percentageOfXP * maxWidth), y + height); // where y = 10
glVertex2i(x, y + height);
glEnd();
This way, if the player is at level 2, which starts at 70 XP, has 120 XP, and level 3 starts at 170 XP:
currentXP = 120
lastLevelXP = 70
nextLevelXP = 170
xpBetweenLevels = 170 - 70 = 100
xpSinceLevelUp = 120 - 70 = 50
percentageOfXP = 50 / 100 = 0.5
barWidth = 0.5 * 1280 = 640 = half of screen's width
Also note that, whereas your code only used 2 different vertices, which would result in a line, mine uses 4 which draws a quad.
edit
Since your code resets XP to 0 every level, and simply increases the required amount, the only modification needed is to set lastLevelXP to 0 and nextLevelXP to the amount of XP needed to level up. Thus, xpBetweenLevels becomes nextLevelXP - 0, which is the total XP needed to level up; likewise, xpSinceLevelUp becomes just currentXP. All you need to do is replace the non-rendering code with
int currentXP;
int xpNeeded;
float percentageOfXP = currentXP / (float) xpNeeded;
int barWidth = (int) (percentageOfXP * maxWidth);

scale an image keeping the aspect ratio without falling below the targets

I wonder if anybody can help me with the math/pseudo code/java code to scale an image to a target dimension. the requirement is to keep the aspect ratio, but not falling below the target dimension on both x and y scales. the final calculated dimension can be greater than the requested target but it needs to be the the closest one to the target.
example:
I have an image that is 200x100. it needs to be scaled down to a target dimension 30x10.
i need to find the minimal dimension that keeps the aspect ratio of the origin where both x and y scales are at least what is specified in the target.
in our example, 20x10 is not good because the x scale fell below the target (which is 30).
the closest one would be 30x15
Thank you.
targetRatio = targetWidth / targetHeight;
sourceRatio = sourceWidth / sourceHeight;
if(sourceRatio >= targetRatio){ // source is wider than target in proportion
requiredWidth = targetWidth;
requiredHeight = requiredWidth / sourceRatio;
}else{ // source is higher than target in proportion
requiredHeight = targetHeight;
requiredWidth = requiredHeight * sourceRatio;
}
This way your final image :
always fits inside the target whereas not being cropped.
keeps its original aspect ratio.
and always has either the width or height (or both) exactly matching the target's.
Well in your example you kind off already used the algorithm you're looking for.
I will use the example you have given.
Original Target
200 x 100 -> 30 x 10
1. You take the bigger value of the target dimensions (in our case 30)
2. Check if its smaller than the corresponding original width or height
2.1 If its smaller define this as the new width (So 30 is the new width)
2.2 If its not smaller check the other part
3. Now we have to calculate the height which is simply the (30/200)*100
So as result you get like you wrote: 30 x 15
Hope this was clear :)
In the coding part you could use the BufferedImage and simply create a new BufferedImage with the correct scale value like that.
BufferedImage before = getBufferedImage(encoded);
int w = before.getWidth();
int h = before.getHeight();
BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(2.0, 2.0); // <-- Here you should use the calculated scale factors
AffineTransformOp scaleOp =
new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(before, after);

Calculating the scale factor for "bar rectangles" of Chart app

I have an array of integer values
String[] values={3100,7500,8000,4200,88000,71000,32000};
that need to be scaled into a known height of my JComponent , the question is how to scale these values into e.g. h=600px?
Here is a pic just for more clarification of what i want to achieve:
Thanks
bar_height = chart_height*(value/max_value)
To determine bar_height, you scale (multiply) chart_height by (value/max_value), where:
bar_height is the height of the a bar in pixels.
value is the value to be charted.
max_value is the maximum value on the y-axis.
chart_height is the height of the chart in pixels (600 in your example).
For example:
88000/88000 = 1.0, or 100% of the chart height (600px)
0/88000 = 0, or 0% of the chart's height ( 0px)
3100/88000 = ~0.035, or ~3.53% of the chart's height (~21px)

Categories