Reputation: 31
i cant find any solution for my problem, hope you can help me. I have a Buffered image (e.g. img), und i want to resize it (with its array of pixels) to fit exactly 100px (100 x 100). All the solutions i found are just for "stretching" the image when drawing, but i really need the array. I thought about a algorithm and tried this one:
BufferedImage resized = new BufferedImage(100,100,BufferedImage.TYPE_INT_ARGB);
for(int i = 0; i < img.getWidth(); i++){
for(int j = 0; j < img.getHeight(); j++){
resized.setRGB(i*(100/img.getWidth()), j*(100/img.getHeight()), img.getRGB(i, j));
}
}
I cant explain it (well, not in english) what it does, but i think you can see it easily (for every pixel in the original image (img), put it in the new BufferedImage (resized) at the postition (the old position * resize factor). (hope that was a good description). But however, it doesnt work, i only get zeros :( Can somebody tell me what to modify or give me a other example for a algorithm? (doesnt matter how fast it is, as long as i can understand it)
(I really hope it isnt a repost, because i really could not find another problem/solution that aims at the array resizing :/ )
Greetings :)
Upvotes: 0
Views: 367
Reputation: 29126
Let's look at your problem in only one dimension. For every column i
in the original image of width owidth
you want to find the column ii
in the new image of width nwidth
, in your case 100. You calculate ii
like this:
ii = i * (nwidth / owidth);
The formula is good in principle, but the parentheses ensure that the ration nwidth / owidth
is calculated first. Because you scale down, this ratio is smaller than one. Because both nwidth
and owidth
are integers, the division is an integer division whose result must also be an integer. Here, it is zero.
You can fix this in two ways: Make the division a floating-point division:
ii = i * (1.0 * nwidth / owidth);
or just remove the parentheses so that the multiplication happens first:
ii = i * nwidth / owidth;
(There is a risk of overflow when your images are really big, but in your case, that shouldn't be a concern.)
Finally, James K Polk is right: You've got the logic the wrong way round. Visit each pixel of the new image with the for
loops and pick a source pixel from the old image for each pixel in the new image. (That also means that the ratio is reversed.)
That logic is the ame for both scaling up and down: You must select a source pixel for each destination pixel. When scaling up, you end up using the same source pixels several times; when scaling down, you skip some source pixels. This is a fast and straightforward (but not necesarily high-quality) scaling algorithm.
Upvotes: 1