首页 文章

从SDL_Texture访问像素颜色

提问于
浏览
1

我的代码抛出了访问错误 . 这是代码:

SDL_Color *getPixelColor(SDL_Surface *loadingSurface, int x, int y) {

    SDL_Color getColor = {0,0,0};

    SDL_Texture *readingTexture = nullptr;
    readingTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, loadingSurface->w, loadingSurface->h);
    SDL_SetTextureBlendMode(readingTexture, SDL_BLENDMODE_BLEND);

    void * vPixels;

    SDL_LockTexture(readingTexture, &loadingSurface->clip_rect, &vPixels, &loadingSurface->pitch);

    memcpy(vPixels, loadingSurface->pixels, loadingSurface->w * loadingSurface->h);

    Uint32 *aPixels = (Uint32*)vPixels;

    SDL_UnlockTexture(readingTexture);

    //Get pixel at location.
    Uint32 getPixel = aPixels[y * loadingSurface->w + x];
    Uint8 *colors = (Uint8*)getPixel;

    //cout << colors[0] << " " << colors[1] << " " << colors[2] << endl;

    getColor.r = colors[0];
    getColor.g = colors[1];
    getColor.b = colors[2];

    SDL_Color *color = &getColor;
    return color;

}

抛出异常:读取访问冲突 . 颜色是0xFF00 .

我随时尝试访问颜色 . SDL文档中描述的方法都返回相同的错误,并且除了LazyFoo之外没有关于互联网的信息(此方法基于,但不起作用 . )

谢谢您的帮助 .

EDIT:

我通过重写它来修复我的代码并忽略了我用来理解SDL某些部分的一些不良来源 . 这是工作代码:

Uint32 getPixel(SDL_Surface *loadingSurface, int x, int y) {

    Uint32 *pixels = (Uint32*)loadingSurface->pixels;
    return pixels[(y * loadingSurface->pitch / 4) + x]; // I noticed that each y selection was off by 4 pixels in the y so I divided by 4. Why this is the case remains a mystery.

}

为什么我需要除以4是一个谜,需要一段时间来弄明白 . 有什么想法吗?

SDL_Color getPixelColor(SDL_Surface *loadingSurface, int x, int y) {

    SDL_Color getColor = {0,0,0};
    SDL_PixelFormat *format;
    Uint32 pixel, index;
    Uint8 red, green, blue, alpha;

    format = loadingSurface->format;
    SDL_LockSurface(loadingSurface);
    pixel = getPixel(loadingSurface, x, y);
    SDL_UnlockSurface(loadingSurface);

    index = pixel & format->Rmask;  
    index = index >> format->Rshift; 
    index = index << format->Rloss;  
    red = (Uint8)index;

    index = pixel & format->Gmask;   
    index = index >> format->Gshift; 
    index = index << format->Gloss;  
    green = (Uint8)index;

    index = pixel & format->Bmask;   
    index = index >> format->Bshift; 
    index = index << format->Bloss;  
    blue = (Uint8)index;

    index = pixel & format->Amask;
    index = index >> format->Ashift;
    index = index << format->Aloss;
    alpha = (Uint8)index;

    getColor.r = red;
    getColor.g = green;
    getColor.b = blue;
    getColor.a = alpha;

    return getColor;

}

1 回答

  • 1

    这一行:

    Uint8 *colors = (Uint8*)getPixel;
    

    据我所知,你的代码中, getPixel 是纹理中位置(x,y)的32位RGBA像素颜色值 . 然后由于某种原因将此值转换为 Uint8* .

    所以现在 colors 包含一个无意义的地址,等于像素颜色值,而不是 getPixel 的地址,正如您可能想要的那样 . 因此,当您执行 colors[0] 并尝试通过此"address"读取内存时,会出现访问冲突 .

    您是否要在转换之前首先获取 getPixel 的地址,以便访问各个颜色通道值?

    Uint8 *colors = (Uint8*)&getPixel; // Note the &
    

    与您的确切问题无关,但也与您的代码有关:您正在返回指向局部变量的指针:

    SDL_Color getColor = {0,0,0};
    // etc.
    SDL_Color *color = &getColor;
    return color;
    

    当函数返回时, getColor 将超出范围,函数的调用者将获得的是一个悬空指针 .

    您应该重写函数以按值返回 SDL_Color :只需 return getColor; 并将返回类型更改为 SDL_Color .

相关问题