Skip to main content

Bilinear Interpolation Scaling help

1 reply [Last post]
xpectro
Offline
Joined: 2010-06-14
Points: 0

Hi,

I'm trying to program a class for a project, that reads a picture as BufferedImage, and resize it using Bilinear Interpolation (Using the mathematical formulas, not the methods included in java). I almost sure that the Bilinear Interpolation part of the method is done, but after many thinking, searching and losing hope, I just can't figure out how to apply the scaling part to the method.

Here's the method:

<br />
public static BufferedImage resize(BufferedImage image, int w2, int h2)<br />
{</p>
<p>BufferedImage outputImage = new BufferedImage( w2, h2, BufferedImage.TYPE_INT_RGB );</p>
<p>// Ratio between original picture and resized picture<br />
float x_ratio = ((float) (image.getWidth()-1))/w2 ;<br />
float y_ratio = ((float) (image.getHeight()-1))/h2;</p>
<p>// Four pixels a,b,c,d int a, b, c, d, i, j, color;<br />
float alpha, beta, xabRed, xabGreen, xabBlue, xcdRed, xcdGreen, xcdBlue, xfinalRed, xfinalGreen, xfinalBlue; </p>
<p>for (int x = 0; x < image.getHeight()-1; x++)<br />
   for( int y = 0; y < image.getWidth()-1; y++){ </p>
<p>//Find the color values of the 4 pixels around the desired point to interpolate<br />
   a = image.getRGB(x, y);<br />
   b = image.getRGB(x, y + 1);<br />
   c = image.getRGB(x + 1, y);<br />
   d = image.getRGB(x + 1, y + 1); </p>
<p>   i = (int) (x_ratio * x);<br />
   j = (int) (y_ratio * y); </p>
<p>   alpha = (x_ratio * x) - i;<br />
   beta = (y_ratio * y) - j; </p>
<p>// a,b represents 2 of the 4 points for interpolation<br />
   xabRed = alpha * ((b >> 16)&0xff) + (1 - alpha) * ((a >> 16)&0xff);<br />
   xabGreen = alpha * ((b >> 8)&0xff) + (1 - alpha) * ((a >> 8)&0xff);<br />
   xabBlue = alpha * (b &0xff) + (1 - alpha) * (a &0xff); </p>
<p>// c,d represents 2 of the 4 points for interpolation<br />
   xcdRed = alpha * ((d >> 16)&0xff) + (1 - alpha) * ((c >> 16)&0xff);<br />
   xcdGreen = alpha * ((d >> 8)&0xff) + (1 - alpha) * ((c >> 8)&0xff);<br />
   xcdBlue = alpha * (d &0xff) + (1 - alpha) * (c &0xff); </p>
<p>// Desired point<br />
   xfinalRed = beta * xcdRed + (1 - beta) * xabRed;<br />
   xfinalGreen = beta * xcdGreen + (1 - beta) * xabGreen;      xfinalBlue = beta * xcdBlue + (1 - beta) * xabBlue; </p>
<p>// Prints the RGB values, for bound confirmation    System.out.println((int) xfinalRed + " " + (int) xfinalGreen + " " + (int) xfinalBlue); </p>
<p>// Sets the new color value for the pixel<br />
   color = new Color((int)xfinalRed, (int)xfinalGreen, (int)xfinalBlue).getRGB(); </p>
<p>// Set the pixel<br />
   outputImage.setRGB(x, y, color);<br />
}<br />
 return outputImage;<br />
}<br />

Thanks in advance

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kitfox
Offline
Joined: 2004-03-31
Points: 0

The easiest way to go about this is to do it in two parts. First, write a
method that calculates the bilinear interpolation for any floating point
coordinate in your image. (Eg, sampleImage(float x, float y) will give
you the bilinear interpolated color for any point in the image).

Next, write a method that handles the scaling. This will take the
coordinate in your device space (the destination image), transform it into
image space (your source image), and then do the lookup there. So you can
write something like:

sampleScaledImage(float x, float y, float scale)
{
return sampleImage(x / scale, y / scale);
}

You may also want to look at AffineTransform. It will manipulate
coordinates in a similar way.

Mark McKay