在 SDL2 中垂直翻转表面
Flipping a surface vertically in 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;
}
我得到的最接近的是:
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;
}