Original Post
Does anybody have any good urls showing code for resizing image s using Bicubic Interpolation? Or at least a site that explains it well?
uint Interpolate_Value(uint v0, uint v1, uint v2, uint v3, float t)
{
int p = (v3 - v2) - (v0 - v1);
int q = (v0 - v1) - p;
int r = v2 - v0;
int s = v1;
float tSqrd = t * t;
//
return (p * (tSqrd * t)) + (q * tSqrd) + (r * t) + s;
//return (p * (tSqrd * t) + 0.5f) + (q * tSqrd + 0.5f) + (r * t + 0.5f) + s; // Use this one for nicer interpolation, it rounds instead of truncates.
}
//
// To interpolate a pixel we need to interpolate each color component seperately
//
ARGB Interpolate_Pixel(ARGB p0, ARGB p1, ARGB p2, ARGB p3, float t)
{
return InterpolateValue(p0.a, p1.a, p2.a, p3.a, t) << 24 |
InterpolateValue(p0.r, p1.r, p2.r, p3.r, t) << 16 |
InterpolateValue(p0.g, p1.g, p2.g, p3.g, t) << 08 |
InterpolateValue(p0.b, p1.b, p2.b, p3.b, t);
}
//
//
//
Resize_Image(ARGB *Image, uint Width, uint Height, uint NewWidth, uint NewWidth, ARGB *NewImage)
{
uint OldImageX, OldImageY;
float dx = Width / NewWidth, dy = Height / NewHeight;
ARGB Temp[4];
//
//
for (y = 0; y < NewHeight; ++y)
{
OldImageY = dy * y;
ty = dy * y - OldImageY;
//
for (x = 0; x < NewWidth; ++x)
{
OldImageX = dx * x;
tx = dx * x - OldImageX;
//
// I don't know how image scaling works with regards to edges
// e.g. when OldImageX is 0 and you need pixels from behind (OldImageX - 1) you can either wrap around and get pixels to sample from the other side of the image (OldImageX = Width - 1)
// or you can just clamp to the edge (if (OldImageX - 1 < 0) OldImageX = 0), your choice, see what looks best.
// Likewise for when OldImageX == Width - 1 and you need to get OldImageX + 1
//
// To interpolate 2D data correctly we first interpolate 4 pixels horizontally for each of 4 scanlines, which leaves us with 4 new pixels
//
Temp[0] = Interpolate_Pixel(Image[(OldImageY - 1) * Width + OldImageX - 1],
Image[(OldImageY - 1) * Width + OldImageX],
Image[(OldImageY - 1) * Width + OldImageX + 1],
Image[(OldImageY - 1) * Width + OldImageX + 2],
tx);
Temp[1] = Interpolate_Pixel(Image[OldImageY * Width + OldImageX - 1],
Image[OldImageY * Width + OldImageX],
Image[OldImageY * Width + OldImageX + 1],
Image[OldImageY * Width + OldImageX + 2],
tx);
Temp[2] = Interpolate_Pixel(Image[(OldImageY + 1) * Width + OldImageX - 1],
Image[(OldImageY + 1) * Width + OldImageX],
Image[(OldImageY + 1) * Width + OldImageX + 1],
Image[(OldImageY + 1) * Width + OldImageX + 2],
tx);
Temp[3] = Interpolate_Pixel(Image[(OldImageY + 2) * Width + OldImageX - 1],
Image[(OldImageY + 2) * Width + OldImageX],
Image[(OldImageY + 2) * Width + OldImageX + 1],
Image[(OldImageY + 2) * Width + OldImageX + 2],
tx);
//
// Then we interpolate those 4 pixels to get a single pixel that is a composite of 4 * 4 pixels, 16 pixels
NewImage[y * NewWidth + x] = Interpolate_Pixel(Temp[0], Temp[1], Temp[2], Temp[3], ty);
}
}
}


Quote:
Original post by Bourla
float p = (v3 - v2) - (v0 - v1);
float q = (v0 - v1) - p;
why not write q = v2 - v3 ?
This topic has been locked by a moderator. New replies are not allowed.
With your permission, GameDev.net uses analytics cookies to understand how people use the platform. You can accept analytics or continue with necessary cookies only. Learn more