nLL

Mobile web, .Net, Android, gadgets and some random stuff

Another Simple C# Wrapper For FFmpeg

After reading below article do not forget to checkout Important Update to Another Simple C# Wrapper For FFmpeg

When you want to encode uploaded videos to your website you are in luck if you use PHP, encoding uploaded videos to your web site on the fly quite easy on Linux based servers. Install FFmpeg and get a PHP wrapper for FFmpeg and you are good to go.

Story is a little bit different on Windows servers. There is no support from .Net framework; although there are couple of open source C# .Net wrappers for FFmpeg that encodes video on the fly, they are mostly incomplete. There are also commercial ones such as Mediahandler are not free/open-source.

In short, I couldn't get what i wanted from open-source ones so I've decided to write my own C# wrapper for FFmpeg.

My .Net skills are no where near good but here what i ended up with.

 

 

See usage in the example at the bottom of this post. Download whole project VideoEncoder.rar (48.54 kb) or download changes made by Anders (see comments) VideoEncoderAsync.rar (6.79 kb)

Don't forget to download FFmpeg win32 build and put in to FFmpeg folder in the project

 

 

My solution has 5 classes;

 

Encoder.cs, does the main job and gets FFmpegPath as input.

It has 3 methods :

  •  EncodeVideo: Encodes video with FFmpeg according to commands
  •  GetVideoThumbnail: Gets video thumbnail image without encoding video
  •  GetVideoInfo: Gets information about source video and assigns it to VideoFile class such as Duration, BitRate, AudioFormat, VideoFormat, Height, Width 

 

To do: Implement a class to insert logo on to the video with ffmpeg -vhook

 

Source of Encoder.cs

 

using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;


namespace VideoEncoder
{
    public class Encoder
    {

