【问题标题】:Change alpha of image cropped with SDL_Rect using C++ & SDL使用 C++ 和 SDL 更改使用 SDL_Rect 裁剪的图像的 alpha
【发布时间】:2011-09-03 18:32:12
【问题描述】:

我需要调整图像 (SDL_Surface*) 的 alpha 值,该图像已使用 SDL_Rect 裁剪并显示在屏幕上。我有一个包含 3 个图像的图像文件 (.bmp),我使用 SDL_Rect 裁剪了每个图像,但我需要单独调整每个图像的 alpha。 这可以做到吗?

如果做不到这一点,我可以将每个裁剪的 SDL_Surface* 存储到一个新的 SDL_Surface 中,我可以在其中将 SDL_SetAlpha 应用于每个吗? 我意识到我可以裁剪原始图像并单独导入它们,但在这种情况下它不是一个选项。

我希望这一切都是有道理的,我是个不喜欢在这里提问的菜鸟,所以如果我以任何方式违反了协议,请原谅我。

编辑:

这就是我所拥有的;

SDL_Rect cropBoxPump1 = { 5, 103, 200, 200 };   
SDL_Rect positionPump1 = { 30, 103, 0, 0 };
SDL_Surface* pumpkinConvertedTo32bit = NULL;    
SDL_Surface *pumpkins = SDL_LoadBMP( "pumpkins_faces.bmp" );

pumpkinConvertedTo32bit = SDL_DisplayFormat( pumpkins );        
SDL_BlitSurface(pumpkinConvertedTo32bit, &cropBoxPump1, screen, &positionPump1);

因此,基于此,我实际上可以更改仅使用 SDL_Rect 裁剪的图像部分的 alpha 吗?而不是整个 SDL_Surface?

【问题讨论】:

    标签: c++ sdl


    【解决方案1】:

    您可以单独调整每个表面的 Alpha,它不会影响任何其他表面。唯一的条件是,表面应该有一个 Alpha 通道。要检查是否有 alpha 通道,请执行以下操作:

    SDL_Surface *surface; // Assume this has been allocated elsewhere.
    
    if (surface->format->Amask != 0)
    {
       // You have an alpha channel
    }
    else
    {
       // Make a copy to a surface with an alpha channel.
    }
    

    否则,是的,您必须将图像复制到具有 Alpha 通道的新表面。这能回答你的问题吗?

    [编辑] 以下是如何将表面的一部分复制到另一个表面。这部分基于文档here

    SDL_Rect cropBox = { 5, 103, 200, 200 };
    SDL_Rect position = {0,0,0,0};
    Uint32 rmask, gmask, bmask, amask;
    
    /* SDL interprets each pixel as a 32-bit number, so our masks must depend
       on the endianness (byte order) of the machine */
    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
    #else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
    #endif
    SDL_Surface *newSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,cropBox.w,
                                 cropBox.h,32,rmask,gmask,bmask,amask);
    
    SDL_BlitSurface(pumpkins,cropBox,newSurface,position);
    

    是的,用 Alpha 通道创建一个大小合适的表面,然后对其进行 blit。

    【讨论】:

    • 鉴于您的表面没有 Alpha 通道,我建议将每个子部分放在单独的表面中。如果它绝对必须留在单个表面中,那么您可以进入表面的像素数据并手动对其进行编辑,我可以更新我的帖子,它将向您展示如何做到这一点,但是将图像分解为单独的表面更容易并且更安全。
    • 嗨,我刚刚编辑了我的帖子以向您展示我所拥有的。如果无法编辑裁剪部分,您能告诉我如何将裁剪部分保存为另一个 Surface 吗?我在任何地方都找不到一个例子。非常感谢您的帮助
    • 哇,看起来好重啊!好的,我会试一试,让你知道结果。再次感谢您的帮助。
    • 它并不像看起来那么复杂。它只考虑字节顺序,(en.wikipedia.org/wiki/Endianness)。去掉所有遮罩的东西,基本上你创建一个新的表面,然后对它进行 blit。
    • 是的,不错。我一定会让你知道它是怎么回事,并在我让它工作后检查它作为答案。再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多