PNG and Alpha

Is it possible to fade out a PNG image with SetAlpha? It doesn’t work for me.
If its not possible, what are some recommended alternatives given rounded,
shadowed images?

Thanks,
Gary__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Is it possible to fade out a PNG image with SetAlpha? It doesn’t work for me.
If its not possible, what are some recommended alternatives given rounded,
shadowed images?

Thanks,
Gary

You can’t fade image simply by calling SetAlpha, after that operation you have to render that image on screen, so that effects will be visible. Also, clearing background would be useful.

And yes, it’s certainly possible. In video memory, png is stored in the same way as ie. bmp. Just look at this example:

#include
#include <SDL.h>

SDL_Surface *image;
SDL_Surface *screen;
int alpha = 255;

void Draw()
{
SDL_Rect rect;
rect.y = 30;
rect.x = 30;
SDL_FillRect(screen, 0, 0);
SDL_BlitSurface(image, NULL, screen, &rect);
SDL_SetAlpha(image, SDL_SRCALPHA, alpha);
alpha–;
}

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

int done;

if (SDL_Init (SDL_INIT_VIDEO) < 0)
 {
 return 1;
 }
 
atexit (SDL_Quit);

screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
if (screen == NULL) return 1;

image = SDL_LoadBMP("elf.bmp"); // change this to IMG_Load("yoursprite.png");

done = 0;
while (!done)
{
 SDL_Event event;

 while (SDL_PollEvent (&event))
  {
   switch (event.type)
    {
     case SDL_QUIT:
      done = 1;
     break;
     }
  }
  Draw();
  SDL_Flip(screen);
  SDL_Delay(0);
}

return 0;

}

Koshmaar

Is it possible to fade out a PNG image with SetAlpha? It doesn’t work for me.
If its not possible, what are some recommended alternatives given rounded,
shadowed images?

I think I know what you are imagining SDL_SetAlpha doing. :slight_smile:
That is NOT what it is doing! When you use SDL_SetAlpha, you are
simply changing a property of a surface, NOT the pixels in the
surface. In order to alpha-blend (or fade as you call it) the surface,
use SDL_SetAlpha and SDL_BlitSurface in combination.

“Algorithm”:

SDL_Surface* screen = SDL_SetVideoMode(…);
SDL_Surface* P;
for every value i in the range 0…255
SDL_SetAlpha(P, i); // read up on exact syntax
SDL_BlitSurface(P, NULL, screen, NULL);
rof

/Olof

Read these API entries on the SDL-documentation:

  1. SDL_SetAlpha
  2. SDL_BlitSurfaceOn 8/8/05, G B wrote:

Thanks,
Gary


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

I’ve found questions and answers to doing this (fading out a PNG image) with
SDL+GL, but nothing for just SDL.

I’m doing:

SDL_Surface *image = IMG_Load(pathToPng);
SDL_SetAlpha(image, SDL_SRCALPHA, m_nCurrentAlphaLevel);
SDL_BlitSurface(image, …, screen, …);

The problem is that the SetAlpha call has no effect - I can’t fade the PNG
image in or out.

What might I be missing to fade the png properly

Thanks!
GB

— G B <@G_B> wrote:> Is it possible to fade out a PNG image with SetAlpha? It doesn’t work for

me.
If its not possible, what are some recommended alternatives given rounded,
shadowed images?

Thanks,
Gary


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Koshmaar,

Thanks for your input.

That example you provided uses a bmp. I’ve also been able to make code like
this work with bmp, but not with png.

I understand your argument about the surface for png and bmp being stored in
the same manner in memory, but in practice, there seems to be a little more to
it than that. In particular, there is per pixel and per surface alpha
information, and the documentation seems to say that SDL_BlitSurface uses one
or the other, but not both.

Thanks,
Gary

— Koshmaar wrote:>

Is it possible to fade out a PNG image with SetAlpha? It doesn’t work for
me.
If its not possible, what are some recommended alternatives given rounded,
shadowed images?

Thanks,
Gary

You can’t fade image simply by calling SetAlpha, after that operation you
have to render that image on screen, so that effects will be visible. Also,
clearing background would be useful.

And yes, it’s certainly possible. In video memory, png is stored in the same
way as ie. bmp. Just look at this example:

#include
#include <SDL.h>

SDL_Surface *image;
SDL_Surface *screen;
int alpha = 255;

