Scaling up an image using nearest-neighbor

旧时模样 提交于 2019-12-02 04:52:53

I see that you're overcomplicating things (walking over the image twice for example).
Here's the code (I am posting the whole program - I made assumptions about Pixel and Image that might not match what you have), but if you copy / paste makeBigger it should work in your code OOTB:

code.c:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


typedef uint32_t Pixel;

typedef struct {
    uint32_t width, height;
    Pixel **pixels;
} Image;


void makeBigger(Image *img, int scale) {
    uint32_t i = 0, j = 0;
    Image *tmp = (Image*)malloc(sizeof(Image));
    tmp->height = img->height * scale;
    tmp->width = img->width * scale;

    tmp->pixels = (Pixel**)malloc(sizeof(Pixel*) * tmp->height);
    for (i = 0; i < tmp->height; i++) {
        tmp->pixels[i] = (Pixel*)malloc(sizeof(Pixel) * tmp->width);
        for (j = 0; j < tmp->width; j++) {
            tmp->pixels[i][j] = img->pixels[i / scale][j / scale];
        }
    }

    for (i = 0; i < img->height; i++)
        free(img->pixels[i]);
    free(img->pixels);

    img->width = tmp->width;
    img->height = tmp->height;
    img->pixels = tmp->pixels;
    free(tmp);
}


void printImage(Image *img) {
    printf("Width: %d, Height: %d\n", img->width, img->height);
    for (uint32_t i = 0; i < img->height; i++) {
        for (uint32_t j = 0; j < img->width; j++)
            printf("%3d", img->pixels[i][j]);
        printf("\n");
    }
    printf("\n");
}


int main() {
    uint32_t i = 0, j = 0, k = 1;
    Image img;
    // Allocate and initialize the image data
    img.height = 2;
    img.width = 3;
    img.pixels = (Pixel**)malloc(sizeof(Pixel*) * img.height);
    for (i = 0; i < img.height; i++) {
        img.pixels[i] = (Pixel*)malloc(sizeof(Pixel) * img.width);
        for (j = 0; j < img.width; j++)
            img.pixels[i][j] = k++;
    }

    printImage(&img);
    makeBigger(&img, 2);
    printImage(&img);

    // Deallocate the image data
    for (i = 0; i < img.height; i++)
        free(img.pixels[i]);
    free(img.pixels);

    return 0;
}

Notes (makeBigger related - designed to replace the content of the image given as argument):

  • Construct a temporary image that will be the enlarged one
  • Only traverse the temporary image once (populate its pixels as we allocate them); to maintain scaling to the original image and make sure that the appropriate pixel is "copied" into the new one, simply divide the indexes by the scaling factor: tmp->pixels[i][j] = img->pixels[i / scale][j / scale]
  • Deallocate the original image content: since each pixel row is malloced, it should also be freed (free(img->pixels); alone will yield memory leaks)
  • Store the temporary image content (into the original one) and then deallocate it

Output:

[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q041861274]> ls
code.c
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q041861274]> gcc -o code.exe code.c
[cfati@cfati-5510-0:/cygdrive/e/Work/Dev/StackOverflow/q041861274]> ./code.exe
Width: 3, Height: 2
  1  2  3
  4  5  6

Width: 6, Height: 4
  1  1  2  2  3  3
  1  1  2  2  3  3
  4  4  5  5  6  6
  4  4  5  5  6  6
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!