Запуск C-билинейной интерполяции

Я наткнулся на эту версию 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


person Community    schedule 16.07.2019    source источник
comment
Это сложнее, чем просто добавить main. Также нужно прочитать изображение. Какой у него формат? Наконец, вам нужно снова записать масштабированное изображение. Предлагаю вам помощь. Здесь может быть слишком много спрашивать и объяснять.   -  person Paul Ogilvie    schedule 16.07.2019
comment
image_1.jpeg - это изображение, которое я использую для этого. Вывод может быть любым, например image_1_larger.jpeg. Это билинейная интерполяция, поэтому изображение увеличивается на 60%. Мое сообщение отредактировали, поэтому ссылка была потеряна: rosettacode.org/wiki/Bilinear_interpolation#C   -  person    schedule 16.07.2019
comment
Затем вам также необходимо декодировать изображение jpeg. Становится все сложнее ... Вы можете преобразовать jpeg в BMP, а затем прочитать BMP, что проще, но также совершенно неривиально.   -  person Paul Ogilvie    schedule 16.07.2019
comment
Если я просто использую BMP, есть ли простой способ сделать это?   -  person    schedule 16.07.2019
comment
Мой ответ на stackoverflow.com/questions/47768094/ показывает, как читать растровое изображение, однако вы все равно должны преобразовывать строки развертки в данные пикселей вашей структуры. Строка сканирования округляется в большую сторону, и последние несколько байтов не используются. Вы не должны не копировать их в данные изображения. Тем не менее: наверное, это слишком сложно для вас, но, возможно, это поможет.   -  person Paul Ogilvie    schedule 16.07.2019
comment
Сначала нужно декодировать сжатие jpeg, чтобы получить несжатое изображение, например, keyj.emphy.de/nanojpeg. На первый взгляд кажется, что их код использует 32-битный формат пикселей RGBA, но ваш файл jpeg, вероятно, 24-битный, так что это может вызвать проблему. Вы можете отредактировать его, например, с помощью gimp до формата, совместимого с этим кодом.   -  person Neil    schedule 16.07.2019


Ответы (1)


Ваша проблема здесь, вероятно, не столько в том, чтобы выяснить, как вызвать scale, а в большей степени в том, чтобы выяснить, как загружать ваши изображения. Я рекомендую библиотеку SOIL, она обрабатывает наиболее распространенные форматы и предоставляет вам необработанные данные пикселей.

Вам также, скорее всего, понадобится какая-то функция для создания реальных image_t экземпляров из необработанного изображения. SOIL и другие библиотеки изображений должны иметь возможность предоставить вам ширину и высоту, а также какой-либо массив байтов или int для самого изображения. 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;
}

Просто не забудьте освободить пиксельные данные вашего изображения после того, как вы закончите его использовать.

person elucent    schedule 16.07.2019