void Draw()
{
SDL_Rect rect;
rect.y = 30;
rect.x = 30;
SDL_FillRect(screen, 0, 0);
SDL_BlitSurface(image, NULL, screen, &rect);
SDL_SetAlpha(image, SDL_SRCALPHA, alpha);
alpha–;
}

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

int done;

if (SDL_Init (SDL_INIT_VIDEO) < 0)
 {
 return 1;
 }
 
atexit (SDL_Quit);

screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
if (screen == NULL) return 1;

image = SDL_LoadBMP("elf.bmp"); // change this to

IMG_Load(“yoursprite.png”);

done = 0;
while (!done)
{
 SDL_Event event;

 while (SDL_PollEvent (&event))
  {
   switch (event.type)
    {
     case SDL_QUIT:
      done = 1;
     break;
     }
  }
  Draw();
  SDL_Flip(screen);
  SDL_Delay(0);
}

return 0;

}

Koshmaar


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Thanks for your input, Olof.

I don’t see how your algorithm solves the problem. As I understand it, your
algorithm will simply blit the image onto the surface 256 times with a
different per surface alpha level each time. Besides the fact that blitting
the whole image 256 is needless and costly, the per surface alpha will actually
be ignored since SDL_BlitSurface will not take per surface alpha into account
if there is an alpha channel (per pixel alpha info), as show below by the
pseudo code taken from the documentation.

if (source surface has SDL_SRCALPHA set) {
if (source surface has alpha channel (that is, format->Amask != 0))
blit using per-pixel alpha, ignoring any colour key
else {
if (source surface has SDL_SRCCOLORKEY set)
blit using the colour key AND the per-surface alpha value
else
blit using the per-surface alpha value
}
} else {
if (source surface has SDL_SRCCOLORKEY set)
blit using the colour key
else
ordinary opaque rectangular blit
}

— Olof Bjarnason <olof.bjarnason at gmail.com> wrote:> On 8/8/05, G B <@G_B> wrote:

Is it possible to fade out a PNG image with SetAlpha? It doesn’t work for
me.
If its not possible, what are some recommended alternatives given rounded,
shadowed images?

I think I know what you are imagining SDL_SetAlpha doing. :slight_smile:
That is NOT what it is doing! When you use SDL_SetAlpha, you are
simply changing a property of a surface, NOT the pixels in the
surface. In order to alpha-blend (or fade as you call it) the surface,
use SDL_SetAlpha and SDL_BlitSurface in combination.

“Algorithm”:

SDL_Surface* screen = SDL_SetVideoMode(…);
SDL_Surface* P;
for every value i in the range 0…255
SDL_SetAlpha(P, i); // read up on exact syntax
SDL_BlitSurface(P, NULL, screen, NULL);
rof

/Olof

Read these API entries on the SDL-documentation:

  1. SDL_SetAlpha
  2. SDL_BlitSurface

Thanks,
Gary


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Is having a full alpha channel required, or do you just use it for
on/off transparency (ala GIF) ? If all you need is on/off transparency,
you can convert the image to use a color key, and use SDL_SetAlpha in
the normal way.

If you do need the full alpha channel, you need to create your own alpha
mixer. Mixing alpha is pretty easy (or, well, linear mixing is, which
technically isn’t correct, but it’s good enough for this purpose). To
create the fade effect you want, you could do something like this:

// (Init)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
alpha_storage_thingy[index_for_this_pixel] = pixel_alpha_value;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);

// (Fade)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
old_alpha = alpha_storage_thingy[index_for_this_pixel];
pixel_alpha_value = old_alpha * fade_alpha / 255;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
SDL_BlitSurface(image, srcrect, destination, destrect);

The 255 is assuming the alpha is an 8-bit value. Dividing by 256 may be
slightly more efficient as that can use a bit shift in stead of an
actual division, but the result will not be 100% correct – though
again, probably good enough. This should still be true on modern CPUs
(saves some registers, etc), although to tell the truth you probably
won’t notice much difference these days =)

  • Gerry

Ok, that’s along the lines of what I figured I need to do. Thank you for some
actual code! What I don’t understand is why this isn’t already available in
SDL. Don’t many people need to fade out PNGs?

I guess I will want to modify SDL_BlitSurface, or make a similar function
within SDL to accomplish this.

Thanks again!
Gary

— Gerry JJ wrote:> Is having a full alpha channel required, or do you just use it for

on/off transparency (ala GIF) ? If all you need is on/off transparency,
you can convert the image to use a color key, and use SDL_SetAlpha in
the normal way.

