由于 SDL_RenderReadPixels,PNG 文件颜色错误!或者:这个函数返回哪个SDL_PixelFormat?

问题描述 投票:0回答:1

(希望你喜欢阅读。我很抱歉内容太多......)

在我的 TexturWrapper 类中,我需要一种方法将主纹理或其一部分保存到 PNG 文件中。 (Textur 是德语,对于我的代码中的此类内容再次表示抱歉。)

IMG_SavePNG 只能将 SDL_Surface 保存到文件,而不是 SDL_Texture。

我的类的主要纹理可以是 SDL_TEXTUREACCESS_STREAMING 或 SDL_TEXTUREACCESS_TARGET。 由于目标可能性,我无法直接使用 SDL_LockTexture 访问纹理像素。 但我们需要像素数据来从纹理创建表面。

...理论上它按我的方式工作,但我无法获得正确的颜色。例如,我的一个测试文件在原始背景颜色中为青色,这意味着在 SDL_Color: {0, 255, 255, 255} 中,但 png 文件背景为黄色。 SDL_Color 黄色将为 {255, 255, 0 , 255}。所以我首先将蒙版换成红色和蓝色通道。有趣的是,更改后它仍然是黄色背景。 我尝试了其他组合,但没有效果。有些确实返回了 SDL_Error“未知像素格式”。

我将蒙版恢复正常并编写了一个函数来手动更改表面的像素:

void rearrangePixels(Uint8* pixelData, int width, int height, Uint32 rmask, Uint32 gmask, Uint32 bmask, Uint32 amask)

这些是 R、G、B 和 A 的所有可能组合:

RGBA
RGAB
RBGA
RBAG
RAGB
RABG
GRBA
GRAB
GBRA
GBAR
GARB
GABR
BRGA
BRAG
BGRA
BGAR
BARG
BAGR
ARGB
ARBG
AGRB
AGBR
ABRG
ABGR

...我只得到了 2 个不同的 png 文件产品。 1. 黄色背景或 2. 100% 透明且看不见的图片。

我尝试自己解决这个问题,使用 Google 并大量使用 phind.com 一个月了。

我也尝试在stackoverflow中的旧帖子和答案中找到解决方案,并且我合并了其他用户的一些代码,例如我的代码中的user1902824(即使我的SDL2版本中没有“SDL_CreateRGBSurfaceWithFormatFrom”)。 .

但我的问题仍然存在。

我正在使用 C4droid,直接在 C++17 中的 Android 上使用 SDL2 + SDL_Image。 我唯一的硬件是一台使用了 3-4 年的华为平板电脑,配备 3GB RAM 和 Android-8。这就是为什么 C4droid 不能是最新版本以及我的 SDL2 的原因。

编辑:

以我自己的技术水平无法解决这个问题。我真的尝试了我发现或能想到的一切。

  • 以各种可能的方式更改所有通道的顺序(如上所示)...
  • 忽略每个像素的第一个字节...
  • 使用我的 SDL2 版本在 SDL_RenderReadPixels 函数中知道的任何 SDL_PIXELFORMAT_ 标准作为参数...
  • 反转颜色(全部 3 个或同时仅 1 或 2 个)...
  • 不同种类的表面选项...

也许还有其他一些我现在不记得了。

我不确定,但我相信SDL_RenderReadPixels返回不同的数据, 取决于系统和/或硬件!?

无论如何,我一个人无法应对。 所以我会尽力为您提供更多信息和更好的代码, 您可以在 c4droid 中编译出一个 cpp 文件。 (您需要更改图像的路径)

顺便说一句,这是我使用的原始图像: Original colors 当我将文件加载到表面并直接使用 IMG_SavePNG 保存时,它是相同的!

这是我在代码中首先使用 SDL_RenderReadPixels 时得到的结果: Colors after the SDL_RenderReadPixels function

最后(对我来说最令人惊讶的是)这是我使用我的 无论通道组合如何,rearrangePixels 方法: Colors after my rearrangePixels method

这是我的代码的简化和更正版本(您可以将整个代码逐步复制并粘贴到一个 cpp 文件中,以使用 c4droid 进行编译):

首先,变量、SDL2、SDL_Image 和一些便利函数的初始化:

#include <SDL2/SDL.h>
#include <SDL_image.h>
#include <string>


