Does anybody have any suggestion how to create a routine to create simple morphing between 2 images using the GDI APIs? I'm guessing that some XORing between the images would do it but I just can't figure out a good way of doing it. What I want is for the user to select two pictures and the program would create a number of images "between" those so they together could form a simple morphing animation.
Any suggestions are more then welcome.
Last edited by Joacim Andersson; May 14th, 2003 at 09:23 AM.
have you tried MorphMan? maybe that program will give you some ideas...
it lets the user click on a point on the first pic and set where it should be on the other pic and the finished animation fades between the two pics while moving that certain point....looks really good
Originally posted by cyborg have you tried MorphMan? maybe that program will give you some ideas...
it lets the user click on a point on the first pic and set where it should be on the other pic and the finished animation fades between the two pics while moving that certain point....looks really good
Thanks but if it doesn't come with an API I can use in my app it's useless for me.
Thanks Mushroom, it works as expected however it's dead slow since it's just using Get/SetPixels, especially on larger images. I was hoping for some quicker code... There must be a faster way to XOR the DIBs or GDIs together, or not ??? But thank you so much anyway.
Originally posted by Zaei The only FAST way to do realtime fading is with assembly or DirectX.
Z.
Well, it all depends on how you would define "realtime" in this context. What I want to do is to create images that will be stored on disk, I could later use these images to create an animation, GIF or AVI or whatever. Using assembly to work with GDI objects is not what I'm after. My application will NOT require directx either. Cyborg mentioned MorphMan which doesn't use DirectX and I know for a fact that it isn't written in an assembly language either, I'm pretty sure it uses good ol' Windows GDI functions, either through API or MFC classes.
I define realtime to be generating the images on the fly fast enough that the image appears to be moving (even if it is choppy). However, since you are actually going to be generating and storing the frames, this isnt a problem... The Get/SetPixel method should do fine. If you wanted, you could also try using the Get/SetDIBits functions.
Originally posted by Zaei I define realtime to be generating the images on the fly fast enough that the image appears to be moving (even if it is choppy). However, since you are actually going to be generating and storing the frames, this isnt a problem... The Get/SetPixel method should do fine. If you wanted, you could also try using the Get/SetDIBits functions.
Z.
Well, the problem is that Get/SetPixel isn't fast enough... It takes forever to loop through an image and then doing it again and again for each image to create. I've done some experimenting with the Get/SetDIBits functions but couldn't get it to work for this. Do you have any example code?
Thanks Mushroom, it works as expected however it's dead slow since it's just using Get/SetPixels, especially on larger images. I was hoping for some quicker code... There must be a faster way to XOR the DIBs or GDIs together, or not ??? But thank you so much anyway.
I dint have a better thought to do it..
But yes.. what you could do is after drawing at the first store the picture in a dc do it till your frame count...
This would be one time activity.. Then you can just load those dc'c on by one using BitBlt..
You can use AlphaBlend to fade and combine two pictures.
I'm not sure that is what you want, but is a way of mrphing images.
Code:
'This project requires two picture boxes
'Both picture boxes should contain a picture
Const AC_SRC_OVER = &H00
Private Type BLENDFUNCTION
BlendOp As Byte
BlendFlags As Byte
SourceConstantAlpha As Byte
AlphaFormat As Byte
End Type
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal BLENDFUNCT As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (Destination As Any, Source As Any, ByVal Length As Long)
Private Sub Form_Load()
'KPD-Team 2000
'URL: http://www.allapi.net/
'E-Mail: [email protected]
Dim BF As BLENDFUNCTION, lBF As Long
'Set the graphics mode to persistent
Picture1.AutoRedraw = True
Picture2.AutoRedraw = True
'API uses pixels
Picture1.ScaleMode = vbPixels
Picture2.ScaleMode = vbPixels
'set the parameters
With BF
.BlendOp = AC_SRC_OVER
.BlendFlags = 0
.SourceConstantAlpha = 128
.AlphaFormat = 0
End With
'copy the BLENDFUNCTION-structure to a Long
RtlMoveMemory lBF, BF, 4
'AlphaBlend the picture from Picture1 over the picture of Picture2
AlphaBlend Picture2.hdc, 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture1.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, lBF
End Sub
Thanks a million Jim. I did get alphablend to work, the only problem with that call is that it's not available in Win95 or NT4, but I guess I could live with that. I can always check the OS version and use AlphaBlend if it's available and if not use the slow Get/SetPixel approach if it's not (that should teach people to upgrade their OSes )
Well basically you just have 2 data DIBData arrays instead of one and then blend from one to the other. It's quite easy as long as both pictures have the same size.
[b].A = (iPic1.Data(A).A * Blend1) + (iPic2.Data(A).A * Blend2)<b>Do you work in 24bit graphics mode? Well try adding the A component of the color (Blend function):
</b>
End With
[/B]
Oh yes, that did it Thanks a million Fox, this is greatly appreciated!
When the pathfinding tutorial is out I'll teach you all how to switch the "renderer" of the tile engine. In fact I mean switching from BitBlt to a DXGraphics engine. But give me some time to prepare everything
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal BLENDFUNCT As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (Destination As Any, Source As Any, ByVal Length As Long)
As mentioned in another thread: Right after the path finding tutorial I'll show you how to switch the renderer of the sample engine form BitBlt to DX8. I'm currently working on the path finding tutorial but this may take me the week-end to finish.
I hope nobody minds if I close this thread..... I'm very gratefull to those who has helped me but the discussion of different tutorials should probably be discussed in another thread