        public EncodedVideo EncodeVideo(VideoFile input, string encodingCommand, string outputFile, bool getVideoThumbnail)
        {
            EncodedVideo encoded = new EncodedVideo();

            Params = string.Format("-i {0} {1} {2}", input.Path, encodingCommand, outputFile);
            string output = RunProcess(Params);
            encoded.EncodingLog = output;
            encoded.EncodedVideoPath = outputFile;
            




            if (File.Exists(outputFile))
            {
                encoded.Success = true;

                //get thumbnail?
                if (getVideoThumbnail)
                {
                    string saveThumbnailTo = outputFile + "_thumb.jpg";

                    if (GetVideoThumbnail(input, saveThumbnailTo))
                    {
                        encoded.ThumbnailPath = saveThumbnailTo;
                    }
                }
            }
            else
            {
                encoded.Success = false;
            }


            return encoded;

        }
        public bool GetVideoThumbnail(VideoFile input, string saveThumbnailTo)
        {
            if (!input.infoGathered)
            {
                GetVideoInfo(input);
            }
            int secs;
            //divide the duration in 3 to get a preview image in the middle of the clip
            //instead of a black image from the beginning.
            secs = (int)Math.Round(TimeSpan.FromTicks(input.Duration.Ticks / 3).TotalSeconds, 0);
            string Params = string.Format("-i {0} {1} -vcodec mjpeg -ss {2} -vframes 1 -an -f rawvideo", input.Path, saveThumbnailTo, secs);
            string output = RunProcess(Params);

            if (File.Exists(saveThumbnailTo))
            {
                return true;
            }
            else
            {
                //try running again at frame 1 to get something
                Params = string.Format("-i {0} {1} -vcodec mjpeg -ss {2} -vframes 1 -an -f rawvideo", input.Path, saveThumbnailTo, 1);
                output = RunProcess(Params);

                if (File.Exists(saveThumbnailTo))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }


        }
        public void GetVideoInfo(VideoFile input)
        {
            string Params = string.Format("-i {0}", input.Path);
            string output = RunProcess(Params);
            input.RawInfo = output;
            input.Duration = ExtractDuration(input.RawInfo);
            input.BitRate = ExtractBitrate(input.RawInfo);
            input.RawAudioFormat = ExtractRawAudioFormat(input.RawInfo);
            input.AudioFormat = ExtractAudioFormat(input.RawAudioFormat);
            input.RawVideoFormat = ExtractRawVideoFormat(input.RawInfo);
            input.VideoFormat = ExtractVideoFormat(input.RawVideoFormat);
            input.Width = ExtractVideoWidth(input.RawInfo);
            input.Height = ExtractVideoHeight(input.RawInfo);
            input.infoGathered = true;
        }
        private string RunProcess(string Parameters)
        {
            //create a process info
            ProcessStartInfo oInfo = new ProcessStartInfo(this.FFmpegPath, Parameters);
            oInfo.UseShellExecute = false;
            oInfo.CreateNoWindow = true;
            oInfo.RedirectStandardOutput = true;
            oInfo.RedirectStandardError = true;

            //Create the output and streamreader to get the output
            string output = null; StreamReader srOutput = null;

            //try the process
            try
            {
                //run the process
                Process proc = System.Diagnostics.Process.Start(oInfo);

                proc.WaitForExit();

                //get the output
                srOutput = proc.StandardError;

                //now put it in a string
                output = srOutput.ReadToEnd();

                proc.Close();
            }
            catch (Exception)
            {
                output = string.Empty;
            }
            finally
            {
                //now, if we succeded, close out the streamreader
                if (srOutput != null)
                {
                    srOutput.Close();
                    srOutput.Dispose();
                }
            }
            return output;
        }
        public string FFmpegPath { get; set; }
        private string Params { get; set; }
        private TimeSpan ExtractDuration(string rawInfo)
        {
            TimeSpan t = new TimeSpan(0);
            Regex re = new Regex("[D|d]uration:.((\\d|:|\\.)*)", RegexOptions.Compiled);
            Match m = re.Match(rawInfo);

            if (m.Success)
            {
                string duration = m.Groups[1].Value;
                string[] timepieces = duration.Split(new char[] { ':', '.' });
                if (timepieces.Length == 4)
                {
                    t = new TimeSpan(0, Convert.ToInt16(timepieces[0]), Convert.ToInt16(timepieces[1]), Convert.ToInt16(timepieces[2]), Convert.ToInt16(timepieces[3]));
                }
            }

            return t;
        }
        private double ExtractBitrate(string rawInfo)
        {
            Regex re = new Regex("[B|b]itrate:.((\\d|:)*)", RegexOptions.Compiled);
            Match m = re.Match(rawInfo);
            double kb = 0.0;
            if (m.Success)
            {
                Double.TryParse(m.Groups[1].Value, out kb);
            }
            return kb;
        }
        private string ExtractRawAudioFormat(string rawInfo)
        {
            string a = string.Empty;
            Regex re = new Regex("[A|a]udio:.*", RegexOptions.Compiled);
            Match m = re.Match(rawInfo);
            if (m.Success)
            {
                a = m.Value;
            }
            return a.Replace("Audio: ", "");
        }
        private string ExtractAudioFormat(string rawAudioFormat)
        {
            string[] parts = rawAudioFormat.Split(new string[] { ", " }, StringSplitOptions.None);
            return parts[0].Replace("Audio: ", "");
        }
        private string ExtractRawVideoFormat(string rawInfo)
        {
            string v = string.Empty;
            Regex re = new Regex("[V|v]ideo:.*", RegexOptions.Compiled);
            Match m = re.Match(rawInfo);
            if (m.Success)
            {
                v = m.Value;
            }
            return v.Replace("Video: ", ""); ;
        }
        private string ExtractVideoFormat(string rawVideoFormat)
        {
            string[] parts = rawVideoFormat.Split(new string[] { ", " }, StringSplitOptions.None);
            return parts[0].Replace("Video: ", "");
        }
        private int ExtractVideoWidth(string rawInfo)
        {
            int width = 0;
            Regex re = new Regex("(\\d{2,4})x(\\d{2,4})", RegexOptions.Compiled);
            Match m = re.Match(rawInfo);
            if (m.Success)
            {
                int.TryParse(m.Groups[1].Value, out width);
            }
            return width;
        }
        private int ExtractVideoHeight(string rawInfo)
        {
            int height = 0;
            Regex re = new Regex("(\\d{2,4})x(\\d{2,4})", RegexOptions.Compiled);
            Match m = re.Match(rawInfo);
            if (m.Success)
            {
                int.TryParse(m.Groups[2].Value, out height);
            }
            return height;
        }
    }
}

 

 

 

EncodedVideo.cs is output package for Encode method

Source of EncodedVideo.cs

 

namespace VideoEncoder
{
    public class EncodedVideo
    {
        public string EncodedVideoPath { get; set; }
        public string ThumbnailPath {get; set; }
        public string EncodingLog { get; set; }
        public bool Success { get; set; }
    }

}

 

 

VideoFile.cs holds properties of input/source video

Source of VideoFile.cs

 

using System;
using System.IO;

namespace VideoEncoder
{

    public class VideoFile
    {
        private string _Path;
        public string Path
        {
            get
            {
                return _Path;
            }
            set
            {
                _Path = value;
            }
        }
        public TimeSpan Duration { get; set; }
        public double BitRate { get; set; }
        public string RawAudioFormat { get; set; }
        public string AudioFormat { get; set; }
        public string RawVideoFormat { get; set; }
        public string VideoFormat { get; set; }
        public int Height { get; set; }
        public int Width { get; set; }
        public string RawInfo { get; set; }
        public bool infoGathered { get; set; }

        public VideoFile(string path)
        {
            _Path = path;
            Initialize();
        }
        private void Initialize()
        {
            this.infoGathered = false;
            if (string.IsNullOrEmpty(_Path))
            {
                throw new Exception("Video file Path not set or empty.");
            }
            if (!File.Exists(_Path))
            {
                throw new Exception("The video file " + _Path + " does not exist.");
            }
        }
    }
}

 

Project also have two helper classes QuickAudioEncodingCommands.cs and QuickVideoEncodingCommands.cs to make video encoding easier. I simple created FFmpeg command-line snippets for easy encoding

Source of QuickAudioEncodingCommands.cs

 

/// 
/// 
/// Ready made encoding commands for FFmpeg
/// Use when calling EncodeVideo commands as string encodingCommand
/// Add remove as you like
/// 
///
///
public class QuickAudioEncodingCommands
{
        //mp3
    public static string MP3128Kbps = "-y -ab 128k -ar 44100";
    public static string MP396Kbps = "-y -ab 96k -ar 44100";
    public static string MP364Kbps = "-y -ab 64k -ar 44100";
    public static string MP332Kbps = "-y -ab 32k -ar 44100";
 }

 

 

Source of  QuickVideoEncodingCommands.cs

 

/// 
/// 
/// Ready made encoding commands for FFmpeg
/// Use when calling EncodeVideo commands as string encodingCommand
/// Add remove as you like
/// 
///
///
namespace VideoEncoder
{
    public class QuickVideoEncodingCommands
    {
        //-b
        static string LQVideoBitrate = "256k";
        static string MQVideoBitrate = "512k";
        static string HQVideoBitrate = "756k";
        static string VHQVideoBitrate = "1024k";
        //-ab 
        static string LQAudioBitrate = "32k";
        static string MQAudioBitrate = "64k";
        static string HQAudioBitrate = "96k";
        static string VHQAudioBitrate = "128k";
        //-ar
        static string LQAudioSamplingFrequency = "22050";
        static string MQAudioSamplingFrequency = "44100";
        static string HQAudioSamplingFrequency = "44100";
        //-s
        static string SQCIF = "sqcif"; //128x96
        static string QCIF = "qcif"; //176x144
        static string QVGA = "qvga"; //320x240
        static string CIF = "cif"; //352x288
        static string VGA = "vga"; //640x480
        static string SVGA = "svga"; //800x600

   
        // todo
        //insert logo
        //
        //string LogoPath ="/Path/to/transparent/png";
        //string PositionX ="0";
        //string PositionY ="0";
        //string.Format("-vhook \"vhook/imlib2.dll -x {0} -y {1}  -i {2}\"", PositionX,PositionY,LogoPath);



        //flv
        public static string FLVLowQualityQCIF = string.Format("-y -b {0} -ab {1} -ar {2} -s {3} -f flv", LQVideoBitrate, LQAudioBitrate, LQAudioSamplingFrequency, QVGA);
        public static string FLVMediumQualityCIF = string.Format("-y -b {0} -ab {1} -ar {2} -s {3} -f flv", MQVideoBitrate, MQAudioBitrate, MQAudioSamplingFrequency, CIF);
        public static string FLVHighQualityVGA = string.Format("-y -b {0} -ab {1} -ar {2} -s {3} -f flv", HQVideoBitrate, HQAudioBitrate, HQAudioSamplingFrequency, VGA);
        public static string FLVVeryHighQualitySVGA = string.Format("-y -b {0} -ab {1} -ar {2} -s {3} -f flv", VHQVideoBitrate, VHQAudioBitrate, HQAudioSamplingFrequency, SVGA);