// Global variables
static SDL_Window *myWindow;
static SDL_Renderer *myRenderer;


// call a message box
void MessageBox( std::string header , std::string message )
{
   SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_INFORMATION , header.c_str() , message.c_str() , NULL );
}


// clean up
void sdlExit( void )
{
    SDL_DestroyWindow( myWindow );
    IMG_Quit();
    SDL_DestroyRenderer( myRenderer );
    SDL_Quit();
    return;
}


// returns the aktual display mode in a sdl_rect
SDL_Rect GetDisplayMode()
{
    SDL_DisplayMode displayM;
    SDL_GetCurrentDisplayMode(0, &displayM);

    // get a percent of the display hight
    int percentY = displayM.h / 100;

    // trick the android bars out for fullscreen immersive-mode
    int adjustedY = - (percentY * 3); // Set y-coordinate 3% below the upperbound 
    int adjustedHeight = displayM.h + (percentY * 6); // hight + 6%

    SDL_Rect displayMode = {0, adjustedY, displayM.w, adjustedHeight};

    return displayMode;
}


// Initialize SDL2, SDL_Image and open a window
bool sdlInit( const char* title)
{
  // Initialize SDL2
  if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER )  != 0 ) {
        char txt[ 64 ];
          sprintf( txt , "Could not initialisieren SDL2: %s.\n" , SDL_GetError() );
            MessageBox( "In Function sdlInit:" , txt );
            return false;
  }
  atexit( SDL_Quit );

        // Device display mode
        SDL_Rect displayMode = GetDisplayMode();

  // the window:
  myWindow = SDL_CreateWindow(
      title,                                                                   // title "..."
      SDL_WINDOWPOS_UNDEFINED,                  // initialize x position
      SDL_WINDOWPOS_UNDEFINED,                  // initialize y position
      displayMode.w,                                               // width, in pixel
      displayMode.h,                                                // hight, in pixel
      SDL_WINDOW_FULLSCREEN_DESKTOP ); // windowmode or 0

// Start Immersive Full-Screen-Mode
SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1");
SDL_SetWindowFullscreen(myWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);

  // Check window
  if ( myWindow == NULL ) {
        char txt[ 64 ];
          sprintf( txt , "Could not create window: %s\n" , SDL_GetError() );
            MessageBox( "In Function sdlInit:" , txt );
            return false;
  }

  // Initialize Renderer,
  myRenderer = SDL_CreateRenderer( myWindow , -1 , SDL_RENDERER_ACCELERATED ); 
  SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY , "linear" );
  SDL_RenderSetLogicalSize( myRenderer , displayMode.w , displayMode.h );

  // Check Renderer
  if ( myRenderer == NULL ) {
        char txt[ 64 ];
          sprintf( txt , "Could not initialize renderer: %s\n" , SDL_GetError() );
            MessageBox( "In Function sdlInit:" , txt );
            return false;
  }

  // Set blending
  SDL_SetRenderDrawBlendMode( myRenderer , SDL_BLENDMODE_BLEND  );

  // Initialize SDL_Img--------------------------------F1.2
  int imgFlags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF;
  int initted = IMG_Init( imgFlags );
  if (( initted & imgFlags ) != imgFlags ) {
        char txt[ 64 ];
          sprintf( txt , "IMG_Init: Failed to init required support: %s\n", IMG_GetError() );
            MessageBox( "In Function sdlInit:" , txt );
            return false;
  }
  return true;
}

现在是 TexturWrapper 类主体:

class TexturWrapper
{
      
    public:
    
        // Init Variables
        TexturWrapper();

        // Destructor
        ~TexturWrapper();

        // Load ...with colorKey?
        bool Laden( std::string pfad , bool CKAktiv = 0 , unsigned char CKr = 0 , unsigned char CKg = 0 , unsigned char CKb = 0  );

        // Blank-Texture
        bool Blank( int BREITE , int HOEHE , char ta ); // (w, h, 's' = streaming and 't' = target)

        // Size of Image
        int getBreite(); //width
        int getHoehe(); //highth

        // Set as Rendertarget
        void Renderziel();

            // Reset Rendertarget
            void RenderzielReset();

