0

我正在写一个计算图像每个像素的 rgb 值的小东西。

我想在计算后显示每一个。问题是我不知道如何快速做到这一点。计算完整的图像然后显示它需要几秒钟,而正确显示每个像素需要几分钟。

重要的是我可以看到图像计算的进度。有没有办法在 SDL 1.2 中有效地解决这个任务?

我的代码现在如下所示:

SDL_Surface* screen = NULL;
SDL_Surface* image = NULL;

SDL_Init(SDL_INIT_EVERYTHING);

//Set up screen
screen = SDL_SetVideoMode(img.width(), img.height(), 32, SDL_SWSURFACE);

// create surface with default values
image = SDL_CreateRGBSurface(SDL_SWSURFACE,img.width(),img.height(),32,0,0,0,0);

if(image == NULL) {
    std::cout << "failed creating SDL surface";
}

// create array for pixels
Uint32 *pixels = (Uint32 *)image->pixels;

//Apply image to screen
SDL_BlitSurface(image, NULL, screen, NULL);

//Update screen
SDL_Flip(screen);

// compute image
for (int i = 0; i < img.width(); i++) {
    for (int j = 0; j < img.height(); j++) {
        img(i, j) = computeColor(i, j, img.width(), img.height());
        pixels[i * img.width() + j] = SDL_MapRGB(image->format,(Uint8)getR(img(i,j)), (Uint8)getG(img(i,j)),(Uint8)getB(img(i,j)));
        SDL_BlitSurface(image, NULL, screen, NULL);
        SDL_UpdateRect(screen, i, j, i, j);
    }
}

//Pause
SDL_Delay(2000);

//Free the loaded image
SDL_FreeSurface(image);

//Quit SDL
SDL_Quit();
4

2 回答 2

1

您不需要中间图像,您可以将像素直接放在屏幕表面上。您可以为每一行而不是每个像素调用 SDL_Flip() 或 SDL_UpdateRect(),这样会快得多。

此外,循环通过行而不是列会给您带来小的速度提升,因为单行上的像素在物理内存中彼此靠近,并且在现代 CPU 上顺序内存访问速度更快。

// create array for pixels
Uint32 *pixels = (Uint32 *)screen->pixels;

// Clear screen
SDL_FillRect(screen, NULL, 0);

//Update screen
SDL_Flip(screen);

// compute image
for (int j = 0; j < img.height(); j++) {
    for (int i = 0; i < img.width(); i++) {
        img(i, j) = computeColor(i, j, img.width(), img.height());
        pixels[i + j * img.width()] = SDL_MapRGB(image->format,(Uint8)getR(img(i,j)), (Uint8)getG(img(i,j)),(Uint8)getB(img(i,j)));
    }
    SDL_UpdateRect(screen, i, j, img.width(), 1);
}

// Display final result
SDL_Flip(screen);
SDL_Delay(2000);

您还可以为 img.height() 和 img.width() 创建单独的 int 变量,这样您就不会在每次迭代时都进行函数调用,但编译器通常能够优化它。

于 2014-10-28T17:47:07.820 回答
0

一次更改一个像素的通信开销将太高。这与您的特定 API 几乎没有关系。

尝试跟踪时间,并以指数方式更改更多像素,直到经过足够的时间(例如 1/100 秒)。然后更新它们。(仅在指数增加间隔后检查时钟)

这将为您带来进步,而不会因为一次解决方案的像素等开销而陷入困境。

于 2014-10-28T17:43:14.220 回答