Dynamic image placement

Topics: User Forum
Developer
Jan 10, 2007 at 2:11 PM
Hi there,

I'm trying to take a video, then superimpose an image on top using an alpha channel, whilst writing some text onto this image. The code i have is as follows:

ITimeline timeline = new DefaultTimeline();
IGroup audioGroup = timeline.AddAudioGroup();
ITrack vidAudioTrack = audioGroup.AddTrack();
IGroup vidVidGroup = timeline.AddVideoGroup(32, 176, 144);
ITrack vidVidTrack = vidVidGroup.AddTrack();
vidVidTrack.AddVideo("C:\\TESTCLIP_noname.mp4");
vidAudioTrack.AddAudio("C:\\TESTCLIP_noname.mp4");
ITrack clipTrack = audioGroup.AddTrack();
clipTrack.AddAudio("C:\\andrew.wav", 4.4);
ITrack newTrack = audioGroup.AddTrack();
newTrack.AddAudio("C:\\andrew.wav", 6);
EffectDefinition effectDefinition = new EffectDefinition(StandardEffects.AudioMixerEffect);
audioGroup.AddEffect((double)3, clipTrack.Duration, effectDefinition);

System.Drawing.Image img = Image.FromFile("c:\\BMGBack.png", false);
Graphics graph = Graphics.FromImage(img);

//make image
String drawString = "Funny video!";

// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);

// Create rectangle for drawing.
float x = 15.0F;
float y = 15.0F;
float width = 170.0F;
float height = 100.0F;
RectangleF drawRect = new RectangleF(x, y, width, height);

// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;

// Draw string to screen.
graph.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graph.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

graph.DrawString(drawString, drawFont, drawBrush, drawRect, drawFormat);

graph.Save();
img.Save("c:\\funnyvideo.png");

ITrack vidText = vidVidGroup.AddTrack();
IClip funnyVidClip = vidText.AddImage("text", img, InsertPosition.Absolute, 3, 0, 3);
funnyVidClip.AddEffect(3, 3, StandardEffects.CreateAlphaSetterRamp(0.5));
vidText.AddTransition(0, clipTrack.Duration,StandardTransitions.CreateKey(KeyTransitionType.Alpha, null, null, null,null,null),false);

using (
MPEGFileRenderer renderer = new MPEGFileRenderer(timeline, "C:\\output.mp4"))
{
renderer.Render();

The image I have has a hole in the middle.

When I save the image out in the middle and then load it into fireworks it looks great - still has the hole but with the text written in the middle. However when I view the video, the colours are broken; there is a purple banding across the text and border and the alpha area has turned black. Also, there is a line in the code which is meant to make the whole image 50% transparent however the video shows a solid image.

Any ideas why this is happening?

Thanks, Mike

p.s. If anyone needs to view the image/video then I can post them somewhere..
Coordinator
Jan 13, 2007 at 3:18 AM
Hi Mike,

Have a look at changeset 16187 - I have added a couple of sample callback participants, showing how you can modify the video frames just prior to them being encoded - this allows you to watermark them using CLR Code, and it's very easy - the down side being that manipulating frames with managed code is never going to be very fast.

For instance this is the whole class required to render the current sample time onto the current frame:

public class SampleTimeWatermarkParticipant : AbstractWatermarkParticipant
{
public SampleTimeWatermarkParticipant(short bitCount, int width, int height, bool flipImages)
: base(bitCount, width, height, flipImages)
{
}

public override void UpdateImage(double sampleTime, System.Drawing.Bitmap bitmap)
{
using (Graphics g = Graphics.FromImage(bitmap))
{
Font font = new Font("Arial", 16);
g.DrawString(string.Format("Time: {0}", sampleTime), font, Brushes.White, 11, 11);
g.DrawString(string.Format("Time: {0}", sampleTime), font, Brushes.Black, 10, 10);
}
}
}

I'm sure you could tailor something to suit your own needs, perhaps even introduce some dynamic behaviour to your watermarks :)

http://www.codeplex.com/splicer/SourceControl/DownloadSourceCode.aspx?changeSetId=16187

Cheers,

- Alex