What do you mean by aren't correct? If the GIF images has an images (by double clicking on it in your folder) then it's a correct GIF image. Give me an example of one that isn't correct
What do you mean by aren't correct? If the GIF images has an images (by double clicking on it in your folder) then it's a correct GIF image. Give me an example of one that isn't correct
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
I don't understand your numbers 0, 1, 2, 3, 4, 5
There are only four disposal codes: 0, 1, 2, and 3.
The image I tested has all frames with a disposal value of 1 = LEAVE
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
sorry... i will express better:
frame #0 -> don't need the disposal value, because it's the 1st frame;
frame #1 ->needs the last frame to be completed... disposal value is '1'(correct). Frame #0 + transparent Frame #1;
frame #2 -> it's a new frame. don't needs a disposal method, but we recive '1'... it's incorrect!!!;
frame #3 -> it's a new frame. don't needs a disposal method, but we recive '1'... it's incorrect!!!;
frame #4 ->needs the last frame to be completed... disposal value is '1'(correct). Frame #3 + transparent Frame #4;
frame #5 ->needs the last frame to be completed... disposal value is '1'(correct). Frame #4(now that these frame is completed) + transparent Frame #5.
sorry if my english is bad, but now i think that you know what i mean(using the halloween image for the test).
i'm testing the disposal values:
but i see some errors:Code:TotalFrames = aImg.Count - 1 LoadGif = True Load aImg(imgCount - 1) For i = 1 To TotalFrames If intDisposed(i) = 0 Then 'do nothing ElseIf intDisposed(i) = 1 Then aImg(aImg.Count - 1).Picture = aImg(i - 1).Image Debug.Print TransparentBlt(aImg(aImg.Count - 1).hdc, 0, 0, aImg(i - 1).ScaleWidth, aImg(i - 1).ScaleHeight, aImg(i).hdc, 0, 0, aImg(i - 1).ScaleWidth, aImg(i - 1).ScaleHeight, GetPixel(aImg(i).hdc, 0, 0)) aImg(i).Picture = aImg(aImg.Count - 1).Image aImg(aImg.Count - 1).Cls End If Next i aImg(aImg.Count - 1) = Nothing 'Unload aImg.Count - 1 Debug.Print aImg.Count - 1 Exit Function
1 - the transparentblt() api function don't do the job(i think is the Load method), because i recive false;
2 - i can't unload the last image control that i create for these test
any advice my friend?
thanks
ok... now works
my problem is the TransparentBlt () destionation position: aImg(0).ScaleWidth \ 2 - aImg(i).ScaleWidth \ 2, aImg(0).ScaleHeight \ 2 - aImg(i).ScaleHeight \ 2, aImg(i).ScaleWidth (X,Y). because i can't put it on centerCode:If aImg.Count >= 2 Then Load aImg(aImg.Count) For i = 1 To aImg.Count - 2 If i = 0 Then 'nothing ElseIf intDisposed(i) = 1 Then 'previous frame + actual frame(transparent) = result frame aImg(aImg.Count - 1).Picture = Nothing aImg(aImg.Count - 1).Picture = aImg(i - 1).Image TransparentBlt aImg(aImg.Count - 1).hdc, aImg(0).ScaleWidth \ 2 - aImg(i).ScaleWidth \ 2, aImg(0).ScaleHeight \ 2 - aImg(i).ScaleHeight \ 2, aImg(i).ScaleWidth, aImg(i).ScaleHeight, aImg(i).hdc, 0, 0, aImg(i).ScaleWidth, aImg(i).ScaleHeight, GetPixel(aImg(i).hdc, 0, 0) aImg(i).Picture = Nothing aImg(i).Picture = aImg(aImg.Count - 1).Image End If Next i Unload aImg(aImg.Count - 1) End If![]()
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
now, in same function, i'm use the disposal values
but i have 1 position error here:Code:If aImg.Count >= 2 Then Load aImg(aImg.Count) aImg(imgCount - 1).Width = aImg(imgCount - 2).Width aImg(imgCount - 1).Height = aImg(imgCount - 2).Height For i = 1 To aImg.Count - 2 If i = 0 Then 'nothing ElseIf intDisposed(i) = 1 Then 'previous frame + actual frame(transparent) = result frame aImg(aImg.Count - 1).Picture = Nothing aImg(aImg.Count - 1).Picture = aImg(i - 1).Image TransparentBlt aImg(aImg.Count - 1).hdc, aImg(i - 1).Width / 2 - aImg(i).Width / 2, aImg(i - 1).Height / 2 - aImg(i).Height / 2, aImg(i - 1).Width, aImg(i - 1).Height, aImg(i).hdc, 0, 0, aImg(i).ScaleWidth, aImg(i).ScaleHeight, GetPixel(aImg(i).hdc, 0, 0) aImg(i).Picture = Nothing aImg(i).Picture = aImg(aImg.Count - 1).Image End If Next i Unload aImg(aImg.Count - 1) End If
i must put all frames on middle of last one for be drawed correctly. but my code isn't right... can you advice me?Code:TransparentBlt aImg(aImg.Count - 1).hdc, aImg(i - 1).Width / 2 - aImg(i).Width / 2, aImg(i - 1).Height / 2 - aImg(i).Height / 2, aImg(i - 1).Width, aImg(i - 1).Height, aImg(i).hdc, 0, 0, aImg(i).ScaleWidth, aImg(i).ScaleHeight, GetPixel(aImg(i).hdc, 0, 0)
I can't because that code your are posting is not in the code you sent me, That's what I asked you before but you didn't respond .
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
Code:'Method Values : '0 - No disposal specified. The decoder is _ not required to take any action. '1 - Do not dispose. The graphic is to be left _ in place. '2 - Restore to background color. The area used by the _ graphic must be restored to the background color. '3 - Restore to previous. The decoder is required to _ restore the area overwritten by the graphic with _ what was there prior to rendering the graphic. '4-7 - To be defined. Option Explicit Public Enum GifType GIF87A = 0 GIF89A = 1 End Enum 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 Public RepeatTimes As Long 'This one calculates, ' but don't use in this sample. If You need, You ' can add simple checking at Timer1_Timer Procedure Public TotalFrames As Long Public GifTypeFile As GifType Public Function LoadGif(sFile As String, aImg As Variant) As Boolean If Dir$(sFile) = "" Or sFile = "" Then MsgBox "File " & sFile & " not found", vbCritical Exit Function End If If Mid$(UCase(sFile), Len(sFile) - 2, 3) <> "GIF" Then Exit Function 'On Error GoTo ErrHandler 'On Error Resume Next Dim fNum As Integer Dim imgHeader As String, fileHeader As String Dim buf$, picbuf$ Dim imgCount As Integer Dim i&, j&, xOff&, yOff&, TimeWait& Dim GifEnd As String Dim intDisposed() As Integer Dim intHeight As Integer Dim intWidth As Integer GifEnd = Chr(0) & Chr(33) & Chr(249) '<---only for animated GIF's For i = 1 To aImg.Count - 1 Unload aImg(i) Next i fNum = FreeFile Open sFile For Binary Access Read As fNum buf = String(LOF(fNum), Chr(0)) Get #fNum, , buf 'Get GIF File into buffer Close fNum i = 1 imgCount = 0 j = InStr(1, buf, GifEnd) + 1 '<--- j = 1 or 0 if not a animated gif ---- j > 1 if it is an animated gif If j < 2 Then aImg(0).Picture = LoadPicture(sFile) TotalFrames = aImg.Count - 1 aImg(0).Tag = 0 LoadGif = True Exit Function End If fileHeader = Left(buf, j) If Left$(fileHeader, 1) <> "G" Then MsgBox "This file is not a *.gif file", vbCritical Exit Function End If 'Get gif type 'intWidth = Asc(Mid$(fileHeader, 7, 4)) 'intHeight = Asc(Mid$(fileHeader, 9, 4)) frmTest.BackColor = Asc(Mid$(fileHeader, 12, 1)) If Left$(fileHeader, 6) = "GIF89a" Then GifTypeFile = GIF89A Else GifTypeFile = GIF87A End If LoadGif = True i = j + 2 If Len(fileHeader) >= 127 Then RepeatTimes& = Asc(Mid(fileHeader, 126, 1)) + (Asc(Mid(fileHeader, 127, 1)) * 256&) Else RepeatTimes = 0 End If Do ' Split GIF Files at separate pictures ' and load them into Image Array imgCount = imgCount + 1 j = InStr(i, buf, GifEnd) + 3 If j > Len(GifEnd) Then fNum = FreeFile Open "temp.gif" For Binary As fNum picbuf = String(Len(fileHeader) + j - i, Chr(0)) picbuf = fileHeader & Mid(buf, i - 1, j - i) Put #fNum, 1, picbuf imgHeader = Left(Mid(buf, i - 1, j - i), 16) Close fNum TimeWait = ((Asc(Mid(imgHeader, 4, 1))) + (Asc(Mid(imgHeader, 5, 1)) * 256&)) * 10& If imgCount > 1 Then xOff = Asc(Mid(imgHeader, 9, 1)) + (Asc(Mid(imgHeader, 10, 1)) * 256&) yOff = Asc(Mid(imgHeader, 11, 1)) + (Asc(Mid(imgHeader, 12, 1)) * 256&) Load aImg(imgCount - 1) 'aImg(imgCount - 1).Width = intWidth '\ Screen.TwipsPerPixelX 'aImg(imgCount - 1).Height = intHeight '\ Screen.TwipsPerPixelY 'aImg(imgCount - 1).Left = aImg(0).Left + (xOff * Screen.TwipsPerPixelX) 'aImg(imgCount - 1).Top = aImg(0).Top + (yOff * Screen.TwipsPerPixelY) End If ' Use .Tag Property to save TimeWait interval for separate Image aImg(imgCount - 1).Tag = TimeWait aImg(imgCount - 1).Picture = LoadPicture("temp.gif") ReDim Preserve intDisposed(aImg.Count - 1) intDisposed(aImg.Count - 1) = Asc(Mid(imgHeader, 3, 1)) / 4 And 3 Kill ("temp.gif") i = j End If 'DoEvents Loop Until j = 3 ' If there are one more Image - Load it If i < Len(buf) Then fNum = FreeFile Open "temp.gif" For Binary As fNum picbuf = String(Len(fileHeader) + Len(buf) - i, Chr(0)) picbuf = fileHeader & Mid(buf, i - 1, Len(buf) - i) Put #fNum, 1, picbuf imgHeader = Left(Mid(buf, i - 1, Len(buf) - i), 16) Close fNum TimeWait = ((Asc(Mid(imgHeader, 4, 1))) + (Asc(Mid(imgHeader, 5, 1)) * 256)) * 10 If imgCount > 1 Then xOff = Asc(Mid(imgHeader, 9, 1)) + (Asc(Mid(imgHeader, 10, 1)) * 256) yOff = Asc(Mid(imgHeader, 11, 1)) + (Asc(Mid(imgHeader, 12, 1)) * 256) Load aImg(imgCount - 1) 'aImg(imgCount - 1).Width = intWidth '\ Screen.TwipsPerPixelX 'aImg(imgCount - 1).Height = intHeight '\ Screen.TwipsPerPixelY 'aImg(imgCount - 1).Left = aImg(0).Left + (xOff * Screen.TwipsPerPixelX) 'aImg(imgCount - 1).Top = aImg(0).Top + (yOff * Screen.TwipsPerPixelY) End If aImg(imgCount - 1).Tag = TimeWait aImg(imgCount - 1).Picture = LoadPicture("temp.gif") ReDim Preserve intDisposed(aImg.Count - 1) intDisposed(aImg.Count - 1) = Asc(Mid(imgHeader, 3, 1)) / 4 And 3 Kill ("temp.gif") End If TotalFrames = aImg.Count - 1 LoadGif = True If aImg.Count >= 2 Then Load aImg(aImg.Count) aImg(imgCount - 1).Width = aImg(imgCount - 2).Width aImg(imgCount - 1).Height = aImg(imgCount - 2).Height For i = 1 To aImg.Count - 2 If i = 0 Then 'nothing ElseIf intDisposed(i) = 1 Then 'previous frame + actual frame(transparent) = result frame aImg(aImg.Count - 1).Picture = Nothing aImg(aImg.Count - 1).Picture = aImg(i - 1).Image TransparentBlt aImg(aImg.Count - 1).hdc, aImg(0).Width / 2 - aImg(i).Width / 2, aImg(0).Height / 2 - aImg(i).Height / 2, aImg(i - 1).Width, aImg(i - 1).Height, aImg(i).hdc, 0, 0, aImg(i).ScaleWidth, aImg(i).ScaleHeight, GetPixel(aImg(i).hdc, 0, 0) aImg(i).Picture = Nothing aImg(i).Picture = aImg(aImg.Count - 1).Image End If Next i Unload aImg(aImg.Count - 1) End If Exit Function ErrHandler: MsgBox "Error No. " & Err.Number & " when reading file", vbCritical LoadGif = False On Error GoTo 0 End Function
Why are you messing around with the TransparentBLT API? Doesn't loading the Image controls already support transparency?
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
All frames have their own positioning control codes. Look at the format I posted in post #23
Each frame has the following header
Code:Y Pos of frame --------------------------+ X Pos of frame --------------------+ | | | 21 F9 | 04 | 05 32 00 09 00 | 2C | 00 00 00 00 | 13 00 | 19 00 |
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
You want the picturebox to have the size of the container's scalemode? Am I understanding you correctly?
I'm assuming the container is the Form on which the picturebox is.
Picture1.ScaleMode = Form1.ScaleMode
Picture1.ScaleWidth = Form1.ScaleWidth
Picture1.ScaleHeight = Form1.ScaleHeight
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
I have question for you
If you are trying to make this GIF application on a regular Form and you are using the Image control to show the different frames then the Image control already has transparency so I don't understand why you need to deal with the TransparentBlt API. If you are trying to do this on a User Control then you are not going to get any transparency at all using Image or Picture controls; it won't work even if you use the TransparentBlt API. The only way to get transparency on a User Control is to draw the pictures directly on the UC window. Is this what you are doing?
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
i will try express me
my last for..next is for compare the disposal values, like you have seen. but thinking in these way: if the frame#1=frame#0 + transparent frame#1, why not show it completed in same picturebox(i have change it)!?! is what i do in last for..next loop
then, when you show the images, you don't need to horry about disposal values![]()
sorry no. think in these way:
form1.scalemode=vbtwips
picture1.scalemode=vbpixels
you know that image size is in pixels
then how you can resize the picture1(i always have these problem)?
imagine:
imagewidth=100 pixels
imageheight=50 pixels
you can't do:
picture1.width=100
picture1.height=50
because the picture size is more small than image size
i need convert the values to form(container) scalemode.
i'm trying correct the transparentblt() destination position![]()
Last edited by joaquim; Aug 2nd, 2012 at 03:01 PM.
First, The Form ScaleMode has nothing to do with your Picture box ScaleMode but just for convenience sake then change your FormScaleMode = vbPixels. Why are you even using Twips?
Second, Your Picture box is already in Pixels and how you deal with it has nothing to do with the Form or the Form's ScaleMode.
If you are putting a picture in a Picture box by loading it (LoadPicture for example) then if your Picture box has it's AutoSize = True it will resize for you. If you are putting a picture in the Picture use BitBlt then you need to do your own resizing. So, you say the image itself is 100 by 50 pixels, right. Change your Picture box to have no border around it; Picture1.Appearance = 0 and Picture1.BorderStyle = 0. Now you can make your changes
Picture1.Width=100
Picture1.Height=50
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
i know my friend. my objective is combine the frames(for show the corrected frame).
but my big objective is use these code for update my sprite control. i'm update it for read more gif files, and make the graphics effects more faster(i'm building the Graphic class too hehehe
can you just advice on transparentblt() api function?
i know that works fine, but the positions aren't correct![]()
I don't know which project you are working on so send me the project that you are currently working on with the TransparentBlt problem and only the gif file you are trying to position. I see what I can do.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
heres the code updated:
the frame 0 position isn't correct. how can i get it?Code:'Method Values : '0 - No disposal specified. The decoder is _ not required to take any action. '1 - Do not dispose. The graphic is to be left _ in place. '2 - Restore to background color. The area used by the _ graphic must be restored to the background color. '3 - Restore to previous. The decoder is required to _ restore the area overwritten by the graphic with _ what was there prior to rendering the graphic. '4-7 - To be defined. Option Explicit Private Type DisposedValues Disposed As Integer FrameXPos As Long FrameYPos As Long End Type Public Enum GifType GIF87A = 0 GIF89A = 1 End Enum 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 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 Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Public RepeatTimes As Long 'This one calculates, ' but don't use in this sample. If You need, You ' can add simple checking at Timer1_Timer Procedure Public TotalFrames As Long Public GifTypeFile As GifType Public Dispose() As DisposedValues Public Function LoadGif(sFile As String, aImg As Variant) As Boolean If Dir$(sFile) = "" Or sFile = "" Then MsgBox "File " & sFile & " not found", vbCritical Exit Function End If If Mid$(UCase(sFile), Len(sFile) - 2, 3) <> "GIF" Then Exit Function 'On Error GoTo ErrHandler 'On Error Resume Next Dim fNum As Integer Dim imgHeader As String, fileHeader As String Dim buf$, picbuf$ Dim imgCount As Integer Dim i&, j&, FrameX&, FrameY&, TimeWait& Dim GifEnd As String Dim intDisposed() As Integer Dim intHeight As Integer Dim intWidth As Integer GifEnd = Chr(0) & Chr(33) & Chr(249) '<---only for animated GIF's 'unload all pictureboxes\images For i = 1 To aImg.Count - 1 Unload aImg(i) Next i 'Get GIF File into buffer fNum = FreeFile Open sFile For Binary Access Read As fNum buf = String(LOF(fNum), Chr(0)) Get #fNum, , buf Close fNum i = 1 imgCount = 0 j = InStr(1, buf, GifEnd) + 1 '<--- j = 1 or 0 if not a animated gif ---- j > 1 if it is an animated gif 'if the Gif isn't animated 'then just show the image If j < 2 Then aImg(0).Picture = LoadPicture(sFile) TotalFrames = aImg.Count - 1 aImg(0).Tag = 0 LoadGif = True Exit Function End If fileHeader = Left(buf, j) 'if the file is gif structure If Left$(fileHeader, 1) <> "G" Then MsgBox "This file is not a *.gif file", vbCritical Exit Function End If LoadGif = True 'Get gif type 'intWidth = Asc(Mid$(fileHeader, 7, 4)) 'intHeight = Asc(Mid$(fileHeader, 9, 4)) 'BackColor = Asc(Mid$(fileHeader, 11, 1)) 'Gif Type If Left$(fileHeader, 6) = "GIF89a" Then GifTypeFile = GIF89A Else GifTypeFile = GIF87A End If i = j + 2 'how many times the animation is repeated If Len(fileHeader) >= 127 Then RepeatTimes& = Asc(Mid(fileHeader, 126, 1)) + (Asc(Mid(fileHeader, 127, 1)) * 256&) Else RepeatTimes = 0 End If Do ' Split GIF Files at separate pictures ' and load them into Image Array imgCount = imgCount + 1 j = InStr(i, buf, GifEnd) + 3 If j > Len(GifEnd) Then fNum = FreeFile Open "temp.gif" For Binary As fNum picbuf = String(Len(fileHeader) + j - i, Chr(0)) picbuf = fileHeader & Mid(buf, i - 1, j - i) Put #fNum, 1, picbuf imgHeader = Left(Mid(buf, i - 1, j - i), 16) Close fNum 'frame delay time TimeWait = ((Asc(Mid(imgHeader, 4, 1))) + (Asc(Mid(imgHeader, 5, 1)) * 256&)) * 10& If imgCount > 1 Then 'Get frame position FrameX = Asc(Mid(imgHeader, 9, 1)) + (Asc(Mid(imgHeader, 10, 1)) * 256&) FrameY = Asc(Mid(imgHeader, 11, 1)) + (Asc(Mid(imgHeader, 12, 1)) * 256&) 'load control for show the image Load aImg(imgCount - 1) 'change the control position 'for show the image in right position aImg(imgCount - 1).Left = FrameX * Screen.TwipsPerPixelX aImg(imgCount - 1).Top = FrameY * Screen.TwipsPerPixelY End If ' Use .Tag Property to save TimeWait interval for separate Image aImg(imgCount - 1).Tag = TimeWait aImg(imgCount - 1).Picture = LoadPicture("temp.gif") 'Get the disposal values and positions from frames ReDim Preserve Dispose(aImg.Count - 1) Dispose(aImg.Count - 1).Disposed = Asc(Mid(imgHeader, 3, 1)) / 4 And 3 Dispose(aImg.Count - 1).FrameXPos = FrameX Dispose(aImg.Count - 1).FrameYPos = FrameY 'kill temp file Kill ("temp.gif") i = j End If 'DoEvents Loop Until j = 3 ' If there are one more Image - Load it If i < Len(buf) Then fNum = FreeFile Open "temp.gif" For Binary As fNum picbuf = String(Len(fileHeader) + Len(buf) - i, Chr(0)) picbuf = fileHeader & Mid(buf, i - 1, Len(buf) - i) Put #fNum, 1, picbuf imgHeader = Left(Mid(buf, i - 1, Len(buf) - i), 16) Close fNum TimeWait = ((Asc(Mid(imgHeader, 4, 1))) + (Asc(Mid(imgHeader, 5, 1)) * 256)) * 10 If imgCount > 1 Then FrameX = Asc(Mid(imgHeader, 9, 1)) + (Asc(Mid(imgHeader, 10, 1)) * 256) FrameY = Asc(Mid(imgHeader, 11, 1)) + (Asc(Mid(imgHeader, 12, 1)) * 256) Load aImg(imgCount - 1) aImg(imgCount - 1).Left = FrameX * Screen.TwipsPerPixelX aImg(imgCount - 1).Top = FrameY * Screen.TwipsPerPixelY End If aImg(imgCount - 1).Tag = TimeWait aImg(imgCount - 1).Picture = LoadPicture("temp.gif") ReDim Preserve Dispose(aImg.Count - 1) Dispose(aImg.Count - 1).Disposed = Asc(Mid(imgHeader, 3, 1)) / 4 And 3 Dispose(aImg.Count - 1).FrameXPos = FrameX Dispose(aImg.Count - 1).FrameYPos = FrameY Kill ("temp.gif") End If TotalFrames = aImg.Count - 1 LoadGif = True If aImg.Count >= 2 Then Load aImg(aImg.Count) aImg(aImg.Count - 1).Width = aImg(0).Width aImg(aImg.Count - 1).Height = aImg(0).Height For i = 1 To aImg.Count - 2 If Dispose(i).Disposed = 0 Then 'nothing ElseIf Dispose(i).Disposed = 1 Then 'previous frame + actual frame(transparent) = result frame aImg(aImg.Count - 1).Picture = aImg(i - 1).Image Debug.Print TransparentBlt(aImg(aImg.Count - 1).hdc, Dispose(i).FrameXPos, Dispose(i).FrameYPos, aImg(i).ScaleWidth, aImg(i).ScaleHeight, aImg(i).hdc, 0, 0, aImg(i).ScaleWidth, aImg(i).ScaleHeight, GetPixel(aImg(i).hdc, 0, 0)) aImg(i).Picture = aImg(aImg.Count - 1).Image aImg(i).Left = FrameX * Screen.TwipsPerPixelX aImg(i).Top = FrameY * Screen.TwipsPerPixelY aImg(aImg.Count - 1).Cls End If Next i Unload aImg(aImg.Count - 1) End If LoadGif = True Exit Function ErrHandler: MsgBox "Error No. " & Err.Number & " when reading file", vbCritical LoadGif = False On Error GoTo 0 End Function
Last edited by joaquim; Aug 5th, 2012 at 03:38 PM.
Here's what you do
1) Set Form ScaleMode = vbPixels
2) Change Image1(0) to appearance flat and BorderStyle none
3) Add another Picture box control (Picture2)
4) Set it's ScaleMode to vbPixels
5) Cut and Paste Image1(0) inside of Picture2
6) Change code as below
In the .BAS module change codeCode:Private Sub Command1_Click() Timer1.Enabled = False CommonDialog1.ShowOpen If LoadGif(CommonDialog1.FileName, image1) = False Then Exit Sub Picture2.Width = image1(0).Width + 4 Picture2.Height = image1(0).Height + 4 FrameCount = 0 Timer1.Interval = image1(0).Tag Timer1.Enabled = True image1(0).Visible = True End Sub
Code:'Method Values : '0 - No disposal specified. The decoder is _ not required to take any action. '1 - Do not dispose. The graphic is to be left _ in place. '2 - Restore to background color. The area used by the _ graphic must be restored to the background color. '3 - Restore to previous. The decoder is required to _ restore the area overwritten by the graphic with _ what was there prior to rendering the graphic. '4-7 - To be defined. Option Explicit Private Type DisposedValues Disposed As Integer FrameXPos As Long FrameYPos As Long End Type Public Enum GifType GIF87A = 0 GIF89A = 1 End Enum 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 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 Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long Public RepeatTimes As Long 'This one calculates, ' but don't use in this sample. If You need, You ' can add simple checking at Timer1_Timer Procedure Public TotalFrames As Long Public GifTypeFile As GifType Public Dispose() As DisposedValues Public Function LoadGif(sFile As String, aImg As Variant) As Boolean If Dir$(sFile) = "" Or sFile = "" Then MsgBox "File " & sFile & " not found", vbCritical Exit Function End If If Mid$(UCase(sFile), Len(sFile) - 2, 3) <> "GIF" Then Exit Function 'On Error GoTo ErrHandler 'On Error Resume Next Dim fNum As Integer Dim imgHeader As String, fileHeader As String Dim buf$, picbuf$ Dim imgCount As Integer Dim i&, j&, FrameX&, FrameY&, TimeWait& Dim GifEnd As String Dim intDisposed() As Integer Dim intHeight As Integer Dim intWidth As Integer GifEnd = Chr(0) & Chr(33) & Chr(249) '<---only for animated GIF's 'unload all pictureboxes\images For i = 1 To aImg.Count - 1 Unload aImg(i) Next i 'Get GIF File into buffer fNum = FreeFile Open sFile For Binary Access Read As fNum buf = String(LOF(fNum), Chr(0)) Get #fNum, , buf Close fNum i = 1 imgCount = 0 j = InStr(1, buf, GifEnd) + 1 '<--- j = 1 or 0 if not a animated gif ---- j > 1 if it is an animated gif 'if the Gif isn't animated 'then just show the image If j < 2 Then aImg(0).Picture = LoadPicture(sFile) TotalFrames = aImg.Count - 1 aImg(0).Tag = 0 LoadGif = True Exit Function End If fileHeader = Left(buf, j) 'if the file is gif structure If Left$(fileHeader, 1) <> "G" Then MsgBox "This file is not a *.gif file", vbCritical Exit Function End If LoadGif = True 'Get gif type 'intWidth = Asc(Mid$(fileHeader, 7, 4)) 'intHeight = Asc(Mid$(fileHeader, 9, 4)) 'BackColor = Asc(Mid$(fileHeader, 11, 1)) 'Gif Type If Left$(fileHeader, 6) = "GIF89a" Then GifTypeFile = GIF89A Else GifTypeFile = GIF87A End If i = j + 2 'how many times the animation is repeated If Len(fileHeader) >= 127 Then RepeatTimes& = Asc(Mid(fileHeader, 126, 1)) + (Asc(Mid(fileHeader, 127, 1)) * 256&) Else RepeatTimes = 0 End If Do ' Split GIF Files at separate pictures ' and load them into Image Array imgCount = imgCount + 1 j = InStr(i, buf, GifEnd) + 3 If j > Len(GifEnd) Then fNum = FreeFile Open "temp.gif" For Binary As fNum picbuf = String(Len(fileHeader) + j - i, Chr(0)) picbuf = fileHeader & Mid(buf, i - 1, j - i) Put #fNum, 1, picbuf imgHeader = Left(Mid(buf, i - 1, j - i), 16) Close fNum 'frame delay time TimeWait = ((Asc(Mid(imgHeader, 4, 1))) + (Asc(Mid(imgHeader, 5, 1)) * 256&)) * 10& If imgCount > 1 Then 'Get frame position FrameX = Asc(Mid(imgHeader, 9, 1)) + (Asc(Mid(imgHeader, 10, 1)) * 256&) FrameY = Asc(Mid(imgHeader, 11, 1)) + (Asc(Mid(imgHeader, 12, 1)) * 256&) 'load control for show the image Load aImg(imgCount - 1) 'change the control position 'for show the image in right position aImg(imgCount - 1).Left = FrameX '* Screen.TwipsPerPixelX aImg(imgCount - 1).Top = FrameY '* Screen.TwipsPerPixelY End If ' Use .Tag Property to save TimeWait interval for separate Image aImg(imgCount - 1).Tag = TimeWait aImg(imgCount - 1).Picture = LoadPicture("temp.gif") 'Get the disposal values and positions from frames ReDim Preserve Dispose(aImg.Count - 1) Dispose(aImg.Count - 1).Disposed = Asc(Mid(imgHeader, 3, 1)) / 4 And 3 Dispose(aImg.Count - 1).FrameXPos = FrameX Dispose(aImg.Count - 1).FrameYPos = FrameY 'kill temp file Kill ("temp.gif") i = j End If 'DoEvents Loop Until j = 3 ' If there are one more Image - Load it If i < Len(buf) Then fNum = FreeFile Open "temp.gif" For Binary As fNum picbuf = String(Len(fileHeader) + Len(buf) - i, Chr(0)) picbuf = fileHeader & Mid(buf, i - 1, Len(buf) - i) Put #fNum, 1, picbuf imgHeader = Left(Mid(buf, i - 1, Len(buf) - i), 16) Close fNum TimeWait = ((Asc(Mid(imgHeader, 4, 1))) + (Asc(Mid(imgHeader, 5, 1)) * 256)) * 10 If imgCount > 1 Then FrameX = Asc(Mid(imgHeader, 9, 1)) + (Asc(Mid(imgHeader, 10, 1)) * 256) FrameY = Asc(Mid(imgHeader, 11, 1)) + (Asc(Mid(imgHeader, 12, 1)) * 256) Load aImg(imgCount - 1) aImg(imgCount - 1).Left = FrameX '* Screen.TwipsPerPixelX aImg(imgCount - 1).Top = FrameY '* Screen.TwipsPerPixelY End If aImg(imgCount - 1).Tag = TimeWait aImg(imgCount - 1).Picture = LoadPicture("temp.gif") ReDim Preserve Dispose(aImg.Count - 1) Dispose(aImg.Count - 1).Disposed = Asc(Mid(imgHeader, 3, 1)) / 4 And 3 Dispose(aImg.Count - 1).FrameXPos = FrameX Dispose(aImg.Count - 1).FrameYPos = FrameY Kill ("temp.gif") End If TotalFrames = aImg.Count - 1 LoadGif = True If aImg.Count >= 2 Then Load aImg(aImg.Count) aImg(aImg.Count - 1).Width = aImg(0).Width aImg(aImg.Count - 1).Height = aImg(0).Height For i = 1 To aImg.Count - 2 If Dispose(i).Disposed = 0 Then 'nothing ElseIf Dispose(i).Disposed = 1 Then 'previous frame + actual frame(transparent) = result frame aImg(aImg.Count - 1).Picture = aImg(i - 1).Image Debug.Print TransparentBlt(aImg(aImg.Count - 1).hdc, Dispose(i).FrameXPos, Dispose(i).FrameYPos, aImg(i).ScaleWidth, aImg(i).ScaleHeight, aImg(i).hdc, 0, 0, aImg(i).ScaleWidth, aImg(i).ScaleHeight, GetPixel(aImg(i).hdc, 0, 0)) aImg(i).Picture = aImg(aImg.Count - 1).Image aImg(i).Left = 0 'FrameX * Screen.TwipsPerPixelX aImg(i).Top = 0 'FrameY * Screen.TwipsPerPixelY aImg(aImg.Count - 1).Cls End If Next i Unload aImg(aImg.Count - 1) End If LoadGif = True Exit Function ErrHandler: MsgBox "Error No. " & Err.Number & " when reading file", vbCritical LoadGif = False On Error GoTo 0 End Function
Last edited by jmsrickland; Aug 5th, 2012 at 06:56 PM.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
OK, here is another BAS module
BTW: You are not using the correct value for the background color
Code:+------+----+----+--+--+--+----------------------- |GIF89a|1400|1900|F7|04|00|<--- Start of GCT ---> +------+----+----+--+--+--+----------------------- | | If high bit is 1 ---+ | then use this byte ----+ as index into Global Color Table for the background color
Last edited by jmsrickland; Aug 6th, 2012 at 02:37 PM.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
i see 1 error that sometimes i do... instead start with '1', i start with '0'. the 1st byte is '1' and not '0'
i need ask 2 things:
1 - all bytes are in hexadecimal values?
2 - if so. when we see the Logical Screen Descriptor(for sample) the Packed Field(2 bytes). we need convert it to binary and then catch the bits that we need, right? or theres another calculation\formula more easy?
'There is no error you just need to know how to read the bits of the bytes
The Format Is this:
Which means you use the next byte 04 an the index into the Global Color Table. The 04 does not mean to use the 5th byte as the color. It means you need to multiply the index by 3 and add that value the the base address of the color tableCode:Bit Position = 7 6 5 4 3 2 1 0 F7 = 1 1 1 1 0 1 1 1 You can see that the high bit is set to 1 | | 1 1 1 1 0 1 1 1 F 7
The table has 3-bytes per color, like this:
Keep in mind that there may not even be a Global Color Table. If this is the case then allCode:<--------------- Global Color Table (up to 768 Bytes) --------------------> Color 0 Color 1 Color 2 Color 3 Color 4 Color 254 Color 255 | 00 00 00 | 80 00 00 | 00 80 00 | 80 80 00 | XX XX XX | ......... | 00 FF FF | FF FF FF |
frames use their own Local Color Table if they have one.
Also, even if there is a Global Color Table it may or may not be used.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
What 2-byte packed field are you referring to? A packed field is only 1-byte
You don't convert to binary, you convert to Ascii. For example, if you want to test the Global Color Table bit (in the above example it is the byte that has the &HF7 = 11110111 ) you AND that byte with 128(= &H80 = 10000000) and if it equals 128 then the bit is set on and that means there is a Global Color Table
In VB you would do it this way:
Code:If Asc(Mid(GifBuffer, 11, 1)) And 128 = 128 Then ' ' Here if there is a Global Color Table ' End If
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
You say you are looking at a 91. Now is that a Decimal 91 (same as Ascii) or is it &H91?Code:+---- GIF Header ---+ | | Packed byte -------------------------|--------------+ | Logical Screen Height ---------------|------------+ | | Logical Screen Width ----------------|---------+ | | | | | | | | +---+---+--+--+-+-+-+ |GIF|89a| | | | | | +---+---+--+--+-+-+-+ | | | | | + -- Pixel Aspect Ratio | + ---- Background Color Index | Global Color Table Size ----------------------+ | Sort Flag --------------------------------+ | | Color Resolution ---------------------+ | | | Global Color Table Flag ----------+ | | | | | | | | | | | | | | 7 6 5 4 3 2 1 0 | +-+-----+-+-----+ | | | | | | -+ +-+-----+-+-----+ | | | + --- 0 Table not sorted | 1 Table is sorted decreasing importance, most important color first. | + 1 = Global Color Table - Use next byte as index for Background Color 0 = No Global Color Table - Next byte is meaningless Size of Global Color Table 3 * (2 ^ ((Value of bits 2 1 0) + 1))
Assuming it is &H91 then you have this:
91 = 1000 0001
Now look at above table I posted and you can see that the high bit is on so therefore you have a Global Color Table and because the last three bit are 001 that says you color table is only 1 which doesn't make sense.
Now if it is Ascii 91 then that means it is &H5B and 5B = 0101 1011
And that says the high bit is off so there is no Global Color Table
Which GIF file are you looking at?
Last edited by jmsrickland; Aug 16th, 2012 at 01:02 PM.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
You are not paying attention to what I am saying to you.
First: Asc(91) does not equal 5B. It the other way around; Asc(Chr(&H5B)) = 91. To get the hexadecimal you simply do this Hex(91) = 5B
If it is decimal 91 (which means the byte is 5B then there is no Global Color Table so it is meaningless to try and to find it's size.
Second, you do not use the last 3-bits like you are doing. Do not do this:
3 * (2 ^ ((011) + 1))=12288
because you are using the last 3-bits as the value and that is not what you should do. 011 = 3 so you math would be this:
3 * (2 ^ 3) + 1 = 25
Your VB code for this is this:
3 * (2 ^ (Asc(Mid(GifBuffer, 11, 1)) And 3)) + 1
But remember, &H5B says there is no global color table which means that the frame(s) have their own
Last edited by jmsrickland; Aug 16th, 2012 at 03:00 PM.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
You are not paying attention to what I am saying to you.
First: Asc(91) does not equal 5B. It the other way around; Asc(Chr(&H5B)) = 91. To get the hexadecimal you simply do this Hex(91) = 5B
If it is decimal 91 (which means the byte is 5B then there is no Global Color Table so it is meaningless to try and to find it's size.
Second, you do not use the last 3-bits like you are doing. Do not do this:
3 * (2 ^ ((011) + 1))=12288
because you are using the last 3-bits as the value and that is not what you should do. 011 = 3 so you math would be this:
3 * (2 ^ 3) + 1 = 25
3 * (2 ^ (Asc(Mid(buf, 11, 1)) And 3)) + 1
But remember, &H5B says there is no global color table which means that the frame(s) have their own
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
ok... thanks for correct me.
i know that 011(binary)=3(decimal). the vb6 have something for convert the binary to decimal or i must build a function?
"But remember, &H5B says there is no global color table which means that the frame(s) have their own"
it's a const value?
You are not paying attention to what I am saying to you.
First: Asc(91) does not equal 5B. It the other way around; Asc(Chr(&H5B)) = 91. To get the hexadecimal you simply do this Hex(91) = 5B
If it is decimal 91 (which means the byte is 5B then there is no Global Color Table so it is meaningless to try and to find it's size.
Second, you do not use the last 3-bits like you are doing. Do not do this:
3 * (2 ^ ((011) + 1))=12288
because you are using the last 3-bits as the value and that is not what you should do. 011 = 3 so you math would be this:
3 * (2 ^ 3) + 1 = 25
Your VB code is this:
3 * (2 ^ (Asc(Mid(GifBuffer, 11, 1)) And 3)) + 1
But remember, &H5B says there is no global color table which means that the frame(s) have their own so the above calculation would be meaningless in this case but you would use this when there is a global color table or use it for a local color table except the offset 11 would be a different number
3 * (2 ^ (Asc(Mid(GifBuffer, ??, 1)) And 3)) + 1
where ?? is the string position for the byte that is used for a local color table
To extract the values from this byte use the following
7654 3210
xxxx xxxx
And 128 to get x000 0000 = Global Color Table Flag
And 48 to get 0xxx 0000 = Color Resolution
And 8 to get 0000 x000 = Sort Flag
And 3 to get 0000 0xxx = Global Color Table Size
Last edited by jmsrickland; Aug 16th, 2012 at 03:19 PM.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
"3 * (2 ^ (Asc(Mid(GifBuffer, 11, 1)) And 3)) + 1"
then it's:
3 * (2 ^ (Asc(Mid(GifBuffer, 11, 1)) And BinaryConvertedToDecimal)) + 1
right?
Last edited by joaquim; Aug 16th, 2012 at 03:28 PM.
The calculation 3 * (2 ^ (Asc(Mid(GifBuffer, 11, 1)) And 3)) + 1 is for the color table size only, not the other fields.
Global Color Table Flag = Asc(Mid(GifBuffer, 11, 1)) And 128
Color Resolution = Asc(Mid(GifBuffer, 11, 1)) And 48
Sort Flag = Asc(Mid(GifBuffer, 11, 1)) And 8
Global Color Table Size = 3 * (2 ^ (Asc(Mid(GifBuffer, 11, 1)) And 3)) + 1
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
Last edited by jmsrickland; Aug 16th, 2012 at 04:15 PM.
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day
Here is a complete description of the GCE
Code:"Extension Introducer" Identifies beginning of an extension Block ----------+ Block Terminator | | | | +----+----+----+----+----+----+----+----+ | 21 | F9 | 04 | X1 | X2 | X3 | X4 | 00 | +----+----+----+----+----+----+----+----+ | | | | | | |<- Control Block ->| Graphic Control Label ---------------+ | +---- Block Size (Fixed Value) block. This field contains the fixed value 0x21. ii) Graphic Control Label - Identifies the current block as a Graphic Control Extension. This field contains the fixed value 0xF9. iii) Block Size - Number of bytes in the block, after the Block Size field and up to but not including the Block Terminator. This field contains the fixed value 4. iv) Disposal Method - Indicates the way in which the graphic is to be treated after being displayed. | +-----------------------+ | +----+----+----+----+----+ | 04 | X1 | X2 | X3 | X4 | +----+----+----+----+----+ | +------------+ | | --------------- X1 = 7 6 5 4 3 2 1 0 --------------- x x x x 0 0 x x x x x x 0 1 x x x x x x 1 0 x x x x x x 1 1 x x | | +---------+ | 00 0 No disposal specified 01 1 Do not dispose - Leave 10 2 Restore Background 11 3 Restore Previous Bits 7 6 5 3 To be defined v) User Input Flag - Indicates whether or not user input is expected before continuing. If the flag is set, processing will continue when user input is entered. The nature of the User input is determined by the application (Carriage Return, Mouse Button Click, etc.). | +------------------------+ | X1 = 7 6 5 4 3 2 1 0 --------------- x x x x d d 0 x x x x x d d 1 x Values : 0 - User input is not expected. 1 - User input is expected. When a Delay Time is used and the User Input Flag is set, processing will continue when user input is received or when the delay time expires, whichever occurs first. vi) Transparency Flag - Indicates whether a transparency index is given in the Transparent Index field. (This field is the least significant bit of the byte.) | +--------------------------+ | X1 = 7 6 5 4 3 2 1 0 --------------- x x x x x x x 0 x x x x d d u 1 Values : 0 - Transparent Index is not given. 1 - Transparent Index is given. vii) Delay Time - If not 0, this field specifies the number of hundredths (1/100) of a second to wait before continuing with the processing of the Data Stream. The clock starts ticking immediately after the graphic is rendered. This field may be used in conjunction with the User Input Flag field. | +----------------------------+----+ 2-byte value | | +---+----+----+----+----+----+----+----+ |21 | F9 | 04 | X1 | X2 | X3 | X4 | 00 | +---+----+----+----+----+----+----+----+ viii) Transparency Index - The Transparency Index is such that when encountered, the corresponding pixel of the display device is not modified and processing goes on to the next pixel. The index is present if and only if the Transparency Flag is set to 1. | +--------------------------------------+ | +---+----+----+----+----+----+----+----+ |21 | F9 | 04 | X1 | X2 | X3 | X4 | 00 | +---+----+----+----+----+----+----+----+ ix) Block Terminator - This [1 byte] zero-length data block marks the end of the | Graphic Control Extension. | +-------------------------------------------+ | +---+----+----+----+----+----+----+----+ |21 | F9 | 04 | X1 | X2 | X3 | X4 | 00 | +---+----+----+----+----+----+----+----+
The better the information you give to begin with and the sooner you reply the sooner you will get help and get your problem resolved
When I was young and in my prime I used to program all the time but now I'm old and getting gray I only program once a day