If you do need the full alpha channel, you need to create your own alpha
mixer. Mixing alpha is pretty easy (or, well, linear mixing is, which
technically isn’t correct, but it’s good enough for this purpose). To
create the fade effect you want, you could do something like this:

// (Init)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
alpha_storage_thingy[index_for_this_pixel] = pixel_alpha_value;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);

// (Fade)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
old_alpha = alpha_storage_thingy[index_for_this_pixel];
pixel_alpha_value = old_alpha * fade_alpha / 255;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
SDL_BlitSurface(image, srcrect, destination, destrect);

The 255 is assuming the alpha is an 8-bit value. Dividing by 256 may be
slightly more efficient as that can use a bit shift in stead of an
actual division, but the result will not be 100% correct – though
again, probably good enough. This should still be true on modern CPUs
(saves some registers, etc), although to tell the truth you probably
won’t notice much difference these days =)

  • Gerry

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

Ok, that’s along the lines of what I figured I need to do. Thank you for some
actual code! What I don’t understand is why this isn’t already available in
SDL. Don’t many people need to fade out PNGs?

I guess I will want to modify SDL_BlitSurface, or make a similar function
within SDL to accomplish this.
Take my advice: don’t modify SDL_BlitSurface. :slight_smile:

Instead, in your routine for loading PNGs, just do the algorithm I
told you automatically:

SDL_Surface* loadPNG(char* file) {
// load 32 bit surface from png file, P
// convert it to 24 bit surface, E
SDL_FreeSurface§
return E;
}

Do you follow?

/OlofOn 8/9/05, G B wrote:

Thanks again!
Gary

— Gerry JJ wrote:

Is having a full alpha channel required, or do you just use it for
on/off transparency (ala GIF) ? If all you need is on/off transparency,
you can convert the image to use a color key, and use SDL_SetAlpha in
the normal way.

If you do need the full alpha channel, you need to create your own alpha
mixer. Mixing alpha is pretty easy (or, well, linear mixing is, which
technically isn’t correct, but it’s good enough for this purpose). To
create the fade effect you want, you could do something like this:

// (Init)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
alpha_storage_thingy[index_for_this_pixel] = pixel_alpha_value;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);

// (Fade)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
old_alpha = alpha_storage_thingy[index_for_this_pixel];
pixel_alpha_value = old_alpha * fade_alpha / 255;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
SDL_BlitSurface(image, srcrect, destination, destrect);

The 255 is assuming the alpha is an 8-bit value. Dividing by 256 may be
slightly more efficient as that can use a bit shift in stead of an
actual division, but the result will not be 100% correct – though
again, probably good enough. This should still be true on modern CPUs
(saves some registers, etc), although to tell the truth you probably
won’t notice much difference these days =)

  • Gerry

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Olof,
I don’t see how your algorithm would allow me to blit using both per pixel and
per surface alpha, combined. E.g., fade out a PNG image that has per pixel
alpha along its border for shadow effect. What you are telling me is to get
rid of the alpha channel. This is not what I’m trying to do.

I will likely iterate over all pixels and apply a per surface alpha to the per
pixel alpha in my PNG RGBAs in my application. Once I am confident that the
approach works, I might attempt to inspect where in SDL code the algorithm
belongs, and then possibly move it there.
Thanks,
Gary

— Olof Bjarnason <olof.bjarnason at gmail.com> wrote:> On 8/9/05, G B <@G_B> wrote:

Ok, that’s along the lines of what I figured I need to do. Thank you for
some
actual code! What I don’t understand is why this isn’t already available
in
SDL. Don’t many people need to fade out PNGs?

I guess I will want to modify SDL_BlitSurface, or make a similar function
within SDL to accomplish this.
Take my advice: don’t modify SDL_BlitSurface. :slight_smile:

Instead, in your routine for loading PNGs, just do the algorithm I
told you automatically:

SDL_Surface* loadPNG(char* file) {
// load 32 bit surface from png file, P
// convert it to 24 bit surface, E
SDL_FreeSurface§
return E;
}

Do you follow?

/Olof

Thanks again!
Gary

— Gerry JJ wrote:

Is having a full alpha channel required, or do you just use it for
on/off transparency (ala GIF) ? If all you need is on/off transparency,
you can convert the image to use a color key, and use SDL_SetAlpha in
the normal way.

If you do need the full alpha channel, you need to create your own alpha
mixer. Mixing alpha is pretty easy (or, well, linear mixing is, which
technically isn’t correct, but it’s good enough for this purpose). To
create the fade effect you want, you could do something like this:

