Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SDL2透明背景_C++_Sdl 2 - Fatal编程技术网

C++ SDL2透明背景

C++ SDL2透明背景,c++,sdl-2,C++,Sdl 2,我正在尝试从一个更大的.PNG图像创建一个.PNG图像。 基本上是剪辑原始图像的矩形区域,并将结果保存为另一个.PNG 有点像一个纹理解压器,如果你愿意的话 我的问题是,在原始图像中是透明的部分在剪裁图像中是彩色的 最初我使用硬件加速,背景是白色的斑点,切换到软件渲染器只是将背景更改为黑色 我想保持原始图像的透明度 #include <SDL2/SDL.h> #include <SDL2_image/SDL_image.h> void save_texture(con

我正在尝试从一个更大的.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);
}
#包括
#包括
void save_纹理(常量字符*文件名,SDL_渲染器*渲染器,SDL_纹理*纹理);//
将png保存到磁盘
SDL_纹理*clipTexture(SDL_Rect,SDL_渲染器*渲染器,SDL_纹理*源);//得到
从原始纹理剪裁的新纹理
int main(int argc,const char*argv[]
{
SDL_Init(SDL_Init_视频);
IMG_Init(IMG_Init_PNG);
SDL_Surface*Surface=IMG_载荷(“LevelItems.png”);
SDL_渲染器*渲染器=SDL_CreateSoftwareRenderer(曲面);
SDL_Texture*Texture=SDL_CreateTextureFromSurface(渲染器,曲面);
SDL_Rect frame_Rect={189243115,50};
SDL_纹理*tex_clip=clipTexture(帧、渲染器、纹理);
保存纹理(“test1.png”,渲染器,纹理剪辑);
SDL_自由曲面(曲面);
返回0;
}
//返回作为原始纹理一部分的新纹理。
SDL_纹理*clipTexture(SDL_Rect、SDL_渲染器*渲染器、SDL_纹理*源)
{
SDL_纹理*结果=SDL_CreateTexture(渲染器、SDL_像素格式、RGBA888、,
SDL_TEXTUREACCESS_TARGET,rect.w,rect.h);
SDL_SetRenderTarget(渲染器,结果);
SDL_RenderCopy(渲染器、源和rect、NULL);
返回结果;
}
//将png保存到磁盘
void save_纹理(常量字符*文件名,SDL_渲染器*渲染器,SDL_纹理*纹理)
{
int宽度、高度;
SDL_QueryTexture(纹理、空值、空值、宽度和高度);
SDL_Surface*Surface=SDL_CreateRGB曲面(0,宽度,高度,32,0,0,0,0);
SDL_渲染器像素(渲染器,空,曲面->格式->格式,曲面->像素,曲面-
>音高);
IMG_SavePNG(曲面、文件名);
SDL_自由曲面(曲面);
}

有两个问题:

  • 禁用混合。使用
    SDL\u SetTextureBlendMode(源代码,SDL\u BLENDMODE\u无)
    渲染复制
    之前,否则会得到错误的颜色(与默认的黑色混合-结果会比应该的颜色暗)。混合绑定到纹理,所以如果您想稍后使用此纹理,您可能应该立即重置混合模式。有关在不同混合模式下使用的公式,请参见文档

  • 生成的曲面没有alpha通道,因此无法复制结果。检查文档:虽然它允许对彩色遮罩使用
    0
    来推断默认值,但它明确不允许对alpha通道使用它,因此
    0
    代替
    amask
    会导致“我不想要alpha通道,只需要RGB”。生成的格式为RGB888,压缩为32位。你想要alpha,所以你应该使用正确的颜色遮罩-从文档中获得一个,在你的情况下,你甚至不需要检查是否有持久性,但它永远不会伤害你

  • 总而言之:

    #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);
    }
    
    #包括
    #包括
    void save_纹理(常量字符*文件名,SDL_渲染器*渲染器,SDL_纹理*纹理);
    SDL_纹理*clipTexture(SDL_Rect、SDL_渲染器*渲染器、SDL_纹理*源);
    int main(int argc,const char*argv[]
    {
    SDL_Init(SDL_Init_视频);
    IMG_Init(IMG_Init_PNG);
    SDL_表面*表面=IMG_载荷(“test.png”);
    SDL_渲染器*渲染器=SDL_CreateSoftwareRenderer(曲面);
    SDL_Texture*Texture=SDL_CreateTextureFromSurface(渲染器,曲面);
    SDL_Rect frame_Rect={189243115,50};
    SDL_纹理*tex_clip=clipTexture(帧、渲染器、纹理);
    保存纹理(“test1.png”,渲染器,纹理剪辑);
    SDL_自由曲面(曲面);
    返回0;
    }
    //返回作为原始纹理一部分的新纹理。
    SDL_纹理*clipTexture(SDL_Rect、SDL_渲染器*渲染器、SDL_纹理*源)
    {
    SDL_纹理*结果=SDL_CreateTexture(渲染器、SDL_像素格式、RGBA888、,
    SDL_TEXTUREACCESS_TARGET,rect.w,rect.h);
    SDL_SetRenderTarget(渲染器,结果);
    SDL_SetTextureBlendMode(源、SDL_BLENDMODE_无);
    SDL_RenderCopy(渲染器、源和rect、NULL);
    返回结果;
    }
    //将png保存到磁盘
    void save_纹理(常量字符*文件名,SDL_渲染器*渲染器,SDL_纹理*纹理)
    {
    int宽度、高度;
    SDL_QueryTexture(纹理、空值、空值、宽度和高度);
    Uint32 rmask、gmask、bmask、amask;
    #如果SDL_字节顺序==SDL_BIG_ENDIAN
    rmask=0xff000000;
    gmask=0x00ff0000;
    bmask=0x0000ff00;
    amask=0x000000ff;
    #否则
    rmask=0x000000ff;
    gmask=0x0000ff00;
    bmask=0x00ff0000;
    amask=0xff000000;
    #恩迪夫
    SDL_Surface*Surface=SDL_CreateRGB曲面(0,宽度,高度,32,rmask,gmask,bmask,amask);
    SDL_渲染器像素(渲染器,空,曲面->格式->格式,曲面->像素,曲面->间距);
    IMG_SavePNG(曲面、文件名);
    SDL_自由曲面(曲面);
    }
    
    RenderCopy
    之前,禁用与
    SDL\u SetTextureBlendMode(source,SDL\u BLENDMODE\u NONE)的混合。您可能希望稍后恢复混合模式。尝试过,不起作用,抱歉;(