问题描述
我得到的最接近的是这个:
The closest i've gotten is this:
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);
}
但它并没有保持透明度.我如何才能真正实现这一目标?
But it doesn't keep the transparency. How can i go about actually achieving this?
推荐答案
我不知道错误到底在哪里,我在我的机器上尝试了你的代码,它在我使用的图像上运行良好.我怀疑您的代码确实保留了透明度,但稍后在您的实现中将其删除.
I don't know where is the error exactly, I tried your code on my machine and it works well on the image I used. I suspect that your code indeed preserves transparency, but it is removed later in your implementation.
无论如何,如果我可以建议对您的代码进行改进:您不需要如此复杂的操作来垂直翻转表面.SDL_Surface
结构以行优先顺序存储像素数据,这意味着 pixels
数组是一系列行,其中每一行的大小为 pitch
字节.因此,要垂直翻转您的表面,您可以简单地遍历行并交换它们.这种方法的优点是不需要了解像素格式,因此可以对所有图像类型(alpha 通道或非 alpha 通道)实现,并且实现起来非常简单.
Anyway, if I may suggest an improvement for your code: you don't need such complicated operations to vertically flip a surface. The SDL_Surface
structure stores the pixel data in row-major order, meaning that the pixels
array is a sequence of rows, where each of these rows have a size of pitch
bytes. Thus, to flip your surface vertically, you can simply iterate over the rows and swap them. The advantage of this method is that it does not require knowledge about pixel format, so it can be implemented for all image types (alpha channel or not), and it is pretty simple to implement.
这是一个您可以编译和试验的最小示例:
Here is a minimal example that you can compile and experiment with:
#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;
}
这篇关于在 SDL2 中垂直翻转表面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!