        // Render Texture (texture-clip) to specific place in specific angle in specific size
        void Rendern( int x , int y , SDL_Rect* clip = NULL , double angle = 0.0 , SDL_Point* center = NULL ,  SDL_RendererFlip flip = SDL_FLIP_NONE , SDL_Rect* rQuad = NULL , bool centerScale = true);

         // Pixel-Manipulation
         SDL_Surface* flip_surface_vertical(SDL_Surface* sfc);

         // Put ImageTextur (ImageTextur - clip) to a file
         void SaveImage(const char *filename, SDL_Rect* clip = NULL, SDL_Rect* rQuad = NULL);

        //For use if the Rendersize is adjustet (adjustRectToPreserveAspectRatio)
        int getPositionX();
      int getPositionY();
        int getRenderW();
        int getRenderH();

        // destroy just texture
        void free();
        // Object clear
        void leeren();

    private:

      // tried to get a correction of the result from SDL_RenderReadPixels()
      void rearrangePixels(Uint8* pixelData, int width, int height, Uint32 rmask, Uint32 gmask, Uint32 bmask, Uint32 amask) {
          for (int y = 0; y < height; ++y) {
              for (int x = 0; x < width; ++x) {
                  // pointer to one pixel
                  Uint8* pixel = pixelData + y * width * 4 + x * 4;
      
                  // extract pixeldata
                  Uint32 pixelValue = *(Uint32*)pixel;
//                  pixelValue = pixelValue << 8; // Ignore first byte if this would be the problem
      
                  Uint8 r = (pixelValue & rmask) >> 24;
                  Uint8 g = (pixelValue & gmask) >> 16;
                  Uint8 b = (pixelValue & bmask) >> 8;
                  Uint8 a = pixelValue & amask;
      
                  // invert colors ? tried the channels even separatet or in combination of 2 out
      //            r = 255 - r;
      //            g = 255 - g;
      //            b = 255 - b;
      
                  // new order of the color-channels
                  *pixel = (a << 24) | (r << 16) | (g << 8) | b;
              }
          }
      }

      
      void adjustRectToPreserveAspectRatio(SDL_Rect* srcRect, SDL_Rect* dstRect) {
          float srcAspectRatio = (float)srcRect->w / srcRect->h;
          float dstAspectRatio = (float)dstRect->w / dstRect->h;
          if (srcAspectRatio > dstAspectRatio) {
              // if texture.w > destination.w, change hight
              dstRect->h = dstRect->w / srcAspectRatio;
          } else if (srcAspectRatio < dstAspectRatio) {
              // if texture.h > destination.h, change width
              dstRect->w = dstRect->h * srcAspectRatio;
          }
      }
    
    // Main-Texture
    SDL_Texture* ImageTextur;

      // Renderdestination
      SDL_Rect renderQuad = { 0 , 0 , 0 , 0 };

            // The pixeldata if Lock is possible
        void* Pixels;
        int Pitch;

        // Image dimensions
        int ImageBreite;
        int ImageHoehe;
        
        // ColorKey
        bool CKAktiv;
        unsigned char CKr;
        unsigned char CKg;
        unsigned char CKb;
        
};

这里是实现:

TexturWrapper::TexturWrapper() 
{
    // Initialise Variables
    ImageTextur = NULL;
    ImageBreite = 0;
    ImageHoehe = 0;
    Pixels = NULL;
    Pitch = 0;
}

TexturWrapper::~TexturWrapper()
{
    leeren();
}

