我遇到了这个,C版本的双线性插值。我不知道如何运行它。我有一个名为image_1.jpeg
的图像,我想使用它...
看起来你只需要调用 scale((,但是你究竟如何编写 main(( 方法来做到这一点?
守则 ->
#include <stdint.h>
typedef struct {
uint32_t *pixels;
unsigned int w;
unsigned int h;
} image_t;
#define getByte(value, n) (value >> (n*8) & 0xFF)
uint32_t getpixel(image_t *image, unsigned int x, unsigned int y){
return image->pixels[(y*image->w)+x];
}
float lerp(float s, float e, float t){return s+(e-s)*t;}
float blerp(float c00, float c10, float c01, float c11, float tx, float ty){
return lerp(lerp(c00, c10, tx), lerp(c01, c11, tx), ty);
}
void putpixel(image_t *image, unsigned int x, unsigned int y, uint32_t color){
image->pixels[(y*image->w) + x] = color;
}
void scale(image_t *src, image_t *dst, float scalex, float scaley){
int newWidth = (int)src->w*scalex;
int newHeight= (int)src->h*scaley;
int x, y;
for(x= 0, y=0; y < newHeight; x++){
if(x > newWidth){
x = 0; y++;
}
float gx = x / (float)(newWidth) * (src->w-1);
float gy = y / (float)(newHeight) * (src->h-1);
int gxi = (int)gx;
int gyi = (int)gy;
uint32_t result=0;
uint32_t c00 = getpixel(src, gxi, gyi);
uint32_t c10 = getpixel(src, gxi+1, gyi);
uint32_t c01 = getpixel(src, gxi, gyi+1);
uint32_t c11 = getpixel(src, gxi+1, gyi+1);
uint8_t i;
for(i = 0; i < 3; i++){
//((uint8_t*)&result)[i] = blerp( ((uint8_t*)&c00)[i], ((uint8_t*)&c10)[i], ((uint8_t*)&c01)[i], ((uint8_t*)&c11)[i], gxi - gx, gyi - gy); // this is shady
result |= (uint8_t)blerp(getByte(c00, i), getByte(c10, i), getByte(c01, i), getByte(c11, i), gx - gxi, gy -gyi) << (8*i);
}
putpixel(dst,x, y, result);
}
}
来源: https://rosettacode.org/wiki/Bilinear_interpolation#C
你在这里的问题可能不是弄清楚如何调用scale
,而是弄清楚如何加载你的图像。我推荐 SOIL 库,它可以处理最常见的格式并为您提供原始像素数据。
您很可能还需要一些函数来从原始映像创建实际的image_t
实例。SOIL和其他图像库应该能够为您提供宽度和高度,以及图像本身的某种字节或整数数组。在您的示例中,image_t似乎是主要的行,因此类似这样的事情可以工作:
image_t to_image_t(int width, int height, unsigned char* data) {
image_t img = { malloc(sizeof(int) * width * height), width, height };
for (int i = 0; i < width * height; i ++) {
// You may need to fiddle with this based on your image's format
// and how you load it.
img->pixels[i] = (data[0] << 24)
| (data[1] << 16)
| (data[2] << 8)
| (data[3]);
}
return img;
}
只需记住在使用完图像后释放图像的像素数据即可。