// (Init)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
alpha_storage_thingy[index_for_this_pixel] = pixel_alpha_value;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);

// (Fade)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
old_alpha = alpha_storage_thingy[index_for_this_pixel];
pixel_alpha_value = old_alpha * fade_alpha / 255;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
SDL_BlitSurface(image, srcrect, destination, destrect);

The 255 is assuming the alpha is an 8-bit value. Dividing by 256 may be
slightly more efficient as that can use a bit shift in stead of an
actual division, but the result will not be 100% correct – though
again, probably good enough. This should still be true on modern CPUs
(saves some registers, etc), although to tell the truth you probably
won’t notice much difference these days =)

  • Gerry

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Start your day with Yahoo! - make it your home page

Take a sample from the original PNG picture, lets call it (R,G,B,A).

Now what does per-pixel-alpha blending mean mathematically? Well it
just means that you display the following pixel onscreen (in the end
everything is RGB triplets - the alpha component is not really visible
if you get my meaning):

display = (AR,AG,AB)

Now, if I understand your fading correctly, you want to multiply this
pixel with another alpha value, call it A’:

fade = A’(AR,AG,AB) = (A’AR,A’AG,A’AB)

… for some A’ in range say 1.0 … 0.0.

Now if you choose to compute A’AR etc. “on-the-fly” (in software with
your own routine) or precompute (AR,AG,AB) (easily done with
SDL_BlitSurface and SDL_ColorKey as I’ve told you earlier) and use SDL
for the last multiplication is up to you but I promise you the second
method is going to beat the first performance-wize by measures. And
it’s easier to code up!

/OlofOn 8/9/05, G B wrote:

Olof,
I don’t see how your algorithm would allow me to blit using both per pixel and
per surface alpha, combined. E.g., fade out a PNG image that has per pixel
alpha along its border for shadow effect. What you are telling me is to get
rid of the alpha channel. This is not what I’m trying to do.

I will likely iterate over all pixels and apply a per surface alpha to the per
pixel alpha in my PNG RGBAs in my application. Once I am confident that the
approach works, I might attempt to inspect where in SDL code the algorithm
belongs, and then possibly move it there.
Thanks,
Gary

— Olof Bjarnason <@Olof_Bjarnason> wrote:

On 8/9/05, G B wrote:

Ok, that’s along the lines of what I figured I need to do. Thank you for
some
actual code! What I don’t understand is why this isn’t already available
in
SDL. Don’t many people need to fade out PNGs?

I guess I will want to modify SDL_BlitSurface, or make a similar function
within SDL to accomplish this.
Take my advice: don’t modify SDL_BlitSurface. :slight_smile:

Instead, in your routine for loading PNGs, just do the algorithm I
told you automatically:

SDL_Surface* loadPNG(char* file) {
// load 32 bit surface from png file, P
// convert it to 24 bit surface, E
SDL_FreeSurface§
return E;
}

Do you follow?

/Olof

Thanks again!
Gary

— Gerry JJ wrote:

Is having a full alpha channel required, or do you just use it for
on/off transparency (ala GIF) ? If all you need is on/off transparency,
you can convert the image to use a color key, and use SDL_SetAlpha in
the normal way.

If you do need the full alpha channel, you need to create your own alpha
mixer. Mixing alpha is pretty easy (or, well, linear mixing is, which
technically isn’t correct, but it’s good enough for this purpose). To
create the fade effect you want, you could do something like this:

// (Init)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
alpha_storage_thingy[index_for_this_pixel] = pixel_alpha_value;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);

// (Fade)
if (SDL_MUSTLOCK(image)) SDL_LockSurface(image);
for each pixel in image {
old_alpha = alpha_storage_thingy[index_for_this_pixel];
pixel_alpha_value = old_alpha * fade_alpha / 255;
}
if (SDL_MUSTLOCK(image)) SDL_UnlockSurface(image);
SDL_BlitSurface(image, srcrect, destination, destrect);

The 255 is assuming the alpha is an 8-bit value. Dividing by 256 may be
slightly more efficient as that can use a bit shift in stead of an
actual division, but the result will not be 100% correct – though
again, probably good enough. This should still be true on modern CPUs
(saves some registers, etc), although to tell the truth you probably
won’t notice much difference these days =)

  • Gerry

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Start your day with Yahoo! - make it your home page
http://www.yahoo.com/r/hs


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl