使用SharpAvi将图像转换为视频

时间:2018-04-24 12:31:49

标签: c#

我正在使用SharpAvi .dll将一系列图像转换为视频,一切看起来都不错,但是当我尝试在Windows媒体播放器中播放视频时,我只得到黑屏一秒钟,没有别的。

这是我写的代码,(框架是一个图像列表base64)

private void CreateMovie(List<string> frames)
{
    int width = 320;
    int height = 240;
    var framRate = 2;

    var writer = new AviWriter("C:\\test.avi")
    {
        FramesPerSecond = framRate,
        EmitIndex1 = true
    };

    var stream = writer.AddVideoStream();
    stream.Width = width;
    stream.Height = height;
    stream.Codec = KnownFourCCs.Codecs.DivX;
    stream.BitsPerPixel = BitsPerPixel.Bpp32;

    foreach (var frame in frames)
    {
        byte[] arr = Convert.FromBase64String(frame);
        stream.WriteFrame(true, arr, 0, arr.Length);
    }

    writer.Close();
}

我看不出错误是什么。有没有人有想法?

1 个答案:

答案 0 :(得分:1)

所以,我发现了错误:

行:

        stream.Codec = KnownFourCCs.Codecs.DivX; 

应该是:

        stream.Codec = KnownFourCCs.Codecs.Uncompressed;  

并且视频的所有帧应与视频大小相同,为此,我使用了这段代码:

        foreach (var frame in frames)
        {
            byte[] arr = Convert.FromBase64String(frame);
            var bm = ToBitmap(arr);
            var rbm = ReduceBitmap(bm, 320, 240);

            byte[] fr = BitmapToByteArray(rbm);

            stream.WriteFrame(true, fr, 0, fr.Length);
        }  

这里是辅助函数:

    public Bitmap ToBitmap(byte[] byteArrayIn)
    {
        var ms = new MemoryStream(byteArrayIn);
        var returnImage = Image.FromStream(ms);
        var bitmap = new Bitmap(returnImage);

        return bitmap;
    }

    public Bitmap ReduceBitmap(Bitmap original, int reducedWidth, int reducedHeight)
    {
        var reduced = new Bitmap(reducedWidth, reducedHeight);
        using (var dc = Graphics.FromImage(reduced))
        {
            dc.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            dc.DrawImage(original, new Rectangle(0, 0, reducedWidth, reducedHeight), new Rectangle(0, 0, original.Width, original.Height), GraphicsUnit.Pixel);
        }

        return reduced;
    }

    public static byte[] BitmapToByteArray(Bitmap bitmap)
    {
        BitmapData bmpdata = null;

        try
        {
            bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
            int numbytes = bmpdata.Stride * bitmap.Height;
            byte[] bytedata = new byte[numbytes];
            IntPtr ptr = bmpdata.Scan0;

            Marshal.Copy(ptr, bytedata, 0, numbytes);

            return bytedata;
        }
        finally
        {
            if (bmpdata != null)
            {
                bitmap.UnlockBits(bmpdata);
            }
        }
    }