SDL2通过操纵像素和SDL_UpdateTexture()搞砸了图像

时间:2013-09-01 08:30:19

标签: c image sdl sdl-2

我正在尝试制作一个简单的图像查看器。我基本上将图像加载到表面,然后从中创建纹理。

最后,我根据migration guide执行通常的SDL_RenderClear()SDL_RenderCopy()SDL_RenderPresent()

这样可以正常工作,但如果我在上面的3个渲染调用之前调用SDL_UpdateTexture(),我会得到一个混乱的图像:

Messed up image

我这样调用SDL_UpdateTexture():

SDL_UpdateTexture(texture, NULL, image->pixels, image->pitch)

image是我为图像加载的表面,texture是我从中创建的纹理。尝试改变音调会导致不同的混乱图像。我也尝试使用rect作为第二个参数,但如果rect与图像具有相同的尺寸,结果是相同的。如果尺寸较大(例如与窗口相同),则不会发生更新,但没有错误。

full code可用。

我想通过image->pixels直接操作曲面的像素,然后调用SDL_UpdateTexture(),但只是在没有任何篡改的情况下调用SDL_UpdateTexture()就足以搞砸了。

2 个答案:

答案 0 :(得分:2)

我认为音高或SDL_Rect参数有问题, 但是还有另一个SDL功能可能会有所帮助:

SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer,
                                      SDL_Surface*  surface)

答案 1 :(得分:0)

你可以试试以下吗?它应该将任何粉红色(r = 255,g = 0,b = 255)像素替换为透明。您只需更改pixel32操作即可满足您的需求。

SDL_Surface* image = IMG_Load(filename);

SDL_Surface* imageFomatted = SDL_ConvertSurfaceFormat(image, 
                                                      SDL_PIXELFORMAT_RGBA8888, 
                                                      NULL);

texture = SDL_CreateTexture(renderer,
                            SDL_PIXELFORMAT_RGBA8888,
                            SDL_TEXTUREACCESS_STREAMING,
                            imageFomatted->w, imageFomatted->h);

void* pixels = NULL;
int pitch = 0;

SDL_LockTexture(texture, &imageFomatted->clip_rect, &pixels, &pitch);

memcpy(pixels, imageFomatted->pixels, (imageFomatted->pitch * imageFomatted->h));

int width   = imageFomatted->w;
int height  = imageFomatted->h;

Uint32* pixels32    = (Uint32*)pixels;
int     pixelCount  = (pitch / 4) * height;

Uint32 colorKey     = SDL_MapRGB(imageFomatted->format, 0xFF, 0x00, 0xFF);
Uint32 transparent  = SDL_MapRGBA(imageFomatted->format, 0xFF, 0x00, 0xFF, 0x00);

for (int i = 0; i < pixelCount; i++) {
  if (pixels32[i] == colorKey) {
    pixels32[i] = transparent;
  }
}

SDL_UnlockTexture(texture);

SDL_FreeSurface(imageFormatted);
SDL_FreeSurface(image);

pixels = NULL;
pitch = 0;
width = 0;
height = 0;