Fading images in quickly.

aewarnick

Well-known member
Joined
Jan 29, 2003
Messages
1,031
I found information about how to fade images on the net. But it is extremely slow. Here is the code:
IA is an ImageAttributes variable. matrixEl is the float value that is incremented to fade in the image.

C#:
float[][] colorMatrixElements = {
new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
						
new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
						
new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
						
new float[] {0.0f,  0.0f,  0.0f, matrixEl, 0.0f},				
new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}									
};
ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
				
IA.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
	return IA;
The code returns the IA and I use a bitmap graphics object to draw it over and over. This method is extremly slow. Is there a much faster way to fade images in and out?
 
Ive used colormatrix instances to fade images quite a lot, without finding it slow. However, Ive only ever used quite small images and I could believe that large images would be significantly slower. Remember, GDI+ is not hardware accelerated.

One thing you could try is not bothering with all those float values; if you just use the parameterless constructor for ColorMatrix and set its Matrix33 property to the alpha multiplier that will do the same.
 
I got rid of all the float values and just set the Matrix33 property but with the same results.

Do you think I have to use the double buffering method:

this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);

If so, does my painting of the images have to derive from the Paint event? My code to paint is in the mouse up event right now, so it has no link to the paint event at all. But when I put the code there and paint from there I get the same results.

Also, the program I am comparing this with was probably made with C++ or VB. Could C# just be slow when it comes to graphics or is it my code:

I am redrawing the graphics image each time I change the ImageAttributes. Once on the Bitmap graphic and once on the form.

Am I doing it wrong? I must be because even when I draw it on the form without the image in the bitmap graphic and only drawing it on the form and not on the bitmap too, it is still slow. It should be extremely fast because I am using a for loop.
 
Last edited by a moderator:
I figured out how to display the images without flicker.

I did have to make the drawing directly connected with the Paint event.

I noticed that even though there is no flicker when I have big images, the time in between each frame is increased. That makes sense.

However, this does not:

Gpic.DrawImage((Image)Ims[tick], picRec, 0, 0, picRec.Width, picRec.Height, GraphicsUnit.Pixel, IA);

That is when I draw my image on the bitmap in the background before I draw it on the form. I always get a Out of memory error when I keep the ImageAttributes in there (IA). But when I remove them it works fine.

I can use the same exact parameters when I draw the faded picture on the form but for some reason, not on the bitmap graphic.

Can anyone help?
 
I dont know why youd get that error. You never told me if the image youre trying to draw fast is a large one. This is almost definitely why its slower than its C++ counterpart, since its using GDI+.
 
the images that I am drawing are large and small. I found that the problem was with this: (Image)Ims[tick]. Ims is an ArrayList with 2 images, one in index 0 and one in index 1.

For some reason I had to put the images into a regular Image or Bitmap variable for it to work. Would you happen to have any idea why?? It does not make sense to me. I spent about 5 hours playing around before I figured that one out because it does not seem logical.
 
Presumably the images already _are_ in an Image class, I dont understand what youre saying you had to do.
 
Bitmap b=new Bitmap((Image)Ims[tick]);

and use b instead of directly using (Image)Ims[tick];

The only time directly using (Image)Ims[tick]; didnt work was when I added the image attributes to the drawing on the graphic.

I know it does not make sense because the Ims[tick] is an Image. That is why I am confused that I had to do it that way.
 
Back
Top