在SDL2中垂直翻转曲面



我得到的最接近的是:

void Engine::flipSurfaceVertically(SDL_Surface* surface)
{
SDL_LockSurface(surface);
Uint8* pixels = reinterpret_cast<Uint8*>(surface->pixels);
for (int k = 0; k < sizeof(Uint32); ++k)
{
for (int i = 0; i < surface->w; ++i)
{
for (int j = 0; j < surface->h / 2; ++j)
{
Uint32 currentPos = (j * surface->pitch) + (i * sizeof(Uint32)) + k;
Uint32 target = ((surface->h - j - 1) * surface->pitch) + (i * sizeof(Uint32)) + k;
Uint8 temp = pixels[target];
pixels[target] = pixels[currentPos];
pixels[currentPos] = temp;
}
}
}
SDL_UnlockSurface(surface);
}

但是它没有保持透明度。我怎样才能真正做到这一点呢?

我不知道错误到底在哪里,我在我的机器上尝试了你的代码,它在我使用的图像上工作得很好。我怀疑你的代码确实保留了透明度,但它在你的实现中被删除了。

无论如何,如果我可以建议改进你的代码:你不需要这么复杂的操作来垂直翻转一个表面。SDL_Surface结构按行为主顺序存储像素数据,这意味着pixels数组是一个行序列,其中每一行的大小为pitch字节。因此,要垂直翻转曲面,只需遍历行并交换它们。这种方法的优点是它不需要关于像素格式的知识,因此它可以实现所有图像类型(alpha通道或非alpha通道),并且实现起来非常简单。

下面是一个最小的示例,您可以编译和实验:

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
void flip_surface(SDL_Surface* surface) 
{
SDL_LockSurface(surface);

int pitch = surface->pitch; // row size
char* temp = new char[pitch]; // intermediate buffer
char* pixels = (char*) surface->pixels;

for(int i = 0; i < surface->h / 2; ++i) {
// get pointers to the two rows to swap
char* row1 = pixels + i * pitch;
char* row2 = pixels + (surface->h - i - 1) * pitch;

// swap rows
memcpy(temp, row1, pitch);
memcpy(row1, row2, pitch);
memcpy(row2, temp, pitch);
}

delete[] temp;
SDL_UnlockSurface(surface);
}
int main(int argc, char* argv[]) 
{
SDL_Init(SDL_INIT_VIDEO);

SDL_Surface* surface = IMG_Load("image.png");
flip_surface(surface);
IMG_SavePNG(surface, "result.png");

SDL_Quit();

return 0;
}

最新更新