c# - 使用 SharpAvi 将图像转换为视频

标签 c#

我正在使用 SharpAvi .dll 将一系列图像转换为视频,一切看起来都很好,但是当我尝试在 Windows Media Player 中播放视频时,我只看到黑屏一秒钟,没有其他内容。

这是我写的代码,(frames是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();
}

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

最佳答案

所以,我发现了错误:

行:

        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);
            }
        }
    }

关于c# - 使用 SharpAvi 将图像转换为视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50001791/

相关文章:

c# - 有两个相同的数组是否需要双倍的内存?

c# - 调试不起作用

c# - 如何将属性绑定(bind)到另一个类的属性(没有 UI 控件)?

c# - 如何在不使用 Interop 的情况下将 VBA 代码注入(inject) Excel .xlsm?

c# - 线段搜索的最佳数据结构是什么?

c# - 何时在实例类上使用静态类的指南?

c# - 尽管发生了未处理的异常,但控制台应用程序已退出,代码为 0 (0x0)

c# - 如何使用 LINQ 将行转换为列来旋转数据

c# - C#中如何从字符串中获取数字

c# - Json.NET + VerificationException 操作可能会破坏运行时的稳定性