• Advertisement
Sign in to follow this  

Transparent png not transparent with sdl_image

This topic is 2137 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I created a png in photoshop with a transparent background, and when I load up the png it has transparency. But when I load it into my game using SDL_image it appears white where it should be transparent.I am not use SDL_BlitSurface(),I use getPiexl() and putPiexl() instead,here is my code:
[color=#0000cd]#include <iostream>
#include <string>
#include "SDL/SDL_image.h"
using namespace std;


void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
*p = pixel;
break;

case 2:
*(Uint16 *)p = pixel;
break;

case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;

case 4:
*(Uint32 *)p = pixel;
break;
}
}

Uint32 getPixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch(bpp) {
case 1:
return *p;

case 2:
return *(Uint16 *)p;

case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;

case 4:
return *(Uint32 *)p;

default:
return 0; /* shouldn't happen, but avoids warnings */
}
}



int main(int argc, char *argv[]) {

SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *pScreen = ::SDL_SetVideoMode(640, 480, 0, SDL_SWSURFACE | SDL_DOUBLEBUF);
SDL_Surface *image = IMG_Load("jbutton.png");
SDL_DisplayFormatAlpha(image);
for(int i=0;i<image->w;i++)
{
for(int j=0;j<image->h;j++)
{

Uint32 color=getPixel(image,i,j);
putPixel(pScreen,i,j,color);


}
}
// SDL_BlitSurface(img, 0, video, 0); //this will be ok
SDL_Flip(pScreen);
SDL_Delay(5000);

SDL_Quit();
return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
As I recall, you can set alpha:


//SDL_SetAlpha(surface_name, SDL_SRCALPHA, SDL_ALPHA_TRANSPARENT);
//SDL_DisplayFormatAlpha(surface_name);

However, I never needed to use it to get true transparency.

Share this post


Link to post
Share on other sites
sorry , I am a freshman in SDL ,it does not help,the main code is here,:
[color=#0000cd]int main(int argc, char *argv[]) {

SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *pScreen = ::SDL_SetVideoMode(640, 480, 0, SDL_SWSURFACE | SDL_DOUBLEBUF);
SDL_Surface *image = IMG_Load("jbutton.png");
SDL_SetAlpha(image, SDL_SRCALPHA, SDL_ALPHA_TRANSPARENT);
SDL_Surface *screen = SDL_DisplayFormatAlpha(image);
for(int i=0;i<image->w;i++)
{
for(int j=0;j<image->h;j++)
{
Uint32 color=getPixel(screen,i,j);
putPixel(pScreen,i,j,color);

}
}
// SDL_BlitSurface(img, 0, video, 0); //this will be ok
SDL_Flip(pScreen);
SDL_Delay(5000);

SDL_Quit();
return 0;
}

Share this post


Link to post
Share on other sites
You shouldn't loop the image and draw it pixel by pixel...



SDL_RWops *gold_rwops = SDL_RWFromFile("img/gold.png", "rb");
SDL_Surface *gold = IMG_LoadPNG_RW(gold_rwops);

SDL_Rect tile = {250 + x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE};
SDL_BlitSurface(gold, NULL, screen, &tile);


Here's how I did it.

Share this post


Link to post
Share on other sites
thank you for that , but I should change the size of the image ,so I can't use SDL_BlitSurface() to do this in my game.I have to draw it pixel by pixel.
the code above can work with PNG-8 ,but it can't work with PNG-24 or PNG-32

Share this post


Link to post
Share on other sites
not only size , I have to flip the image also and some other things according to the game logic . Can I use putPiexl() and getPiexl() to do this?

Share this post


Link to post
Share on other sites
SDL doesn't handle blitting to a surface with alpha properly (it ignores alpha of the destination surface), so alpha to alpha blits have to be done pixel by pixel. Other than that, you should be fine with using regular blits.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement