【问题标题】:Flipping a surface vertically in SDL2在 SDL2 中垂直翻转曲面
【发布时间】:2021-01-20 18:18:53
【问题描述】:

我得到的最接近的是:

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);
}

但它不保持透明度。我怎样才能真正实现这一目标?

【问题讨论】:

    标签: c++ sdl-2 sdl-image


    【解决方案1】:

    我不知道错误到底出在哪里,我在我的机器上尝试了你的代码,它在我使用的图像上运行良好。我怀疑您的代码确实保留了透明度,但在您的实施后期将其删除。

    无论如何,如果我可以建议对您的代码进行改进:您不需要如此复杂的操作来垂直翻转表面。 SDL_Surface 结构以行优先顺序存储像素数据,这意味着pixels 数组是一系列行,其中每一行的大小为pitch 字节。因此,要垂直翻转表面,您可以简单地遍历行并交换它们。这种方法的优点是不需要像素格式的知识,所以它可以适用于所有图像类型(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;
    }
    

    【讨论】:

    • 是的,我意识到有些事情正在尝试。首先,我决定重新利用 stb_image 的 sdl2 加载翻转功能的实现;然后我意识到它正在进行透明度,我只是没有意识到,因为我还不太熟悉着色器。
    • 非常好@wanpelt!很遗憾,这个功能不是库的一部分。
    • 我假设类似这样的东西可以用来水平翻转图像
    • @AntonioCS 遗憾的是,水平翻转图像的操作不同,不。在我的代码中,我使用了行存储在连续内存块中的事实,因此我可以在单个操作中安全地读取和写入行。列不是这种情况,因此如果要水平翻转图像,则需要逐个像素交换图像。
    • @wanpelt 没错,你不能完全使用代码,但是,交换的原理还是可以的。我认为水平翻转可能存在问题。谢谢
    猜你喜欢
    • 1970-01-01
    • 2012-03-25
    • 2015-05-17
    • 1970-01-01
    • 2014-04-28
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多