        public static string FLVLowQualityKeepOriginalSize = string.Format("-y -b {0} -ab {1} -ar {2} -f flv", LQVideoBitrate, LQAudioBitrate, LQAudioSamplingFrequency, QVGA);
        public static string FLVMediumQualityKeepOriginalSize = string.Format("-y -b {0} -ab {1} -ar {2} -f flv", MQVideoBitrate, MQAudioBitrate, MQAudioSamplingFrequency, CIF);
        public static string FLVHighQualityKeepOriginalSize = string.Format("-y -b {0} -ab {1} -ar {2} -f flv", HQVideoBitrate, HQAudioBitrate, HQAudioSamplingFrequency, VGA);
        public static string FLVVeryHighQualityKeepOriginalSize = string.Format("-y -b {0} -ab {1} -ar {2} -f flv", VHQVideoBitrate, VHQAudioBitrate, HQAudioSamplingFrequency, SVGA);

        //3gp
        public static string THREEGPLowQualitySQCIF = string.Format("-y -acodec aac -ac 1 -b {0} -ab {1} -ar {2} -s {3} -f 3gp", LQVideoBitrate, LQAudioBitrate, LQAudioSamplingFrequency, SQCIF);
        public static string THREEGPMediumQualityQCIF = string.Format("-y -acodec aac -b {0} -ab {1} -ar {2} -s {3} -f 3gp", MQVideoBitrate, MQAudioBitrate, MQAudioSamplingFrequency, QCIF);
        public static string THREEGPHighQualityCIF = string.Format("-y -acodec aac -b {0} -ab {1} -ar {2} -s {3} -f 3gp", VHQVideoBitrate, VHQAudioBitrate, HQAudioSamplingFrequency, CIF);
        //mp4
        public static string MP4LowQualityKeepOriginalSize = string.Format("-y -b {0} -ab {1} -ar {2} -f mp4", LQVideoBitrate, LQAudioBitrate, LQAudioSamplingFrequency, QVGA);
        public static string MP4MediumQualityKeepOriginalSize = string.Format("-y -b {0} -ab {1} -ar {2} -f mp4", MQVideoBitrate, MQAudioBitrate, MQAudioSamplingFrequency, CIF);
        public static string MP4HighQualityKeepOriginalSize = string.Format("-y -b {0} -ab {1} -ar {2} -f mp4", HQVideoBitrate, HQAudioBitrate, HQAudioSamplingFrequency, VGA);

        public static string MP4LowQualityQVGA = string.Format("-y -b {0} -ab {1} -ar {2} -s {3} -f mp4", LQVideoBitrate, LQAudioBitrate, LQAudioSamplingFrequency, QVGA);
        public static string MP4MediumQualityCIF = string.Format("-y -b {0} -ab {1} -ar {2} -s {3} -f mp4", MQVideoBitrate, MQAudioBitrate, MQAudioSamplingFrequency, CIF);
        public static string MP4HighQualityVGA = string.Format("-y -b {0} -ab {1} -ar {2} -s {3} -f mp4", HQVideoBitrate, HQAudioBitrate, HQAudioSamplingFrequency, VGA);

        //WMV
        public static string WMVLowQualityQVGA = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2} -s {3}", LQVideoBitrate, LQAudioBitrate, LQAudioSamplingFrequency, QVGA);
        public static string WMVMediumQualityCIF = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2} -s {3}", MQVideoBitrate, MQAudioBitrate, MQAudioSamplingFrequency, CIF);
        public static string WMVHighQualityVGA = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2} -s {3}", HQVideoBitrate, HQAudioBitrate, HQAudioSamplingFrequency, VGA);
        public static string WMVVeryHighQualitySVGA = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2} -s {3}", VHQVideoBitrate, VHQAudioBitrate, HQAudioSamplingFrequency, SVGA);

        public static string WMVLowQualityKeepOriginalSize = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2}", LQVideoBitrate, LQAudioBitrate, LQAudioSamplingFrequency, QVGA);
        public static string WMVMediumQualityKeepOriginalSize = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2}", MQVideoBitrate, MQAudioBitrate, MQAudioSamplingFrequency, CIF);
        public static string WMVHighQualityKeepOriginalSize = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2}", HQVideoBitrate, HQAudioBitrate, HQAudioSamplingFrequency, VGA);
        public static string WMVVeryHighQualityKeepOriginalSize = string.Format("-y -vcodec wmv2  -acodec wmav2 -b {0} -ab {1} -ar {2}", VHQVideoBitrate, VHQAudioBitrate, HQAudioSamplingFrequency, SVGA);

    }
}

