Your code would be a lot easier to read if you use Select Case insteat of a bunch of If statements
Code:
For i = 1 To aimg.Count - 2
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0 ' No Action
'
Case 1 ' Leave
Stop
'ActualFrame = PreviousFrame + TransparentActualFrame '
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i - 1).ScaleWidth, aimg(i - 1).ScaleHeight, aimg(i - 1).hdc, 0, 0, vbSrcCopy
If fraFrame(i).GCGraphicControl.BackColor <> LSDLogicalScreenDescription.BackColor Then
TransparentBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, aimg(i).ScaleHeight, GetPixel(aimg(i).hdc, 0, 0)
Else
BitBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
Case 2 ' Restore Background
'
Case 3 ' Restore Previous
'
Case Else ' Error
'
End Select
Next i
I disagree with your method for transparency. You may think it works but I believe later you will find that it won't be what you expected.
Last edited by jmsrickland; Aug 24th, 2012 at 06:49 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
Your code would be a lot easier to read if you use Select Case insteat of a bunch of If statements
Code:
For i = 1 To aimg.Count - 2
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0 ' No Action
'
Case 1 ' Leave
Stop
'ActualFrame = PreviousFrame + TransparentActualFrame '
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i - 1).ScaleWidth, aimg(i - 1).ScaleHeight, aimg(i - 1).hdc, 0, 0, vbSrcCopy
If fraFrame(i).GCGraphicControl.BackColor <> LSDLogicalScreenDescription.BackColor Then
TransparentBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, aimg(i).ScaleHeight, GetPixel(aimg(i).hdc, 0, 0)
Else
BitBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
Case 2 ' Restore Background
'
Case 3 ' Restore Previous
'
Case Else ' Error
'
End Select
Next i
I disagree with your method for transparency. You may think it works but I believe later you will find that it won't be what you expected.
thanks for the Case...End Select opinion. why you use the "stop" keyword"?
my objective is detect if the backcolor is or not is transparent. and that hallowen.gif image works 100% on positions and frame correctly
the down.gif image stills show me a problem, because show me the last frame... so the if isn't 100%
thanks for all
(MODERATOR: isn't the 1st time that the text cursor have a strange behavior.... but isn't my fault if your forum detect a spam by this bug)
Your code would be a lot easier to read if you use Select Case insteat of a bunch of If statements
Code:
For i = 1 To aimg.Count - 2
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0 ' No Action
'
Case 1 ' Leave
Stop
'ActualFrame = PreviousFrame + TransparentActualFrame '
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i - 1).ScaleWidth, aimg(i - 1).ScaleHeight, aimg(i - 1).hdc, 0, 0, vbSrcCopy
If fraFrame(i).GCGraphicControl.BackColor <> LSDLogicalScreenDescription.BackColor Then
TransparentBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, aimg(i).ScaleHeight, GetPixel(aimg(i).hdc, 0, 0)
Else
BitBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
Case 2 ' Restore Background
'
Case 3 ' Restore Previous
'
Case Else ' Error
'
End Select
Next i
I disagree with your method for transparency. You may think it works but I believe later you will find that it won't be what you expected.
thanks for the Case...End Select opinion. why you use the "stop" keyword"?
my objective is detect if the backcolor is or not is transparent. and that hallowen.gif image works 100% on positions and frame correctly
the down.gif image stills show me a problem, because show me the last frame... so the if isn't 100%
thanks for all
(MODERATOR: isn't the 1st time that the text cursor have a strange behavior.... but isn't my fault if your forum detect a spam by this bug)
thanks for the Case...End Select opinion. why you use the "stop" keyword"?
my objective is detect if the backcolor is or not is transparent. and that hallowen.gif image works 100% on positions and frame correctly
the down.gif image stills show me a problem, because show me the last frame... so the if isn't 100%
thanks for all
(MODERATOR: isn't the 1st time that the text cursor have a strange behavior.... but isn't my fault if your forum detect a spam by this bug)
I just forgot to take the Stop out. I use it for testing. The backcolor is never transparent. This is a quote from the official GIF specifications:
The Background Color is the color used for those pixels on the screen that are not covered by an image.
The transparent color is in the color table and you should know that each frame may or may not use the Global Color Table. If a frame does not use the Global Color table then it has it's own Local Color Table. You need to get the transparent color from the color table whether it's from the Global or the Local Color Table. Also, each frame may have a different transparent color. In the case of the hallowen.gif the transparent color is red but you are using the upper left corner (aimg(i).hdc, 0, 0) as the transparent color and that is not correct. if you use the method that you are using you will find that it isn't going to come out correctly for other gif images. I'm just trying to help you understand how a GIF format works and just because hallowen.gif looks like you got it 100% correct it isn't; it just turned out that way.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
I just forgot to take the Stop out. I use it for testing. The backcolor is never transparent. This is a quote from the official GIF specifications:
The Background Color is the color used for those pixels on the screen that are not covered by an image.
The transparent color is in the color table and you should know that each frame may or may not use the Global Color Table. If a frame does not use the Global Color table then it has it's own Local Color Table. You need to get the transparent color from the color table whether it's from the Global or the Local Color Table. Also, each frame may have a different transparent color. In the case of the hallowen.gif the transparent color is red but you are using the upper left corner (aimg(i).hdc, 0, 0) as the transparent color and that is not correct. if you use the method that you are using you will find that it isn't going to come out correctly for other gif images. I'm just trying to help you understand how a GIF format works and just because hallowen.gif looks like you got it 100% correct it isn't; it just turned out that way.
"I'm just trying to help you understand how a GIF format works" and build a new sub for read these files
ok... speaking about halloween, i see 2 diferent backcolors. and testing them is the way that i show correctly the frames.... think in these way:
the 2nd frame needs the 1st and the 2nd for be completed... and both backcolor are diferent... it's how i combine them. but for the next frame, i can't use the last frame... that why i use these if... but if you have another sugestion, please tell me
Actually, I don't really understand what you are doing. I know you are experimenting around with GIF files but what I don't know is exactly how or what it is that you want to acompolish.
Question: What is the end results of what you are doing? Are you just making a gif animator?
The TransparentBlt API is for copying a picture to another DC and when it "sees" a transparent color on the original picture it wont copy it to the other but you are using this API to copy the background color at location 0,0 of the original picture and that is what I don't understand why you are doing this.
Do me a favor and post the results of Case 1 but only for the first time. I want to see how it looks.
Code:
For i = 1 To aimg.Count - 2
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0 ' No Action
'
Case 1 ' Leave
'ActualFrame = PreviousFrame + TransparentActualFrame '
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i - 1).ScaleWidth, aimg(i - 1).ScaleHeight, aimg(i - 1).hdc, 0, 0, vbSrcCopy
If fraFrame(i).GCGraphicControl.BackColor <> LSDLogicalScreenDescription.BackColor Then
TransparentBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, aimg(i).ScaleHeight, GetPixel(aimg(i).hdc, 0, 0)
Else
BitBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
Case 2 ' Restore Background
'
Case 3 ' Restore Previous
'
Case Else ' Error
'
End Select
Next i
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
Actually, I don't really understand what you are doing. I know you are experimenting around with GIF files but what I don't know is exactly how or what it is that you want to acompolish.
Question: What is the end results of what you are doing? Are you just making a gif animator?
The TransparentBlt API is for copying a picture to another DC and when it "sees" a transparent color on the original picture it wont copy it to the other but you are using this API to copy the background color at location 0,0 of the original picture and that is what I don't understand why you are doing this.
Do me a favor and post the results of Case 1 but only for the first time. I want to see how it looks.
Code:
For i = 1 To aimg.Count - 2
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0 ' No Action
'
Case 1 ' Leave
'ActualFrame = PreviousFrame + TransparentActualFrame '
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i - 1).ScaleWidth, aimg(i - 1).ScaleHeight, aimg(i - 1).hdc, 0, 0, vbSrcCopy
If fraFrame(i).GCGraphicControl.BackColor <> LSDLogicalScreenDescription.BackColor Then
TransparentBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, aimg(i).ScaleHeight, GetPixel(aimg(i).hdc, 0, 0)
Else
BitBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
Case 2 ' Restore Background
'
Case 3 ' Restore Previous
'
Case Else ' Error
'
End Select
Next i
what i'm doing is just a gif animator class\module for my 2D Sprite control(i invented)
but for these i want just draw the frame completed, that's why i need understand more about if theres a transparent backcolor and the methods values
There is no transparent backcolor on any gif. I already told you that. It's a back color and not a transparent color.
If you don't post the results that I asked for I can't help you with this because I need to show you something
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
There is no transparent backcolor on any gif. I already told you that. It's a back color and not a transparent color.
If you don't post the results that I asked for I can't help you with this because I need to show you something
i have send you a mail with an image that show you how the frames must be showed... and i show you when the previous image is used or not
thanks for all
OK, I looked at the frames you sent me and I can see how they are coming out correctly but as I have said before this may not work in all cases. In this case, using the halloween gif it works because you are using the upper left corner pixel (0,0) of the picturebox as the background color (I thought you were using the background color of the image) and using that as the transparent color. OK, in this case you get away with it but what are you going to do when 0,0 is not the background color of the picturebox? Suppose the upper left corner pixel is part of the image and not the background color? It won't work! What you need to do is to make the background color of the picturebox the same as the transparent color of the gif frame image. That's what I have been trying to tell you; you need to use the image transparent color so there will be no guess work on your part otherwise you may get away with this many times but you will find out that it simply will not work for all gif images. You seem to be creating ways to make it work for your project rather than follow the rules of gif file handling which is OK if that is what you want to do.
Also I still do not understand why you are using pictureboxes when the Image controls already take care of the transparent color for you and you can overlay Image controls because they are themselves transparent so you don't need the TransparentBlt.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
OK, I looked at the frames you sent me and I can see how they are coming out correctly but as I have said before this may not work in all cases. In this case, using the halloween gif it works because you are using the upper left corner pixel (0,0) of the picturebox as the background color (I thought you were using the background color of the image) and using that as the transparent color. OK, in this case you get away with it but what are you going to do when 0,0 is not the background color of the picturebox? Suppose the upper left corner pixel is part of the image and not the background color? It won't work! What you need to do is to make the background color of the picturebox the same as the transparent color of the gif frame image. That's what I have been trying to tell you; you need to use the image transparent color so there will be no guess work on your part otherwise you may get away with this many times but you will find out that it simply will not work for all gif images. You seem to be creating ways to make it work for your project rather than follow the rules of gif file handling which is OK if that is what you want to do.
Also I still do not understand why you are using pictureboxes when the Image controls already take care of the transparent color for you and you can overlay Image controls because they are themselves transparent so you don't need the TransparentBlt.
so you are having forum problems too
how you delete that post?
then i just use Transparent Color when Transparent Flag is diferent of '0', right?
Yes I am having Forum problems too. I wound up posting three times. To delete extra posts you click on Edit Post. Then look where it says Delete and click on that.
Here's what you need to make sure of. The background color of the picturebox cannot be a color that is in the gif image otherwise you will wind up making part of the image invisible that should not be invisible. To avoid this you should use the transparent color of the frame as the background color of your picturebox and this will guarantee that you don't make pixels transparent that are not supposed to be transparent. Also, 0,0 may not always be the background; it could be part of the image itself so that would be very bad if you used 0,0 and it is also a color in the image.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
Yes I am having Forum problems too. I wound up posting three times. To delete extra posts you click on Edit Post. Then look where it says Delete and click on that.
Here's what you need to make sure of. The background color of the picturebox cannot be a color that is in the gif image otherwise you will wind up making part of the image invisible that should not be invisible. To avoid this you should use the transparent color of the frame as the background color of your picturebox and this will guarantee that you don't make pixels transparent that are not supposed to be transparent. Also, 0,0 may not always be the background; it could be part of the image itself so that would be very bad if you used 0,0 and it is also a color in the image.
now the problem is the color
but when i change the picturebox backcolor, the problem is resolved
the halloween.gif works 100% fine.. but the down.gif isn't because the method value is 3
don't be mad with me and explain, again, the method 2 and 3, please
thanks
"Also I still do not understand why you are using pictureboxes when the Image controls already take care of the transparent color for you and you can overlay Image controls because they are themselves transparent so you don't need the TransparentBlt."
in these case i don't want use the image, speaking on transparency... why, because i want put the complete frame in 1 image
if use it in your way, must show some imagesboxes and hidde others(i belive that it's more complicated).... my objective it's show the frame complete on a single image... in same picturebox
"Also I still do not understand why you are using pictureboxes when the Image controls already take care of the transparent color for you and you can overlay Image controls because they are themselves transparent so you don't need the TransparentBlt."
in these case i don't want use the image, speaking on transparency... why, because i want put the complete frame in 1 image
if use it in your way, must show some imagesboxes and hidde others(i belive that it's more complicated).... my objective it's show the frame complete on a single image... in same picturebox
OK, I understand what your purpose is - it's OK to use pictureboxes and then use the TransparentBLt API which will give you your desired results. Now the next thing is to use the pictureboxes correctly and use the TransparentBLt correctly.
So, let's take this one step at a time starting with the halloween gif.
1) All frames have 1 or Leave as the disposal method. So, you leave each frame as is. You
do not need to do anything with them - just leave them alone - believe me this is the correct
way to do it. You simply copy one frame onto the 1st frame and that is all you have to do
2) Before you load a temp.gif into a picturebox make the picturebox backcolor the same as the
transparent color for that frame then load the temp.gif into the picturebox. The transparent color
is RGB(254, 1, 2) or 131582 or &H000201FE&. Later I will show you how to get the transparent color but for now just use the value I posted above.
3) On your TransparentBlt change the last parameter from GetPixel(aimg(i).hdc, 0, 0) to aimg(i).BackColor
You do not need the GetPixel API.
Code:
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0 ' No Action
'
Case 1 ' Leave
'
' This assumes that you have followed the above steps 1, 2 , and 3
'
' Leave the 1st picturebox as is then take the second picturebox and do this
'
'ActualFrame = PreviousFrame + TransparentActualFrame '
' I don't know what below does so I will leave it alone
BitBlt aImg(aImg.Count - 1).hdc, 0, 0, aImg(i - 1).ScaleWidth, aImg(i - 1).ScaleHeight, aImg(i - 1).hdc, 0, 0, vbSrcCopy
' You dont need the If statement - just use TransparentBlt for everything
'Not Needed--->If fraFrame(i).GCGraphicControl.BackColor <> LSDLogicalScreenDescription.BackColor Then
TransparentBlt aImg(aImg.Count - 1).hdc, _
fraFrame(i).IDImageDescription.FrameLeft, _
fraFrame(i).IDImageDescription.FrameTop, _
aImg(i).ScaleWidth, aImg(i).ScaleHeight, aImg(i).hdc, _
0, 0, _
aImg(i).ScaleWidth, aImg(i).ScaleHeight, _
aImg(i).BackColor
'Not Needed--->Else
'Not Needed---> BitBlt aImg(aImg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aImg(i).ScaleWidth, aImg(i).ScaleHeight, aImg(i).hdc, 0, 0, vbSrcCopy
'Not Needed--->End If
aImg(i).Picture = aImg(aImg.Count - 1).Image
aImg(aImg.Count - 1).Cls
'
'
'
End Select
To simplify what I am saying take a look at the following code. I use Picture1(1) as the first picture which is the closed door. Picture1(2) is the second picture that says Ding Dong. I hard coded the X and Y of picture1(1) to be the same as the Picture1(2) offset just for this example. You do the same thing with the other frames always leaving each frame as is - just copy them like below. Note that I have already made the Picture1(2).BackColor = TransparentColor which is RGB(254, 1, 2) or 131582 or &H000201FE& however one you want to use.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
NOTE: I forgot to mention. If the frame does not have a Transparent color then you use the Global BackColor or any color that is not part of the image itself for the last parameter of the TransparentBLt API.
I attach example of what I am talking about - run it and just click on each button one at a time to see the results
Last edited by jmsrickland; Aug 25th, 2012 at 05:11 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
OK, I understand what your purpose is - it's OK to use pictureboxes and then use the TransparentBLt API which will give you your desired results. Now the next thing is to use the pictureboxes correctly and use the TransparentBLt correctly.
So, let's take this one step at a time starting with the halloween gif.
1) All frames have 1 or Leave as the disposal method. So, you leave each frame as is. You
do not need to do anything with them - just leave them alone - believe me this is the correct
way to do it. You simply copy one frame onto the 1st frame and that is all you have to do
2) Before you load a temp.gif into a picturebox make the picturebox backcolor the same as the
transparent color for that frame then load the temp.gif into the picturebox. The transparent color
is RGB(254, 1, 2) or 131582 or &H000201FE&. Later I will show you how to get the transparent color but for now just use the value I posted above.
3) On your TransparentBlt change the last parameter from GetPixel(aimg(i).hdc, 0, 0) to aimg(i).BackColor
You do not need the GetPixel API.
Code:
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0 ' No Action
'
Case 1 ' Leave
'
' This assumes that you have followed the above steps 1, 2 , and 3
'
' Leave the 1st picturebox as is then take the second picturebox and do this
'
'ActualFrame = PreviousFrame + TransparentActualFrame '
' I don't know what below does so I will leave it alone
BitBlt aImg(aImg.Count - 1).hdc, 0, 0, aImg(i - 1).ScaleWidth, aImg(i - 1).ScaleHeight, aImg(i - 1).hdc, 0, 0, vbSrcCopy
' You dont need the If statement - just use TransparentBlt for everything
'Not Needed--->If fraFrame(i).GCGraphicControl.BackColor <> LSDLogicalScreenDescription.BackColor Then
TransparentBlt aImg(aImg.Count - 1).hdc, _
fraFrame(i).IDImageDescription.FrameLeft, _
fraFrame(i).IDImageDescription.FrameTop, _
aImg(i).ScaleWidth, aImg(i).ScaleHeight, aImg(i).hdc, _
0, 0, _
aImg(i).ScaleWidth, aImg(i).ScaleHeight, _
aImg(i).BackColor
'Not Needed--->Else
'Not Needed---> BitBlt aImg(aImg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aImg(i).ScaleWidth, aImg(i).ScaleHeight, aImg(i).hdc, 0, 0, vbSrcCopy
'Not Needed--->End If
aImg(i).Picture = aImg(aImg.Count - 1).Image
aImg(aImg.Count - 1).Cls
'
'
'
End Select
To simplify what I am saying take a look at the following code. I use Picture1(1) as the first picture which is the closed door. Picture1(2) is the second picture that says Ding Dong. I hard coded the X and Y of picture1(1) to be the same as the Picture1(2) offset just for this example. You do the same thing with the other frames always leaving each frame as is - just copy them like below. Note that I have already made the Picture1(2).BackColor = TransparentColor which is RGB(254, 1, 2) or 131582 or &H000201FE& however one you want to use.
BitBlt aImg(aImg.Count - 1).hdc, 0, 0, aImg(i - 1).ScaleWidth, aImg(i - 1).ScaleHeight, aImg(i - 1).hdc, 0, 0, vbSrcCopy
it's just for copy the previous image to the new picturebox. then i put the transparent actual image
it's working fine... thanks.
but can you explain to me, again, the methods values... please?
i have a question: if these image have, always, the '0' disposal, why i can't see the image correctly(because i can't nothing down of fire( sorry i don't know some terms)?
(i have anexed an image)
Please send your project with the fire gif so I can test your problem. I can't answer your question as you ask it since I have no way of knowing what or how you are dealing with this situation
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
Please send your project with the fire gif so I can test your problem. I can't answer your question as you ask it since I have no way of knowing what or how you are dealing with this situation
heres the entire project
errors that i see in 2 images:
1 -halloween34.gif.... i can't see entire image;
2-halloween31.gif... the last frame is strange.
OK, I downloaded your project and I am working on it to see why those gifs are not coming out correctly. I was a little surprised when I looked at your code as I was under the impression that you were using the TransparentsBlt API to do your animation but it doesn't appear like that. I see you are still making the frames visible and invisible in the Timer Sub and didn't you tell me that the reason you wanted to use TransparentBLt was to avoid that?
speaking on transparency... why, because i want put the complete frame in 1 image
if use it in your way, must show some imagesboxes and hidde others(i belive that it's more complicated).
but your code isn't doing what you say above
Code:
Private Sub Timer1_Timer()
Image1(FrameCount).Visible = False
If FrameCount < TotalFrames Then
Image1(FrameCount).Visible = False
FrameCount = FrameCount + 1
Image1(FrameCount).Visible = True
Timer1.Interval = CLng(Image1(FrameCount).Tag)
Else
FrameCount = 0
'For i = 1 To Image1.Count - 1
Image1(tota).Visible = False
'Next i
Image1(FrameCount).Visible = True
Timer1.Interval = Image1(FrameCount).Tag
End If
i = FrameCount
End Sub
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
OK, I downloaded your project and I am working on it to see why those gifs are not coming out correctly. I was a little surprised when I looked at your code as I was under the impression that you were using the TransparentsBlt API to do your animation but it doesn't appear like that. I see you are still making the frames visible and invisible in the Timer Sub and didn't you tell me that the reason you wanted to use TransparentBLt was to avoid that?
speaking on transparency... why, because i want put the complete frame in 1 image
if use it in your way, must show some imagesboxes and hidde others(i belive that it's more complicated).
but your code isn't doing what you say above
Code:
Private Sub Timer1_Timer()
Image1(FrameCount).Visible = False
If FrameCount < TotalFrames Then
Image1(FrameCount).Visible = False
FrameCount = FrameCount + 1
Image1(FrameCount).Visible = True
Timer1.Interval = CLng(Image1(FrameCount).Tag)
Else
FrameCount = 0
'For i = 1 To Image1.Count - 1
Image1(tota).Visible = False
'Next i
Image1(FrameCount).Visible = True
Timer1.Interval = Image1(FrameCount).Tag
End If
i = FrameCount
End Sub
sorry my english
that code only do these: hide the previous control and shows the otherone(only show us 1 control). but 1 control have 1 complete frame(with disposal method)
think on that big image that i give you about halloween... you see 6 frames.... but the 2nd is completed on control and don't depends on previous control
Do me a favor and download the attached zip I want you to see how I do it using TransparentAPI by just putting one frame on top of the other. This is not a gif animation program it is just a demonstrating of the 6 frames where I put one on top of the other. Run the project and click on each button one at a time and look at the results on the first picture. This is what I thought you were doing similar to this but using your own code. Notice how the transparent color is red which is the correct transparent color for this gif file. You are not using the transparent color as the backColor for the picture but you are using the index to the transparent color which wont work in other cases - you are just lucky on this one that the index value was 0 which gives you a black background color which worked for your halloween picture becaue it is on a black background but that is not what you want, you want the real transparent color which is red like I have.
I think your method in the aniMod is a little confusing although I see what you are doing I think it's more than you need to do. My demo illustrates how it should be done for the halloween gif because it is emulating the Leave method exactly. If you were to put my demo in a timing loop using the correct timing values for each frame you will see how simple the Leave method really is.
Last edited by jmsrickland; Aug 26th, 2012 at 02:05 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
Do me a favor and download the attached zip I want you to see how I do it using TransparentAPI by just putting one frame on top of the other. This is not a gif animation program it is just a demonstrating of the 6 frames where I put one on top of the other. Run the project and click on each button one at a time and look at the results on the first picture. This is what I thought you were doing similar to this but using your own code. Notice how the transparent color is red which is the correct transparent color for this gif file. You are not using the transparent color as the backColor for the picture but you are using the index to the transparent color which wont work in other cases - you are just lucky on this one that the index value was 0 which gives you a black background color which worked for your halloween picture becaue it is on a black background but that is not what you want, you want the real transparent color which is red like I have.
I think your method in the aniMod is a little confusing although I see what you are doing I think it's more than you need to do. My demo illustrates how it should be done for the halloween gif because it is emulating the Leave method exactly. If you were to put my demo in a timing loop using the correct timing values for each frame you will see how simple the Leave method really is.
is more or less that i did
1 - i put all frames on picturebox array;
2 - now i compare the disposal methods and draw them correctly on picturebox array;
3 - now the timer just need hide or show the right picturebox... and the frame is showed normaly.
i understand the bakcolor is red, my problem is: what i didn't did right?
i did:
Code:
' ADDED BY JMS
fraFrame(i).GCGraphicControl.TransparentFlag = (PackedField And 1)
fraFrame(i).GCGraphicControl.Delay = (Asc(Mid(strFrame, 5, 1)) + Asc(Mid(strFrame, 6, 1)) * 256) * 10
' NOTE This value is meaningless if TransparentFlag is 0
fraFrame(i).GCGraphicControl.TransparentColor = Asc(Mid$(strFrame, 7, 1))
Last edited by joaquim; Aug 26th, 2012 at 02:54 PM.
1) determine if the frame uses the Global Color Table or the Local Color Table.
2) from which ever color table is used, multiple the Index by 3 and add that answer to the base of the color table.
3) extract out 3-bytes from the table. 1st byte = R, 2nd byte = G, and 3rd byte = B or (RGB)
Now these three bytes are in character format so they will need to be converted to ascii and converted to Long variable
4) if there is a Global Color Table it starts here at position 14 in the file:
5) if there is a Local Color Table (per frame) then you use it (per frame) instead of the Global Color Table.
6) if there is a Local Color Table it starts here (example, Left.gif uses Local Color Table):
Code:
1st Color --+ +--2nd Color +-- Last Color
| | |
+--+----+----+----+----+-+-+-+-+-+-+-+-----+-+-+-+
|2C| | | | | |R|G|B|R|G|B|.....|R|G|B|
+--+----+----+----+----+-+-+-+-+-+-+-+-----+-+-+-+
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
1) determine if the frame uses the Global Color Table or the Local Color Table.
2) from which ever color table is used, multiple the Index by 3 and add that answer to the base of the color table.
3) extract out 3-bytes from the table. 1st byte = R, 2nd byte = G, and 3rd byte = B or (RGB)
Now these three bytes are in character format so they will need to be converted to ascii and converted to Long variable
4) if there is a Global Color Table it starts here at position 14 in the file:
5) if there is a Local Color Table (per frame) then you use it (per frame) instead of the Global Color Table.
6) if there is a Local Color Table it starts here (example, Left.gif uses Local Color Table):
Code:
1st Color --+ +--2nd Color +-- Last Color
| | |
+--+----+----+----+----+-+-+-+-+-+-+-+-----+-+-+-+
|2C| | | | | |R|G|B|R|G|B|.....|R|G|B|
+--+----+----+----+----+-+-+-+-+-+-+-+-----+-+-+-+
it's very confuse
i belive that theres another way...
do me a favor and change these 2 lines:
Code:
'Now change the backcolor
'aimg(i).BackColor = fraFrame(i).GCGraphicControl.TransparentColorIndex (now it's a comment)
and:
Code:
'Control the Disposal codes
If aimg.Count > 1000 Then
now i have 1 question: why the 2nd frame have white backcolor(still on Halloween46.gif) instead red?
heres the entire project;)
errors that i see in 2 images:
1 -halloween34.gif.... i can't see entire image;
2-halloween31.gif... the last frame is strange.
Halloween34 has all frames as 0 (Undefined) and in your code where you process the disposal values I see that Case 0 is empty so in essence you do nothing but retain the pictures in their picture boxes. Now in your Timer code you make invisible each preceeding frame and simply display each frame as though it was the only frame to show and that is incorrect because each frame must be overlayed on the preceeding frame. It worked with Halloween46 because you actually processed each frame in Case 1. Now you have each frame that holds the results of the previous frame so you got away with it in your Timer code and that is why you don't see the entire image
Also, Halloween34 has no transparent color and you need to take that into account.
Not only is the last frame strange some of the others are not correct either. There is nothing in your code to process halloween31. This gif has disposal of 2 (RestoreBackground) but your code only handles disposal 1 (Leave) and that isn't going to work for this gif. What did you expect?
See may attached image - you see that I have it correctly displayed.
Originally Posted by joaquim
is more or less that i did;)
1 - i put all frames on picturebox array;
2 - now i compare the disposal methods and draw them correctly on picturebox array;
3 - now the timer just need hide or show the right picturebox... and the frame is showed normaly.
i understand the bakcolor is red, my problem is: what i didn't did right?
i did:
I guess there is no reason for me to comment on this as I can see you are determined to do it this way. I am not 100% positive that it won't work in all cases but only time will tell. Even if it does work it looks like a lot of extra coding and it is not as simple as to just display each frame onto a canvas one by one then you don't need that extra code in your Timer Sub
Originally Posted by joaquim
it's very confuse:(
i belive that theres another way...
do me a favor and change these 2 lines:
Code:
'Now change the backcolor
'aimg(i).BackColor = fraFrame(i).GCGraphicControl.TransparentColorIndex (now it's a comment)
and:
Code:
'Control the Disposal codes
If aimg.Count > 1000 Then
now i have 1 question: why the 2nd frame have white backcolor(still on Halloween46.gif) instead red?
It isn't really that confusing and you are going to have to follow the rules of gif file processing. You need to test for Global Color Table and Local Color Table and use the one that is appropiate for the frame you are processing - there is no other way. Also, the background color you are using is not the background color of the image; it is the index to the background color and you need to extract it from the color table as I described for you in my previous post.
I do not know what you want me to do with your suggested change above. You want me to comment out that one statement and add the If aimg.Count > 1000 Then statement but then what? You give no code for the If clause.
I can only give you advise and help on your project but only in the sense of the correct way of doing it and not the code you write to process the disposal values because I do not think that method is the correct way of displaying gif images.
Gif anaimation is designed to first have a canvas to receive the frames. A canvas can be a Picturebox, a RTB, a WebBrowser page, or any surface that can hold an image. The area used for the canvas is made the size of the Width and Height of the values in
Only the canvas is this size. Then you render each frame image onto this canvas then do as the disposal method says; if it's Leave then leave the image as is; if it's RestoreBackground then simply restore the background color of the canvas, etc. The background color of the canvas is:
1) If image is to be rendered with transparency then make the color of the canvas any color you want except the BackColor of the GIF
2) If the image is to be rendered without transparency the make the color of the canvas the same as the BackColor specified in the GIF specifications.
Also, you need to test each frame to see if it has a transparent color or not. If it does then you use TransparentBlt and if it doesn't you use BitBlt to render the image onto the canvas.
Last edited by jmsrickland; Aug 28th, 2012 at 12:03 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
still having problems for login on forum
i change the code:
Code:
'Special thanks to jmsrickland from www.VBForums.com
Option Explicit
Option Base 0
Private Declare Function TransparentBlt Lib "msimg32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Enum GifType
GIF87A = 0
GIF89A = 1
End Enum
Private Type LogicalScreenDescriptor
GifWidth As Long
GifHeight As Long
GlobalColorSize As Long
SortFlag As Long
ColorResolution As Long
GlobalColorFlag As Long
BackgroundColor As Long
PixelRadio As Long
End Type
Private Type GraphicControl
Disposal As Long
Delay As Long
TransparentColorIndex As Long
UserInput As Long
TransparentFlag As Long
End Type
Private Type ImageDescription
FrameLeft As Long
FrameTop As Long
FrameWidth As Long
FrameHeight As Long
End Type
Private Type Frame
GCGraphicControl As GraphicControl
IDImageDescription As ImageDescription
End Type
Dim fraFrame() As Frame
Public Function LoadGifFile(strFileName As String, aimg As Variant) As Long
Dim GifHeader As GifType
Dim strLogicalScreenDescription As String
Dim LSDLogicalScreenDescription As LogicalScreenDescriptor
'Dim GCGraficControl As GraphicControl
'Dim IDImageDescription As ImageDescription
Dim strGifHeader As String
Dim strFrame As String
Dim fNum As Integer
Dim FileBuffer As String
Dim PictureBuffer As String
Dim PackedField As String
Dim FirstFrame As Long
Dim FrameEnds As Long
Dim ActualFrame As Long
Dim i As Integer
'On Error Resume Next
'Test if the file exists
If Dir$(strFileName) = "" Or strFileName = "" Then
MsgBox "File " & strFileName & " not found", vbCritical
Exit Function
End If
'Put all file info to a variable
fNum = FreeFile
Open strFileName For Binary Access Read As fNum
FileBuffer = String(LOF(fNum), Chr(0))
Get #fNum, , FileBuffer
Close fNum
'FileBuffer = Trim(FileBuffer)
'unload all pictureboxes\images
For i = 1 To aimg.Count - 1
Unload aimg(i)
Next i
'Gif Header
strGifHeader = Left$(FileBuffer, 6)
If strGifHeader = "GIF87a" Then
GifHeader = GIF87A
ElseIf strGifHeader = "GIF89a" Then
GifHeader = GIF89A
End If
'Test if the Gif is animated or not
FirstFrame = InStr(13, FileBuffer, Chr(33) & Chr(249))
ActualFrame = FirstFrame
'if the image isn't animated, then just draw it;)
If InStr(FirstFrame + 2, FileBuffer, Chr(33) & Chr(249)) = 0 Then
aimg(0).Picture = LoadPicture(strFileName)
aimg(0).Tag = 0
Exit Function
End If
'Logical Screen Description
strLogicalScreenDescription = Mid$(FileBuffer, 7, 7)
LSDLogicalScreenDescription.GifWidth = Asc(Mid(strLogicalScreenDescription, 1, 1)) + Asc(Mid(strLogicalScreenDescription, 2, 1)) * 256
LSDLogicalScreenDescription.GifHeight = Asc(Mid(strLogicalScreenDescription, 3, 1)) + Asc(Mid(strLogicalScreenDescription, 4, 1)) * 256
PackedField = Asc(Mid$(strLogicalScreenDescription, 5, 1))
LSDLogicalScreenDescription.GlobalColorFlag = (PackedField And 128) / 2 ^ 7
LSDLogicalScreenDescription.ColorResolution = (PackedField And 112) / 2 ^ 4
LSDLogicalScreenDescription.SortFlag = (PackedField And 8) / 2 ^ 3
' NOTE - This value is meanless if GlobalColorFlag is 0
LSDLogicalScreenDescription.GlobalColorSize = PackedField And 7
LSDLogicalScreenDescription.GlobalColorSize = 3 * (2 ^ (LSDLogicalScreenDescription.GlobalColorSize + 1))
LSDLogicalScreenDescription.BackgroundColor = Asc(Mid$(strLogicalScreenDescription, 6, 1))
LSDLogicalScreenDescription.PixelRadio = Asc(Mid$(strLogicalScreenDescription, 7, 1))
'image count
i = 0
ReDim Preserve fraFrame(i)
Do
'get frame string
If InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249)) <> 0 Then
FrameEnds = InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249)) - 2
Else
FrameEnds = InStr(ActualFrame + 2, FileBuffer, Chr(59)) - 1
End If
strFrame = Mid$(FileBuffer, ActualFrame, Len(FileBuffer) - FirstFrame)
'Get Grafic Control
PackedField = Asc(Mid$(strFrame, 4, 1))
fraFrame(i).GCGraphicControl.Disposal = (PackedField And 12) / 2 ^ 2
' ADDED BY JMS
fraFrame(i).GCGraphicControl.UserInput = (PackedField And 2) / 2 ^ 1
' ADDED BY JMS
fraFrame(i).GCGraphicControl.TransparentFlag = (PackedField And 1)
fraFrame(i).GCGraphicControl.Delay = (Asc(Mid(strFrame, 5, 1)) + Asc(Mid(strFrame, 6, 1)) * 256) * 10
fraFrame(i).GCGraphicControl.TransparentColorIndex = Asc(Mid$(strFrame, 7, 1))
'Get Image Description
fraFrame(i).IDImageDescription.FrameLeft = Asc(Mid(strFrame, 10, 1)) + Asc(Mid(strFrame, 11, 1)) * 256
fraFrame(i).IDImageDescription.FrameTop = Asc(Mid(strFrame, 12, 1)) + Asc(Mid(strFrame, 13, 1)) * 256
fraFrame(i).IDImageDescription.FrameWidth = Asc(Mid(strFrame, 14, 1)) + Asc(Mid(strFrame, 15, 1)) * 256
fraFrame(i).IDImageDescription.FrameHeight = Asc(Mid(strFrame, 16, 1)) + Asc(Mid(strFrame, 17, 1)) * 256
'If the image array don't exist then create\load it
If i > 0 Then
Load aimg(i)
End If
'create the image temp
fNum = FreeFile
Open "temp.gif" For Binary As fNum
PictureBuffer = Mid$(FileBuffer, 1, FirstFrame - 1) & Mid$(FileBuffer, ActualFrame, FrameEnds) & Chr(59) '3B
Put #fNum, 1, PictureBuffer
Close fNum
'Now change the backcolor
aimg(i).BackColor = fraFrame(i).GCGraphicControl.TransparentColorIndex
'now load the image
aimg(i).Picture = LoadPicture("temp.gif")
'change the properties
aimg(i).Tag = fraFrame(i).GCGraphicControl.Delay
'test if theres another image
If InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249)) = 0 Then
Exit Do
Else
ActualFrame = InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249))
i = i + 1
If i > 0 Then ReDim Preserve fraFrame(i)
End If
Loop
'now we can delete the temp file
Kill "temp.gif"
LoadGifFile = i + 1
'Control the Disposal codes
If aimg.Count > 1 Then
Load aimg(aimg.Count)
For i = 1 To aimg.Count - 2
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0, 1 ' Leave
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i - 1).ScaleWidth, aimg(i - 1).ScaleHeight, aimg(i - 1).hdc, 0, 0, vbSrcCopy
If fraFrame(i).GCGraphicControl.TransparentFlag <> 0 Then
TransparentBlt aimg(aimg.Count - 1).hdc, _
fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, _
aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, _
aimg(i).ScaleHeight, fraFrame(i).GCGraphicControl.TransparentColorIndex
Else
BitBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
Case 3
End Select
Debug.Print fraFrame(i).GCGraphicControl.Disposal
Next i
Unload aimg(aimg.Count - 1)
End If
End Function
- now i can see that little fire image normaly
- the last frame, on the "vampire bed", i can't see it... but i understand that it's the backcolor\transparency problems;
You have GCGraphicControl.Delay defined as a LOng variable so you shouldn't get an overflow. I have it defined as an Integer variable and I do not get overflow. What image gives you the overflow on the .Delay.
Also, I see that you still are not processing RestoreBackground since you have no Case 2 in your code. If you don't do this you are never going to get your images to animate correctly.
What image gives you an infinite loop?
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
You have GCGraphicControl.Delay defined as a LOng variable so you shouldn't get an overflow. I have it defined as an Integer variable and I do not get overflow. What image gives you the overflow on the .Delay.
Also, I see that you still are not processing RestoreBackground since you have no Case 2 in your code. If you don't do this you are never going to get your images to animate correctly.
What image gives you an infinite loop?
heres how i correct the overflow:
Code:
fraFrame(i).GCGraphicControl.Delay = (Asc(Mid(strFrame, 5, 1)) + Asc(Mid(strFrame, 6, 1)) * 256) * 10
If fraFrame(i).GCGraphicControl.Delay > 276520 Or fraFrame(i).GCGraphicControl.Delay = 0 Or fraFrame(i).GCGraphicControl.Delay = "" Then fraFrame(i).GCGraphicControl.Delay = fraFrame(0).GCGraphicControl.Delay
why that const and 0 and ""??? because it's what i get.
can you explain to me the case 2 and 3(again)?
- the brucekik.gif gives me the infinite loop;
- the T-rex.gif give me that const values... overflow errors.
Take X and multiply it by 3 and add the results to the base of the appropriate color table (Global or Local)
whichever one is to be used. Local Color Table has power over Global Color Table
Extract out the 3-bytes at that offset into the color table and convert each byte to Ascii. This gives you
the R, G, B values of the background color. This is what you use; not the index that you are using.
BTW: use this same method for the transparent color.
2) if transparency in image then the background color of the canvas can be
any color that is not
a) the transparent color or
b) the background color of the image
Case 3
RestorePrevious means to restore the last image that was not disposed. Usually this mean the last image that had a disposal of 0 or 1.
Last edited by jmsrickland; Aug 28th, 2012 at 06:58 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
Do not avoid errors. If you do then you will find that your animation is going to come out crap and you are not going to know why. You need the errors to tell you what the problem is and then try to code for those circumstances.
Keep this in mind, GIF files are made by many people and companies. They do not always follow the rules and sometimes they even screw up the format because they do not understand what they are supposed to do. There is also the possibility that your code is not correct or complete to handle all GIF files. Only trial and error will get you there.
T-Rex has all frames set to 0 Delay except frame 6 which has an error in the file format which is what causes your value of 27652 then you multiply that by 10 to get 276520 . Rule of thumb: If Delay is 0 or it is greater than 1000 then make the Delay for 10 or 100 whichever you think is best (then times your 10 if that is what you like). T-Rex also has all frames set to RestoreBackground. I told you how to handle this method.
Also, it appears that T-Rex was made by an unregistered copy of Gif Construction Set by someone at Alchemy Mindworks Inc by an amature or it wasn't put together correctly.
Brucekik has two frames, both set to Undefined (which you treat as though it was Leave) and it's Delay is 20 for both frames.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
Do not avoid errors. If you do then you will find that your animation is going to come out crap and you are not going to know why. You need the errors to tell you what the problem is and then try to code for those circumstances.
Keep this in mind, GIF files are made by many people and companies. They do not always follow the rules and sometimes they even screw up the format because they do not understand what they are supposed to do. There is also the possibility that your code is not correct or complete to handle all GIF files. Only trial and error will get you there.
T-Rex has all frames set to 0 Delay except frame 6 which has an error in the file format which is what causes your value of 27652 then you multiply that by 10 to get 276520 . Rule of thumb: If Delay is 0 or it is greater than 1000 then make the Delay for 10 or 100 whichever you think is best (then times your 10 if that is what you like). T-Rex also has all frames set to RestoreBackground. I told you how to handle this method.
Also, it appears that T-Rex was made by an unregistered copy of Gif Construction Set by someone at Alchemy Mindworks Inc by an amature or it wasn't put together correctly.
Brucekik has two frames, both set to Undefined (which you treat as though it was Leave) and it's Delay is 20 for both frames.
now i can see the t-rex animation with that 'if'.... but like you said, my transparency code isn't 100%
with brucelikik.gif: sorry, but seems that the program enters in infinite loop... but i will test it and i will tell you more.
thanks for all my friend
with brucelikik.gif: sorry, but seems that the program enters in infinite loop
It isn't the gif; it's your code that isn't capturing the image correctly. I used your code with that gif and it freezes up trying to load the picture but when I use my code it works perfectly.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
with brucelikik.gif: sorry, but seems that the program enters in infinite loop
It isn't the gif; it's your code that isn't capturing the image correctly. I used your code with that gif and it freezes up trying to load the picture but when I use my code it works perfectly.
we know that Chr(33) & Chr(249) it's the frame start unless you use a diferent way
we know that Chr(33) & Chr(249) it's the frame start unless you use a diferent way
I use Chr(33) & Chr(249) & Chr(4) because that guarantees the beginning of a gif frame. In t-rex.gif it had an invalid frame and that's why you got that large Delay value. The invalid frame started with Chr(33) & Chr(249) but the next byte was not a Chr(4) which is guaranteed by the specifications to be the 3rd byte. So, when your code processed t-rex it picked up that as a valid frame but it was just garbage in the file.
As far as brucekik.gif goes it has 2 valid frames. It is a valid gif file but your code is not correct in the way you loop through the frames and I am quite surprised that it has worked up till now until you tried to process brucekik.gif.
One thing I have noticed from the very beginning is that when you extract out a frame and then add the header to it you save it as a complete gif file but if I try to use that saved gif it is not a valid gif file because it will not display in the browser or any other gif viewer.
Process any gif file that you have been able to display and save all of the temp.gif files. Now double click on each one of them to see if they are valid - I bet they are not.
You need to re-consider the way you are looping through the frames because somewhere in your code you are not picking up all the data correctly even though you have been able to animate them you have been lucky. Now you try to process brucekik.gif and your code freeze when trying to load the temp.gif back into your image array.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
I use Chr(33) & Chr(249) & Chr(4) because that guarantees the beginning of a gif frame. In t-rex.gif it had an invalid frame and that's why you got that large Delay value. The invalid frame started with Chr(33) & Chr(249) but the next byte was not a Chr(4) which is guaranteed by the specifications to be the 3rd byte. So, when your code processed t-rex it picked up that as a valid frame but it was just garbage in the file.
As far as brucekik.gif goes it has 2 valid frames. It is a valid gif file but your code is not correct in the way you loop through the frames and I am quite surprised that it has worked up till now until you tried to process brucekik.gif.
One thing I have noticed from the very beginning is that when you extract out a frame and then add the header to it you save it as a complete gif file but if I try to use that saved gif it is not a valid gif file because it will not display in the browser or any other gif viewer.
Process any gif file that you have been able to display and save all of the temp.gif files. Now double click on each one of them to see if they are valid - I bet they are not.
You need to re-consider the way you are looping through the frames because somewhere in your code you are not picking up all the data correctly even though you have been able to animate them you have been lucky. Now you try to process brucekik.gif and your code freeze when trying to load the temp.gif back into your image array.
i can open my temp files normaly
Code:
'Special thanks to jmsrickland from www.VBForums.com
Option Explicit
Option Base 0
Private Declare Function TransparentBlt Lib "msimg32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal crTransparent As Long) As Boolean
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Enum GifType
GIF87A = 0
GIF89A = 1
End Enum
Private Type LogicalScreenDescriptor
GifWidth As Long
GifHeight As Long
GlobalColorSize As Long
SortFlag As Long
ColorResolution As Long
GlobalColorFlag As Long
BackgroundColor As Long
PixelRadio As Long
End Type
Private Type GraphicControl
Disposal As Long
Delay As Long
TransparentColorIndex As Long
UserInput As Long
TransparentFlag As Long
End Type
Private Type ImageDescription
FrameLeft As Long
FrameTop As Long
FrameWidth As Long
FrameHeight As Long
End Type
Private Type Frame
GCGraphicControl As GraphicControl
IDImageDescription As ImageDescription
End Type
Dim fraFrame() As Frame
Public Function LoadGifFile(strFileName As String, aimg As Variant) As Long
Dim GifHeader As GifType
Dim strLogicalScreenDescription As String
Dim LSDLogicalScreenDescription As LogicalScreenDescriptor
'Dim GCGraficControl As GraphicControl
'Dim IDImageDescription As ImageDescription
Dim strGifHeader As String
Dim strFrame As String
Dim fNum As Integer
Dim FileBuffer As String
Dim PictureBuffer As String
Dim PackedField As String
Dim FirstFrame As Long
Dim FrameEnds As Long
Dim ActualFrame As Long
Dim i As Integer
'On Error Resume Next
'Test if the file exists
If Dir$(strFileName) = "" Or strFileName = "" Then
MsgBox "File " & strFileName & " not found", vbCritical
Exit Function
End If
'Put all file info to a variable
fNum = FreeFile
Open strFileName For Binary Access Read As fNum
FileBuffer = String(LOF(fNum), Chr(0))
Get #fNum, , FileBuffer
Close fNum
'FileBuffer = Trim(FileBuffer)
'unload all pictureboxes\images
For i = 1 To aimg.Count - 1
Unload aimg(i)
Next i
aimg(0).Visible = True
'Gif Header
strGifHeader = Left$(FileBuffer, 6)
If strGifHeader = "GIF87a" Then
GifHeader = GIF87A
ElseIf strGifHeader = "GIF89a" Then
GifHeader = GIF89A
End If
'Test if the Gif is animated or not
FirstFrame = InStr(13, FileBuffer, Chr(33) & Chr(249))
ActualFrame = FirstFrame
'if the image isn't animated, then just draw it;)
If InStr(FirstFrame + 2, FileBuffer, Chr(33) & Chr(249)) = 0 Then
aimg(0).Picture = LoadPicture(strFileName)
aimg(0).Tag = 0
Exit Function
End If
'Logical Screen Description
strLogicalScreenDescription = Mid$(FileBuffer, 7, 7)
LSDLogicalScreenDescription.GifWidth = Asc(Mid(strLogicalScreenDescription, 1, 1)) + Asc(Mid(strLogicalScreenDescription, 2, 1)) * 256
LSDLogicalScreenDescription.GifHeight = Asc(Mid(strLogicalScreenDescription, 3, 1)) + Asc(Mid(strLogicalScreenDescription, 4, 1)) * 256
PackedField = Asc(Mid$(strLogicalScreenDescription, 5, 1))
LSDLogicalScreenDescription.GlobalColorFlag = (PackedField And 128) / 2 ^ 7
LSDLogicalScreenDescription.ColorResolution = (PackedField And 112) / 2 ^ 4
LSDLogicalScreenDescription.SortFlag = (PackedField And 8) / 2 ^ 3
' NOTE - This value is meanless if GlobalColorFlag is 0
LSDLogicalScreenDescription.GlobalColorSize = PackedField And 7
LSDLogicalScreenDescription.GlobalColorSize = 3 * (2 ^ (LSDLogicalScreenDescription.GlobalColorSize + 1))
LSDLogicalScreenDescription.BackgroundColor = Asc(Mid$(strLogicalScreenDescription, 6, 1))
LSDLogicalScreenDescription.PixelRadio = Asc(Mid$(strLogicalScreenDescription, 7, 1))
'image count
i = 0
ReDim Preserve fraFrame(i)
Do
'get frame string
If InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249)) <> 0 Then
FrameEnds = InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249)) - 2
Else
FrameEnds = InStr(ActualFrame + 2, FileBuffer, Chr(59)) - 1
End If
strFrame = Mid$(FileBuffer, ActualFrame, Len(FileBuffer) - FirstFrame)
'Get Grafic Control
PackedField = Asc(Mid$(strFrame, 4, 1))
fraFrame(i).GCGraphicControl.Disposal = (PackedField And 12) / 2 ^ 2
' ADDED BY JMS
fraFrame(i).GCGraphicControl.UserInput = (PackedField And 2) / 2 ^ 1
' ADDED BY JMS
fraFrame(i).GCGraphicControl.TransparentFlag = (PackedField And 1)
fraFrame(i).GCGraphicControl.Delay = (Asc(Mid(strFrame, 5, 1)) + Asc(Mid(strFrame, 6, 1)) * 256) * 10
fraFrame(i).GCGraphicControl.TransparentColorIndex = Asc(Mid$(strFrame, 7, 1))
'Get Image Description
fraFrame(i).IDImageDescription.FrameLeft = Asc(Mid(strFrame, 10, 1)) + Asc(Mid(strFrame, 11, 1)) * 256
fraFrame(i).IDImageDescription.FrameTop = Asc(Mid(strFrame, 12, 1)) + Asc(Mid(strFrame, 13, 1)) * 256
fraFrame(i).IDImageDescription.FrameWidth = Asc(Mid(strFrame, 14, 1)) + Asc(Mid(strFrame, 15, 1)) * 256
fraFrame(i).IDImageDescription.FrameHeight = Asc(Mid(strFrame, 16, 1)) + Asc(Mid(strFrame, 17, 1)) * 256
'If the image array don't exist then create\load it
If i > 0 Then
Load aimg(i)
End If
'create the image temp
fNum = FreeFile
Open "temp.gif" For Binary As fNum
PictureBuffer = Mid$(FileBuffer, 1, FirstFrame - 1) & Mid$(FileBuffer, ActualFrame, FrameEnds) & Chr(59) '3B
Put #fNum, 1, PictureBuffer
Close fNum
'Now change the backcolor
aimg(i).BackColor = fraFrame(i).GCGraphicControl.TransparentColorIndex
'now load the image
aimg(i).Picture = LoadPicture("temp.gif")
'change the properties
aimg(i).Tag = fraFrame(i).GCGraphicControl.Delay
'test if theres another image
If InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249) & chr(4)) = 0 Then
Exit Do
Else
ActualFrame = InStr(ActualFrame + 2, FileBuffer, Chr(33) & Chr(249))
i = i + 1
If i > 0 Then ReDim Preserve fraFrame(i)
End If
Loop
'now we can delete the temp file
Kill "temp.gif"
LoadGifFile = i + 1
'Control the Disposal codes
If aimg.Count > 1 Then
Load aimg(aimg.Count)
For i = 0 To aimg.Count - 2
Select Case fraFrame(i).GCGraphicControl.Disposal
Case 0, 1 ' Leave
If i = 0 Then i = 1
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i - 1).ScaleWidth, aimg(i - 1).ScaleHeight, aimg(i - 1).hdc, 0, 0, vbSrcCopy
If fraFrame(i).GCGraphicControl.TransparentFlag <> 0 Then
TransparentBlt aimg(aimg.Count - 1).hdc, _
fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, _
aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, _
aimg(i).ScaleHeight, fraFrame(i).GCGraphicControl.TransparentColorIndex
Else
BitBlt aimg(aimg.Count - 1).hdc, fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
Case 3
BitBlt aimg(aimg.Count - 1).hdc, 0, 0, aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, vbSrcCopy
aimg(i).Cls
If fraFrame(i).GCGraphicControl.TransparentFlag <> 0 Then
TransparentBlt aimg(aimg.Count - 1).hdc, _
fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, _
aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, _
aimg(i).ScaleHeight, GetPixel(aimg(i).hdc, 0, 0)
Else
TransparentBlt aimg(aimg.Count - 1).hdc, _
fraFrame(i).IDImageDescription.FrameLeft, fraFrame(i).IDImageDescription.FrameTop, _
aimg(i).ScaleWidth, aimg(i).ScaleHeight, aimg(i).hdc, 0, 0, aimg(i).ScaleWidth, _
aimg(i).ScaleHeight, LSDLogicalScreenDescription.BackgroundColor
End If
aimg(i).Picture = aimg(aimg.Count - 1).Image
aimg(aimg.Count - 1).Cls
End Select
Debug.Print fraFrame(i).GCGraphicControl.Disposal
Next i
Unload aimg(aimg.Count - 1)
End If
End Function
What does that mean? Are you telling me that those temp.gif files can be displayed in a browser? In a gif viewer? Or are you saying you can open them normally in your program? If you can open them normally then your program would not freeze up on brucekik.gif.
I tested your last code posted. Only some of the frames are coming out OK but others are invalid and cannot be displayed on browser or gif viewer.
Animation isn't correct probably because you are not doing correct disposal methods plus you have dark background and it should not have that.
Tested Candle
Looks OK
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
What does that mean? Are you telling me that those temp.gif files can be displayed in a browser? In a gif viewer? Or are you saying you can open them normally in your program? If you can open them normally then your program would not freeze up on brucekik.gif.
I tested your last code posted. Only some of the frames are coming out OK but others are invalid and cannot be displayed on browser or gif viewer.
(i said 13, but i belive that i can use the 0(zero))
but the position is the chr(33) or chr(249)?
what i know is the frames starts from chr(33) and ends with another chr(33) or, if is the file end, chr(59)... but i don't know, exacly, how works instr() function with char comparation results... can you tell me what position is?
(if i correct these, i can read the brucekik.gif)