
Introduction
I've always wondered how can you edit a video file, and this article shows you one simple way to do it by first splitting your video to a series of bitmaps, making your changes on them, and finally merging them back to form a video, keeping in mind to include the audio stream of the original video.

Background
You don't have to know much about video or image processing, neither will you learn much from this article as this application is depending on two major helping applications. To split up the video frames, I used VirtualDub 1.7.2 which also did the work of extracting the audio stream of the video, and later when merging back the frames, I used a little neat application called Bmp2Avi which also managed the compression of the video using the Xvid MPEG-4 Codec format.
Using the code
First, we create a BackGroundWorker object which will handle the frames editing.
string FramesFolder;
string tmpFramesDir;
private void bgw_ProcessFrames_DoWork(object sender, DoWorkEventArgs e)
{
string tmpStatus = "Idle";
int tmpProgress = 0;
tmpFramesDir = Environment.GetEnvironmentVariable("TEMP") +
"\\Tatoo_Frames";
if (!Directory.Exists(tmpFramesDir))
Directory.CreateDirectory(tmpFramesDir);
FileStream fs = null;
Bitmap bm = null;
Graphics gfx = null;
FramesFolder = Application.StartupPath + "\\VideoFrames";
string[] strFrames = Directory.GetFiles(FramesFolder,
"*.jpeg", SearchOption.TopDirectoryOnly);
foreach (string strFrame in strFrames)
{
fs = new FileStream(strFrame, FileMode.Open, FileAccess.Read);
bm = new Bitmap(Image.FromStream(fs));
fs.Close();
gfx = Graphics.FromImage(bm);
gfx.DrawString("www.QSoftOnline.com",
new Font("Arial", 10f, FontStyle.Bold),
new SolidBrush(Color.Yellow), new Point(170,220));
if (Convert.ToInt16(strFrame.Replace(FramesFolder + "\\",
String.Empty).Split('.')[0]) >= 475)
{
//Start Tatooing
gfx.RotateTransform(25f);
gfx.DrawImage(QTatoo.Properties.Resources.Dragon,110,35,40,40);
gfx.DrawString(strWording, new Font("Freestyle Script", 20f,
FontStyle.Bold), new SolidBrush(Color.Black), new Point(80, 70));
gfx.Dispose();
//Saving changes
bm.Save(tmpFramesDir + "\\" + strFrame.Replace(FramesFolder +
"\\", String.Empty).Replace(".jpeg", ".bmp"),
System.Drawing.Imaging.ImageFormat.Bmp);
}
else
bm.Save(tmpFramesDir + "\\" + strFrame.Replace(FramesFolder + "\\",
String.Empty).Replace(".jpeg", ".bmp"),
System.Drawing.Imaging.ImageFormat.Bmp);
/////Reporting/////
tmpProgress = Convert.ToInt16(strFrame.Replace(FramesFolder + "\\",
String.Empty).Split('.')[0])*100 / strFrames.Length;
tmpStatus = "Converting frame " + Convert.ToInt16(strFrame.Replace(
FramesFolder + "\\", String.Empty).Split('.')[0]);
if (tmpProgress <= 100)
bgw_ProcessFrames.ReportProgress(tmpProgress, tmpStatus);
////////////////////////
}
}
Notice that the individual bitmaps are loaded using a stream which is immediately closed after the retrieval of the frame.
fs = new FileStream(strFrame, FileMode.Open, FileAccess.Read);
bm = new Bitmap(Image.FromStream(fs));
fs.Close();
Now, we start editing the frames after a certain frame "475", in this case.
if (Convert.ToInt16(strFrame.Replace(FramesFolder + "\\", String.Empty).Split('.')[0]) >= 475)
{
//Start Tatooing
gfx.RotateTransform(25f);
gfx.DrawImage(QTatoo.Properties.Resources.Dragon,110,35,40,40);
gfx.DrawString(strWording, new Font("Freestyle Script", 20f,
FontStyle.Bold), new SolidBrush(Color.Black), new Point(80, 70));
gfx.Dispose();
//Saving changes
bm.Save(tmpFramesDir + "\\" + strFrame.Replace(FramesFolder + "\\",
String.Empty).Replace(".jpeg",".bmp"),
System.Drawing.Imaging.ImageFormat.Bmp);
}
Finally, we merge the edited frames back to one video file including the previously extracted audio stream and applying some basic compression.
Environment.CurrentDirectory = tmpFramesDir;
Environment.SetEnvironmentVariable("PATH", "%PATH%;" + tmpFramesDir);
prc_ProduceVideo.StartInfo.FileName = "B2A";
prc_ProduceVideo.StartInfo.Arguments =
@"-f 24 -w Channel.wav -c ""Xvid MPEG-4 Codec"" -o Output";
prc_ProduceVideo.Start();
The little dragon you see above the wording is an embedded image within the solution which can be changed by replacing it in the resources directory.
You may also download the demo application from QSoftOnline.
History
- QTattoo ver. 1.0.0: 29th June 2009
- QTattoo ver. 1.0.1: 3rd July 2009