SDL2 透明背景
SDL2 transparent background
我正在尝试从较大的.PNG图像创建.PNG图像。 基本上剪裁原始的矩形区域并将结果另存为另一个.PNG 有点像纹理解包机,如果你愿意的话。
我的问题是原始图像中透明的部分在剪切的图像中是彩色的。
最初我使用硬件加速,背景是白色的,有斑点,切换到软件渲染器只是将背景更改为黑色。
我想保持原始图像的透明度。
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
void save_texture(const char* file_name, SDL_Renderer* renderer, SDL_Texture* texture); //
save png to disk
SDL_Texture* clipTexture(SDL_Rect rect, SDL_Renderer* renderer, SDL_Texture* source); // get
a new texture that is clipped from the original
int main(int argc, const char * argv[])
{
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_PNG);
SDL_Surface* surface = IMG_Load("LevelItems.png");
SDL_Renderer* renderer = SDL_CreateSoftwareRenderer(surface);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect frame_rect = { 189, 243,115, 50 };
SDL_Texture* tex_clip = clipTexture( frame_rect, renderer, texture );
save_texture("test1.png", renderer, tex_clip);
SDL_FreeSurface(surface);
return 0;
}
// return a new texture that is a part of the original texture.
SDL_Texture* clipTexture(SDL_Rect rect, SDL_Renderer* renderer, SDL_Texture* source)
{
SDL_Texture* result = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET, rect.w, rect.h);
SDL_SetRenderTarget(renderer, result);
SDL_RenderCopy(renderer, source, &rect, NULL);
return result;
}
// save png to disk
void save_texture(const char* file_name, SDL_Renderer* renderer, SDL_Texture* texture)
{
int width, height;
SDL_QueryTexture(texture, NULL, NULL, &width, &height);
SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
SDL_RenderReadPixels(renderer, NULL, surface->format->format, surface->pixels, surface-
>pitch);
IMG_SavePNG(surface, file_name);
SDL_FreeSurface(surface);
}
有两个问题:
-
禁用混合。在
RenderCopy
之前使用SDL_SetTextureBlendMode(source, SDL_BLENDMODE_NONE);
,否则你会得到错误的颜色(与默认的黑色混合 - 结果会比它更暗(。混合与纹理相关联,因此,如果您以后想使用此纹理,则可能应该立即重置混合模式。请参阅SDL_SetTextureBlendMode文档,了解在不同混合模式下使用的配方。 -
生成的表面没有 Alpha 通道,因此无处复制结果。查看文档以了解SDL_CreateRGBSurface:虽然它允许对颜色遮罩使用
0
来推断默认值,但它明确不允许将其用于 alpha 通道,因此0
代替amask
结果是"我不想要 alpha 通道,只是 RGB"。生成的格式是打包为 32 位的 RGB888。你想要 alpha,所以你应该使用正确的颜色蒙版 - 从文档中获取一个,在您的情况下,您甚至不需要检查 endianess,但它永远不会受到伤害。
总结一下:
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
void save_texture(const char* file_name, SDL_Renderer* renderer, SDL_Texture* texture);
SDL_Texture* clipTexture(SDL_Rect rect, SDL_Renderer* renderer, SDL_Texture* source);
int main(int argc, const char * argv[])
{
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_PNG);
SDL_Surface* surface = IMG_Load("test.png");
SDL_Renderer* renderer = SDL_CreateSoftwareRenderer(surface);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect frame_rect = { 189, 243,115, 50 };
SDL_Texture* tex_clip = clipTexture( frame_rect, renderer, texture );
save_texture("test1.png", renderer, tex_clip);
SDL_FreeSurface(surface);
return 0;
}
// return a new texture that is a part of the original texture.
SDL_Texture* clipTexture(SDL_Rect rect, SDL_Renderer* renderer, SDL_Texture* source)
{
SDL_Texture* result = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET, rect.w, rect.h);
SDL_SetRenderTarget(renderer, result);
SDL_SetTextureBlendMode(source, SDL_BLENDMODE_NONE);
SDL_RenderCopy(renderer, source, &rect, NULL);
return result;
}
// save png to disk
void save_texture(const char* file_name, SDL_Renderer* renderer, SDL_Texture* texture)
{
int width, height;
SDL_QueryTexture(texture, NULL, NULL, &width, &height);
Uint32 rmask, gmask, bmask, amask;
#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* surface = SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask);
SDL_RenderReadPixels(renderer, NULL, surface->format->format, surface->pixels, surface->pitch);
IMG_SavePNG(surface, file_name);
SDL_FreeSurface(surface);
}
相关文章:
- 如何在全屏模式下(在OpenGL中)使背景透明
- SDL2 透明背景
- 一个标签,其背景一方面是透明的,另一方面是上部窗口
- 调整HBITMAP的大小,同时保持透明背景
- 当我使用 DirectWrite 在 GDI hdc 上绘制文本时,如何设置透明背景
- 通过使用alpha混合opengl实现具有透明背景的纹理
- 如何使用 c++/WinAPI 绘制具有透明背景的文本
- Qt透明QWebView:过去的页面停留在新页面的背景中
- OpenFrameworks中的透明背景窗口
- C++libPng 编写一个具有透明背景的 PNG
- QWebEngine页面中的透明背景
- SDL 纹理透明背景
- ID2D1HwndRenderTarget始终具有黑色背景而不是透明
- 使用C++/OpenCV或Matlab将图像的白色背景替换为透明背景
- 透明背景的C++按钮
- MFC显示具有透明背景的png
- 如何在QT中使背景半透明
- 如何使我的纹理背景透明?(我的图像已经没有背景了)
- Q获取背景透明
- 如何使分组框文本背景透明