bool TexturWrapper::Laden( std::string pfad , bool CKAktiv , unsigned char CKr , unsigned char CKg , unsigned char CKb )
{
    free();

    // New Texture
    SDL_Texture* NeueTextur = NULL;

    // Load Image from path
    SDL_Surface* FileSurface = IMG_Load( pfad.c_str() );
    if( FileSurface == NULL )
    {
            char txt[ 64 ];
              sprintf( txt , "Could not load image: %s! SDL_image Error: %s\n" , pfad.c_str() , IMG_GetError() );
                MessageBox( "In class TexturWrapper:" , txt );
                exit( EXIT_FAILURE );
    }
    else
    {

        SDL_Surface* formattedSurface = SDL_ConvertSurfaceFormat( FileSurface , SDL_PIXELFORMAT_RGBA8888 , 0 );

        NeueTextur = SDL_CreateTexture( myRenderer , SDL_PIXELFORMAT_RGBA8888 , SDL_TEXTUREACCESS_STREAMING , formattedSurface->w , formattedSurface->h );

        ImageBreite = formattedSurface->w;
        ImageHoehe = formattedSurface->h;

        SDL_SetTextureBlendMode( NeueTextur , SDL_BLENDMODE_BLEND );

        SDL_LockTexture( NeueTextur , &formattedSurface->clip_rect , &Pixels , &Pitch );

            memcpy( Pixels , formattedSurface->pixels , formattedSurface->pitch * formattedSurface->h );
      
            // Pixels-Data into editable Format
            Uint32* pixels = (Uint32*)Pixels;
            int pixelCount = ( Pitch / 4 ) * ImageHoehe;
      
            // ColorKey Image
            if ( CKAktiv == 1 ) {
                    // Map Colors               
                    Uint32 colorKey = SDL_MapRGB( formattedSurface->format , CKr , CKg , CKb );
                    Uint32 transparent = SDL_MapRGBA( formattedSurface->format , 0x00 , 0xFF , 0xFF , 0x00 );
            
                    // ColorKey pixels
                    for( int i = 0 ; i < pixelCount ; ++i ) {
                        if( pixels[ i ] == colorKey ) {
                            pixels[ i ] = transparent;
                        }
                    }
                  }

        SDL_UnlockTexture( NeueTextur );
        Pixels = NULL;


        // clean up
        SDL_FreeSurface( formattedSurface );
        SDL_FreeSurface( FileSurface );
    }

    ImageTextur = NeueTextur;
      NeueTextur = NULL;
      SDL_DestroyTexture(NeueTextur);
    
    CKAktiv = 0;
    CKr = 0;
    CKg = 0;
    CKb = 0;
    
    return ImageTextur != NULL; 
}

void TexturWrapper::free()
{
    if( ImageTextur != NULL )
    {
        SDL_DestroyTexture( ImageTextur );
        ImageTextur = NULL;
        ImageBreite = 0;
        ImageHoehe = 0;
        Pixels = NULL;
        Pitch = 0;
    }
}

void TexturWrapper::leeren()
{
        SDL_DestroyTexture( ImageTextur );
        ImageTextur = NULL;
        ImageBreite = 0;
        ImageHoehe = 0;
        Pixels = NULL;
        Pitch = 0;
        CKAktiv = 0;
        CKr = 0;
        CKg = 0;
        CKb = 0;
}

void TexturWrapper::Rendern( int x , int y , SDL_Rect* clip , double angle , SDL_Point* center , SDL_RendererFlip flip , SDL_Rect* rQuad , bool centerScale )
{

      if (rQuad != NULL)
      {
            //the picture
            SDL_Rect* TextureQuad = new SDL_Rect;
            TextureQuad->x = 0;
            TextureQuad->y = 0;
            TextureQuad->w = ImageBreite;
            TextureQuad->h = ImageHoehe;
            // Render area
            renderQuad.x = rQuad->x;
            renderQuad.y = rQuad->y;
            renderQuad.w = rQuad->w;
            renderQuad.h = rQuad->h;
            // scale, by keeping proportions
            adjustRectToPreserveAspectRatio(TextureQuad, &renderQuad);
            if (centerScale) {
                  // center picture in the middle on to renderpoint
                  renderQuad.x -= renderQuad.w / 2;
            }
            delete TextureQuad;
      }
      else {
            // Set render position and size on screen
            renderQuad = { x , y , ImageBreite , ImageHoehe };
      }

      // Set Clip_Rendering Dimensions and fit target-rect to it if clip exists
      if (clip != NULL)
      {
          renderQuad.w = clip->w;
          renderQuad.h = clip->h;
          adjustRectToPreserveAspectRatio(clip, &renderQuad);
      }

      SDL_RenderCopyEx( myRenderer , ImageTextur , clip , &renderQuad , angle , center , flip );
}

int TexturWrapper::getBreite()
{
    return ImageBreite;
}

int TexturWrapper::getHoehe()
{
    return ImageHoehe;
}

int TexturWrapper::getPositionX()
{
    return renderQuad.x;
}

int TexturWrapper::getPositionY()
{
    return renderQuad.y;
}