Sample Usage

 

using System;
using VideoEncoder;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Encoder enc = new Encoder();
        enc.FFmpegPath = Server.MapPath("~/FFmpeg/ffmpeg.exe");
        VideoFile inputv = new VideoFile(Server.MapPath("~/WorkingFolder/SourceVideo.wmv"));
        string outputVPath = Server.MapPath("~/WorkingFolder/OutputVideo.flv");
        string saveThumbnailTo = Server.MapPath("~/WorkingFolder/OutputVideoThumbnail.jpg");
        
        // to get video thumbnail call
        enc.GetVideoThumbnail(inputv,saveThumbnailTo);


        // to encode video call
        EncodedVideo encoded = enc.EncodeVideo(inputv, QuickVideoEncodingCommands.FLVVeryHighQualityKeepOriginalSize, outputVPath, true);
        if (encoded.Success)
        {
            Response.Write(encoded.ThumbnailPath);
            Response.Write("
"); Response.Write(encoded.EncodedVideoPath); Response.Write("
"); Response.Write(encoded.EncodingLog); } else { Response.Write(encoded.EncodingLog); } } }

This project borrowed some code from http://jasonjano.wordpress.com/2010/02/09/a-simple-c-wrapper-for-ffmpeg/

 

Extract default user agent from opera mini and novarra c#

 

public static string GetUa(HttpRequest hr)
    {
        try
        {
            string visitorBrowser = hr.UserAgent.ToString();
            string originalBrowser = hr.ServerVariables["X-OperaMini-Phone-UA"];
            string anotherOriginalBrowser = hr.ServerVariables["X-Device-User-Agent"]; //novarra
            
            if (!String.IsNullOrEmpty(originalBrowser))
            {
                return "OPERAMINI " + originalBrowser;
            }
            else
            {
                if (!String.IsNullOrEmpty(anotherOriginalBrowser))
                {
                    return "NOVARRA " + anotherOriginalBrowser;
                }
                else
                {
                    return visitorBrowser;
                }
            }
        }
        catch
        {
            return "No UA Found";
        }
    }

 

C# Website Screenshot Generator AKA Get Screenshot of Webpage With Asp.net C#

Before I wrote below C# wrapper I've looked around for a C# code to get screenshot of a web site or url. Although there are many web services provides website screenshot service none of them are free!

I've found http://smallsharptools.com/Projects/WebPreview it works fine and author used windows forms Webbrowser control but there is a problem with it. Webbrowser control uses internet explorer to render pages and if there is any JavaScript prompt on the page you are trying to render it doesn't work. You also have no way of disabling plug-ins and JavaScript. (See http://nolovelust.com/post/Generate-website-screenshotthumbnail-with-net-webbrowser-control-on-c-aspnet-website.aspx for hack to disable JavaScript)

Next candidate was NirSoft's SiteShoter it is nice little application with command line support but it too uses internet explorer to get screenshot of websites.

I finally found CutyCapt, it uses QT Webkit to render web pages and packs everything in to a single file with command line support.

After couple of hours work I ended up a c# wrapper for CutyCapt. Works like a charm Smile.

  • It caches Thumbnails for given hours.
  • It has 3 different thumbnail sizes but you can add as many as you want.
  • It can keep aspect ratio of thumbnails.
  • You can even start your own website screenshot service with it Tongue out

Unlike some paid website screenshot services claim about free website screenshot tools like mine

  • Development & Testing Cost is 0
  • It is not buggy, even if there is a bug it can be fixed as all the code is open source
  • Is not time-consuming and FREE!

To get started download  CutyCapt and my CutyCaptWrapper.zip (4.46 kb), put CutyCapt in to App_Data folder

There is one problem i couldn't fix with this code. If CutyCapt crashes it takes whole site down with it. Having said that, I've been using it on a production site since 2 months and didn't have any problems.

Please see Contribution to C# Website Screenshot Generator AKA Get Screenshot of Webpage With Asp.net C# for updates by Colarado State University Web team

 

Usage

CutyCaptWrapper ccw = new CutyCaptWrapper();
Response.Write(ccw.GetScreenShot("http://bbc.co.uk"));

 Or

<img src="<%=new CutyCaptWrapper().GetScreenShot("http://bbc.co.uk")%>" alt="">

 

 CutyCaptWrapper.cs

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;

public class CutyCaptWrapper
{
    /// 
    /// 1 - small
    /// 2 - medium
    /// 3 - large
    /// 
    public int ThumbNailSize { get; set; }
    public bool ThumbKeepAspectRatio { get; set; }
    public int ThumbExpiryTimeInHours { get; set; }
    public string ScreenShotPath { get; set; }
    public string CutyCaptPath { get; set; }
    //public string CutyCaptWorkingDirectory { get; set; }
    public string CutyCaptDefaultArguments { get; set; }
    private int ThumbWidth { get; set; }
    private int ThumbHeight { get; set; }

    public CutyCaptWrapper()
    {
        //default values
        ThumbNailSize = 1;
        ThumbKeepAspectRatio = false;
        ThumbExpiryTimeInHours = 168; //1 week
        ScreenShotPath = HttpContext.Current.Server.MapPath("~/ThumbCache/"); // must be within the web root
        CutyCaptPath = HttpContext.Current.Server.MapPath("~/App_Data/CutyCapt.exe"); // must be within the web root
        //CutyCaptWorkingDirectory = HttpContext.Current.Server.MapPath("~/App_Data/");
        CutyCaptDefaultArguments = " --max-wait=10000 --out-format=png --javascript=off --java=off --plugins=off --js-can-open-windows=off --js-can-access-clipboard=off --private-browsing=on";

    }
    /// 
    /// Checks if there is a cached screenshot of the website and returns url path to thumbnail of the website in order to use ase html image element source
    /// Usage example: <img src="<%=CutyCaptWrapper().GetScreenShot("http://google.com")%>" alt="">
    /// 
    public string GetScreenShot(string url)
    {
        if (IsURLValid(url))
        {

            if (!Directory.Exists(ScreenShotPath))
            {
                Directory.CreateDirectory(ScreenShotPath);
            }
            //set thumbnail sizes
            SetThumbnailSize();
            string ScreenShotFileName = ScreenShotPath + GetScreenShotFileName(url);
            string ScreenShotThumbnailFileName = ScreenShotPath + GetScreenShotThumbnailFileName(ScreenShotFileName, ThumbWidth, ThumbHeight);
            string RunArguments = " --url=" + url + " --out=" + ScreenShotFileName + CutyCaptDefaultArguments;

            FileInfo ScreenShotThumbnailFileNameInfo = new FileInfo(ScreenShotThumbnailFileName);

            if (!ScreenShotThumbnailFileNameInfo.Exists || ScreenShotThumbnailFileNameInfo.CreationTime < DateTime.Now.AddHours(-ThumbExpiryTimeInHours))
            {
          
                    ProcessStartInfo info = new ProcessStartInfo(CutyCaptPath, RunArguments);
                    info.UseShellExecute = false;
                    info.RedirectStandardInput = true;
                    info.RedirectStandardError = true;
                    info.RedirectStandardOutput = true;
                    info.CreateNoWindow = true;
                    //info.WorkingDirectory = CutyCaptWorkingDirectory;
                    using (Process scr = Process.Start(info))
                    {
                        //string output = scr.StandardOutput.ReadToEnd();
                        scr.WaitForExit();
                        ThumbnailCreate(ScreenShotFileName, ScreenShotThumbnailFileName, ThumbWidth, ThumbHeight, ThumbKeepAspectRatio);
                        //delete original file
                        File.Delete(ScreenShotFileName);
                        //return output;
                    }
            }
            return GetRelativeUri(ScreenShotThumbnailFileName);
        }
        else
        {
            return "Wrong URL";
        }
    }
    private void ThumbnailCreate(string sourceFilePath, string outFilePath, int NewWidth, int MaxHeight, bool keepAspectRatio)
    {
        using (Image FullsizeImage = Image.FromFile(sourceFilePath))
        {
            int NewHeight = MaxHeight;
            if (keepAspectRatio)
            {
                NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
                if (NewHeight > MaxHeight)
                {
                    NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
                    NewHeight = MaxHeight;
                }
            }
            using (Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero))
            {
                NewImage.Save(outFilePath, ImageFormat.Png);
            }
        }
    }
    private string GetScreenShotFileName(string url)
    {
        Uri uri = new Uri(url);
        return uri.Host.Replace(".", "_") + uri.LocalPath.Replace("/", "_") + ".png";
    }
    private string GetScreenShotThumbnailFileName(string sourceFilename, int width, int height)
    {
        FileInfo sourceFile = new FileInfo(sourceFilename);
        string shortFilename = sourceFile.Name;
        string ext = Path.GetExtension(shortFilename);
        string replacementEnding = String.Format("{0}x{1}", width, height) + ext;
        return shortFilename.Replace(ext, replacementEnding);
    }
    private string GetRelativeUri(string pathToFile)
    {
        string rootPath = HttpContext.Current.Server.MapPath("~");
        return pathToFile.Replace(rootPath, "").Replace(@"\", "/");
    }
    private bool IsURLValid(string url)
    {
        string strRegex = "^(https?://)"
+ "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //user@
+ @"(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP- 199.194.52.184
+ "|" // allows either IP or domain
+ @"([0-9a-z_!~*'()-]+\.)*" // tertiary domain(s)- www.
+ @"([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // second level domain
+ "[a-z]{2,6})" // first level domain- .com or .museum
+ "(:[0-9]{1,4})?" // port number- :80
+ "((/?)|" // a slash isn't required if there is no file name
+ "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
Regex re = new Regex(strRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase);

if (re.IsMatch(url))
return (true);
else
return (false);
} private void SmallThumbnail() { ThumbWidth = 200; ThumbHeight = 150; } private void MediumThumbnail() { ThumbWidth = 240; ThumbHeight = 190; } private void LargeThumbnail() { ThumbWidth = 320; ThumbHeight = 270; } private void SetThumbnailSize() { if (ThumbNailSize == 1) { SmallThumbnail(); } if (ThumbNailSize == 2) { MediumThumbnail(); } if (ThumbNailSize == 3) { LargeThumbnail(); } else { ThumbNailSize = 1; } } }

Generate transparent PNG with c#

private Bitmap CreateLogo(string subdomain)
{

    Bitmap objBmpImage = new Bitmap(1, 1);
    int intWidth = 0;
    int intHeight = 0;
    Font objFont = new Font("Arial", 13, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Pixel);
    Graphics objGraphics = Graphics.FromImage(objBmpImage);
    intWidth = (int)objGraphics.MeasureString(subdomain, objFont).Width;
    intHeight = (int)objGraphics.MeasureString(subdomain, objFont).Height;
    objBmpImage = new Bitmap(objBmpImage, new Size(intWidth, intHeight));
    objGraphics = Graphics.FromImage(objBmpImage);
    objGraphics.Clear(Color.Transparent);
    objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    objGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
    objGraphics.DrawString(subdomain, objFont, new SolidBrush(Color.FromArgb(255, 255, 255)), 0, 0);
    objGraphics.Flush();
    return (objBmpImage);

}

C# .Net Image Resizer Helper Class

Below class have 5 methods

ResizeFromByteArray, ResizeFromStreamAddWaterMarkAddWaterMarkWithQualitySetting and ImageCodecInfo.

Method names pretty self explanatory and i use it quite a lot to re-size image files on the flay or add watermark to uploads.

Here is the class ImageResizer.cs

 

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;


    public class ImageResize
    {
        public static byte[] ResizeFromByteArray(int MaxSideSize, Byte[] byteArrayIn, string fileName)
        {
            byte[] byteArray = null;  // really make this an error gif
            MemoryStream ms = new MemoryStream(byteArrayIn);
            byteArray = ImageResize.ResizeFromStream(MaxSideSize, ms, fileName);

            return byteArray;
        }
        public static byte[] ResizeFromStream(int MaxSideSize, Stream Buffer, string fileName)
        {
            byte[] byteArray = null;  // really make this an error gif 

            try
            {

                Bitmap bitMap = new Bitmap(Buffer);
                int intOldWidth = bitMap.Width;
                int intOldHeight = bitMap.Height;

                int intNewWidth;
                int intNewHeight;

                int intMaxSide;

                if (intOldWidth >= intOldHeight)
                {
                    intMaxSide = intOldWidth;
                }
                else
                {
                    intMaxSide = intOldHeight;
                }

                if (intMaxSide > MaxSideSize)
                {
                    //set new width and height
                    double dblCoef = MaxSideSize / (double)intMaxSide;
                    intNewWidth = Convert.ToInt32(dblCoef * intOldWidth);
                    intNewHeight = Convert.ToInt32(dblCoef * intOldHeight);
                }
                else
                {
                    intNewWidth = intOldWidth;
                    intNewHeight = intOldHeight;
                }

                Size ThumbNailSize = new Size(intNewWidth, intNewHeight);
                System.Drawing.Image oImg = System.Drawing.Image.FromStream(Buffer);
                System.Drawing.Image oThumbNail = new Bitmap(ThumbNailSize.Width, ThumbNailSize.Height);

                Graphics oGraphic = Graphics.FromImage(oThumbNail);
                oGraphic.CompositingQuality = CompositingQuality.HighQuality;
                oGraphic.SmoothingMode = SmoothingMode.HighQuality;
                oGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
                Rectangle oRectangle = new Rectangle
                    (0, 0, ThumbNailSize.Width, ThumbNailSize.Height);

                oGraphic.DrawImage(oImg, oRectangle);

                MemoryStream ms = new MemoryStream();
                oThumbNail.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                oGraphic.Dispose();
                oImg.Dispose();
                ms.Close();
                ms.Dispose();
            }
            catch (Exception)
            {
                int newSize = MaxSideSize - 20;
                Bitmap bitMap = new Bitmap(newSize, newSize);
                Graphics g = Graphics.FromImage(bitMap);
                g.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, newSize, newSize));

                Font font = new Font("Courier", 8);
                SolidBrush solidBrush = new SolidBrush(Color.Red);
                g.DrawString("Failed File", font, solidBrush, 10, 5);
                g.DrawString(fileName, font, solidBrush, 10, 50);

                MemoryStream ms = new MemoryStream();
                bitMap.Save(ms, ImageFormat.Jpeg);
                byteArray = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteArray, 0, Convert.ToInt32(ms.Length));

                ms.Close();
                ms.Dispose();
                bitMap.Dispose();
                solidBrush.Dispose();
                g.Dispose();
                font.Dispose();

            }
            return byteArray;
        }
        public static byte[] AddWaterMark(Byte[] byteArrayIn, string watermarkText, Brush brushcolor)
        {
            byte[] byteArray = null;
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image img = System.Drawing.Image.FromStream(ms);

            ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
            Encoder myEncoder =Encoder.Quality;
            EncoderParameters myEncoderParameters = new EncoderParameters(1);
            EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 75L);
            myEncoderParameters.Param[0] = myEncoderParameter;

            Graphics gr = Graphics.FromImage(img);
            gr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            gr.DrawString(watermarkText, new Font("Tahoma", 10), brushcolor, new Point(0, 0));

            MemoryStream output = new MemoryStream();
            img.Save(output, jgpEncoder, myEncoderParameters);
            byteArray = new byte[output.Length];
            output.Position = 0;
            output.Read(byteArray, 0, Convert.ToInt32(output.Length));
            return byteArray;
        }
        public static byte[] AddWaterMarkWithQualitySetting(Byte[] byteArrayIn, string watermarkText, Brush brushcolor)
        {
            byte[] byteArray = null;
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image img = System.Drawing.Image.FromStream(ms);

            ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
            Encoder myEncoder = Encoder.Quality;
            EncoderParameters myEncoderParameters = new EncoderParameters(1);
            EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 75L); //%75
            myEncoderParameters.Param[0] = myEncoderParameter;

            Graphics gr = Graphics.FromImage(img);
            gr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            gr.DrawString(watermarkText, new Font("Tahoma", 10), brushcolor, new Point(0, 0));

            MemoryStream output = new MemoryStream();
            img.Save(output, jgpEncoder, myEncoderParameters);
            byteArray = new byte[output.Length];
            output.Position = 0;
            output.Read(byteArray, 0, Convert.ToInt32(output.Length));
            return byteArray;
        }
        private static ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
    }