int TexturWrapper::getRenderW()
{
    return renderQuad.w;
}

int TexturWrapper::getRenderH()
{
    return renderQuad.h;
}

void TexturWrapper::Renderziel()
{
    SDL_SetRenderTarget( myRenderer , ImageTextur );
}

void TexturWrapper::RenderzielReset()
{
    SDL_SetRenderTarget( myRenderer , NULL );
}

bool TexturWrapper::Blank( int b , int h , char ta )
{
    // Blank Texture for Streaming....
      if ( ta == 's' ) {
    ImageTextur = SDL_CreateTexture( myRenderer , SDL_PIXELFORMAT_RGBA8888 , SDL_TEXTUREACCESS_STREAMING , b , h );
      }
      else if ( ta == 't' ) { // ...or Target access
    ImageTextur = SDL_CreateTexture( myRenderer , SDL_PIXELFORMAT_RGBA8888 , SDL_TEXTUREACCESS_TARGET , b , h );
      }
    if( ImageTextur == NULL )
    {
            char txt[ 64 ];
                sprintf( txt , "Could not create blank texture! SDL Error: %s\n" , SDL_GetError() );
                  MessageBox( "In class TexturWrapper:" , txt );
                  exit( EXIT_FAILURE );
    }
    else
    {
        ImageBreite = b;
        ImageHoehe = h;
    }
      Renderziel();
      SDL_SetRenderDrawColor(myRenderer, 0x00, 0x00, 0x00, 0x00);
      SDL_RenderClear(myRenderer);
      RenderzielReset();
      SDL_SetTextureBlendMode( ImageTextur , SDL_BLENDMODE_BLEND );
    return ImageTextur != NULL;
}


SDL_Surface* TexturWrapper::flip_surface_vertical(SDL_Surface* sfc)
{
    SDL_Surface* result = SDL_CreateRGBSurface(sfc->flags, sfc->w, sfc->h,
        sfc->format->BytesPerPixel * 8, sfc->format->Rmask, sfc->format->Gmask,
        sfc->format->Bmask, sfc->format->Amask);
    const auto pitch = sfc->pitch;
    const auto pxlength = pitch*(sfc->h - 1);
    auto pixels = static_cast<unsigned char*>(sfc->pixels) + pxlength;
    auto rpixels = static_cast<unsigned char*>(result->pixels) ;
    for(auto line = 0; line < sfc->h; ++line) { // copy sfc to result line by line, upside-down
        memcpy(rpixels,pixels,pitch);
        pixels -= pitch;
        rpixels += pitch;
    }
    return result;
}

这是我的问题所在的方法:

// This is the method I try to get to work correctly!
void TexturWrapper::SaveImage(const char* file_name, SDL_Rect* clipRect, SDL_Rect* rQuadRect)
{
    // test clipRect and rQuadRect for NULL
    SDL_Rect clip = {0, 0, ImageBreite, ImageHoehe};
    SDL_Rect rQuad = {0, 0, ImageBreite, ImageHoehe};
    if (clipRect) {
        clip = *clipRect;
    }
    if (rQuadRect) {
        rQuad = *rQuadRect;
    }
    SDL_Texture* rQuadTexture = SDL_CreateTexture(myRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, rQuad.w, rQuad.h); // final-size texture
    SDL_SetRenderTarget(myRenderer, rQuadTexture); // make it target
    SDL_RenderCopy(myRenderer, ImageTextur, &clip, NULL); // render clip to it

    // surface in rQuad size
    SDL_Surface* surface = SDL_CreateRGBSurface(0, rQuad.w, rQuad.h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);

    // get the pixels of rQuadTexture
    SDL_RenderReadPixels(myRenderer, NULL, surface->format->format, surface->pixels, surface->pitch);

    SDL_PixelFormat* format = surface->format;

/* // To gether information about the SDL_RenderReadPixels output-format
    char txt[ 256 ];
    sprintf( txt , "\nBits per pixel: %d\n Bytes per pixel: %d\n Rmask: %08X\n Gmask: %08X\n Bmask: %08X\n Amask: %08X\n" , format->BitsPerPixel, format->BytesPerPixel, format->Rmask, format->Gmask, format->Bmask, format->Amask);
    MessageBox( "Das Format:" , txt );
*/

      // lock if needed
      if (SDL_MUSTLOCK(surface)) {
          SDL_LockSurface(surface);
      }
      
      // manipulate pixeldata
      rearrangePixels((Uint8*)surface->pixels, surface->w, surface->h, format->Rmask, format->Gmask, format->Bmask, format->Amask);
      
      // Unlock if needet
      if (SDL_MUSTLOCK(surface)) {
          SDL_UnlockSurface(surface);
      }

    SDL_Surface* flipSurf = flip_surface_vertical( surface ); // because RenderReadPixels returns upsidedown data

    IMG_SavePNG(flipSurf, file_name);
    SDL_FreeSurface(surface);
    SDL_FreeSurface(flipSurf);
    SDL_SetRenderTarget(myRenderer, NULL);
}

最后是 main() 来测试一切:

int main( void )
{
  std::string picturefile = "resources/M.png"; // "path to an imagefile.png"

  if ( !sdlInit( "Testing TexturWrapper class" ) ) { // Initialize SDL2 and SDL_Image
      exit( EXIT_FAILURE );
  }

  // TexturWrapper class objects
  TexturWrapper tw1;
  TexturWrapper tw2;
  TexturWrapper tw3;

  tw1.Laden( picturefile ); // Load the imagefile without color-keying
  SDL_Rect screen = GetDisplayMode();
  tw1.Rendern( screen.x , screen.y , NULL , 0.0 , NULL , SDL_FLIP_NONE , &screen, false ); // Render it (scaled) to the middle of the screen...  // false = renderpoint is not centered (0 = 0 and not -(half of the texture.w))

  SDL_RenderPresent( myRenderer ); // Show rendered stuff on the screen
  SDL_Delay( 3000 );

  tw2.Blank( tw1.getRenderW() , tw1.getRenderH() , 't' ); // 't' = SDL_TEXTUREACCESS_TARGET
  tw2.Renderziel(); // This object is now the rendertarget

  tw1.Rendern( screen.x , screen.y , NULL , 0.0 , NULL , SDL_FLIP_NONE , &screen , false ); // 'copy' tw1 to tw2
  tw2.RenderzielReset(); // Rendertarget = myWindow

  tw2.Rendern( screen.x , screen.y , NULL , 0.0 , NULL , SDL_FLIP_NONE , &screen , false ); // show the copy

  SDL_RenderPresent( myRenderer ); // Show rendered stuff on the screen
  SDL_Delay( 3000 );

  SDL_Rect clip = {0, 0, 500, 500}; // if you want to save just a clip of the copy
  SDL_Rect rquad = {0, 0, tw2.getBreite()/4, tw2.getHoehe()/4}; // size of the picture.png
  tw2.SaveImage( "Testfile.png" );//, &clip, &rquad ); // Save the copy as image

  tw3.Laden( "Testfile.png" ); // Load the saved image
  tw3.Rendern( screen.x , screen.y , NULL , 0.0 , NULL , SDL_FLIP_NONE , &screen, false ); // Show then loaded

  SDL_RenderPresent( myRenderer ); // Show rendered stuff on the screen
  SDL_Delay( 3000 );

  // clean up
  tw1.leeren();
  tw2.leeren();
  tw3.leeren();
  sdlExit();
  exit( EXIT_SUCCESS );
}
android c++ c++17 sdl-2 sdl-image
1个回答
0
投票

我也使用 sdl2 进行编程。我在 Windows 上成功测试了您的 SaveImage 方法作为纯函数,这意味着结果的颜色排列正确并且没有扭曲。因此,您关于 SDL_RenderReadPixels 由于硬件而提供不同回报的假设可能是正确的。

数据的测定给你揭示了什么?

/* // 收集有关 SDL_RenderReadPixels 输出格式的信息 字符txt[256]; sprintf( txt , " 每像素位数:%d 每像素字节数:%d 掩码:%08X 掩码:%08X B掩码:%08X 阿马斯克:%08X " , 格式->BitsPerPixel, 格式->BytesPerPixel, 格式->Rmask, 格式->Gmask, 格式->Bmask, 格式->Amask); MessageBox( "Das 格式:" , txt ); */

在我看来,你会在这里找到解决问题的关键。

© www.soinside.com 2019 - 2024. All rights reserved.