mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2025-01-18 12:36:44 +00:00
Replaced System.Drawing.Common with SkiaSharp
This commit is contained in:
parent
c96fdc490a
commit
f464be430b
5 changed files with 34 additions and 57 deletions
|
@ -3,6 +3,7 @@
|
|||
using FFMpegCore.Enums;
|
||||
using FFMpegCore.Extensions.System.Drawing.Common;
|
||||
using FFMpegCore.Pipes;
|
||||
using SkiaSharp;
|
||||
|
||||
var inputPath = "/path/to/input";
|
||||
var outputPath = "/path/to/output";
|
||||
|
@ -79,7 +80,7 @@ await FFMpegArguments
|
|||
FFMpeg.PosterWithAudio(inputPath, inputAudioPath, outputPath);
|
||||
// or
|
||||
#pragma warning disable CA1416
|
||||
using var image = Image.FromFile(inputImagePath);
|
||||
using var image = SKBitmap.Decode(inputImagePath);
|
||||
image.AddAudio(inputAudioPath, outputPath);
|
||||
#pragma warning restore CA1416
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
using System.Drawing;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FFMpegCore.Extensions.System.Drawing.Common
|
||||
{
|
||||
public static class BitmapExtensions
|
||||
{
|
||||
public static bool AddAudio(this Image poster, string audio, string output)
|
||||
public static bool AddAudio(this SKBitmap poster, string audio, string output)
|
||||
{
|
||||
var destination = $"{Environment.TickCount}.png";
|
||||
poster.Save(destination);
|
||||
using (var fileStream = File.OpenWrite(destination))
|
||||
{
|
||||
poster.Encode(fileStream, SKEncodedImageFormat.Png, default); // PNG does not respect the quality parameter
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return FFMpeg.PosterWithAudio(destination, audio, output);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
using FFMpegCore.Pipes;
|
||||
using FFMpegCore.Pipes;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FFMpegCore.Extensions.System.Drawing.Common
|
||||
{
|
||||
|
@ -13,44 +11,24 @@ public class BitmapVideoFrameWrapper : IVideoFrame, IDisposable
|
|||
|
||||
public string Format { get; private set; }
|
||||
|
||||
public Bitmap Source { get; private set; }
|
||||
public SKBitmap Source { get; private set; }
|
||||
|
||||
public BitmapVideoFrameWrapper(Bitmap bitmap)
|
||||
public BitmapVideoFrameWrapper(SKBitmap bitmap)
|
||||
{
|
||||
Source = bitmap ?? throw new ArgumentNullException(nameof(bitmap));
|
||||
Format = ConvertStreamFormat(bitmap.PixelFormat);
|
||||
Format = ConvertStreamFormat(bitmap.ColorType);
|
||||
}
|
||||
|
||||
public void Serialize(Stream stream)
|
||||
{
|
||||
var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat);
|
||||
|
||||
try
|
||||
{
|
||||
var buffer = new byte[data.Stride * data.Height];
|
||||
Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
|
||||
stream.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Source.UnlockBits(data);
|
||||
}
|
||||
var data = Source.Bytes;
|
||||
stream.Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public async Task SerializeAsync(Stream stream, CancellationToken token)
|
||||
{
|
||||
var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat);
|
||||
|
||||
try
|
||||
{
|
||||
var buffer = new byte[data.Stride * data.Height];
|
||||
Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
|
||||
await stream.WriteAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Source.UnlockBits(data);
|
||||
}
|
||||
var data = Source.Bytes;
|
||||
await stream.WriteAsync(data, 0, data.Length, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -58,27 +36,20 @@ public void Dispose()
|
|||
Source.Dispose();
|
||||
}
|
||||
|
||||
private static string ConvertStreamFormat(PixelFormat fmt)
|
||||
private static string ConvertStreamFormat(SKColorType fmt)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case PixelFormat.Format16bppGrayScale:
|
||||
return "gray16le";
|
||||
case PixelFormat.Format16bppRgb555:
|
||||
return "bgr555le";
|
||||
case PixelFormat.Format16bppRgb565:
|
||||
return "bgr565le";
|
||||
case PixelFormat.Format24bppRgb:
|
||||
return "bgr24";
|
||||
case PixelFormat.Format32bppArgb:
|
||||
case SKColorType.Gray8:
|
||||
return "gray8";
|
||||
case SKColorType.Bgra8888:
|
||||
return "bgra";
|
||||
case PixelFormat.Format32bppPArgb:
|
||||
//This is not really same as argb32
|
||||
return "argb";
|
||||
case PixelFormat.Format32bppRgb:
|
||||
case SKColorType.Rgb888x:
|
||||
return "rgb";
|
||||
case SKColorType.Rgba8888:
|
||||
return "rgba";
|
||||
case PixelFormat.Format48bppRgb:
|
||||
return "rgb48le";
|
||||
case SKColorType.Rgb565:
|
||||
return "rgb565";
|
||||
default:
|
||||
throw new NotSupportedException($"Not supported pixel format {fmt}");
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Drawing;
|
||||
using FFMpegCore.Pipes;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FFMpegCore.Extensions.System.Drawing.Common
|
||||
{
|
||||
|
@ -14,7 +15,7 @@ public static class FFMpegImage
|
|||
/// <param name="streamIndex">Selected video stream index.</param>
|
||||
/// <param name="inputFileIndex">Input file index</param>
|
||||
/// <returns>Bitmap with the requested snapshot.</returns>
|
||||
public static Bitmap Snapshot(string input, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
|
||||
public static SKBitmap Snapshot(string input, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
|
||||
{
|
||||
var source = FFProbe.Analyse(input);
|
||||
var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
|
||||
|
@ -26,8 +27,8 @@ public static Bitmap Snapshot(string input, Size? size = null, TimeSpan? capture
|
|||
.ProcessSynchronously();
|
||||
|
||||
ms.Position = 0;
|
||||
using var bitmap = new Bitmap(ms);
|
||||
return bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), bitmap.PixelFormat);
|
||||
using var bitmap = SKBitmap.Decode(ms);
|
||||
return bitmap.Copy();
|
||||
}
|
||||
/// <summary>
|
||||
/// Saves a 'png' thumbnail to an in-memory bitmap
|
||||
|
@ -38,7 +39,7 @@ public static Bitmap Snapshot(string input, Size? size = null, TimeSpan? capture
|
|||
/// <param name="streamIndex">Selected video stream index.</param>
|
||||
/// <param name="inputFileIndex">Input file index</param>
|
||||
/// <returns>Bitmap with the requested snapshot.</returns>
|
||||
public static async Task<Bitmap> SnapshotAsync(string input, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
|
||||
public static async Task<SKBitmap> SnapshotAsync(string input, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
|
||||
{
|
||||
var source = await FFProbe.AnalyseAsync(input).ConfigureAwait(false);
|
||||
var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildSnapshotArguments(input, source, size, captureTime, streamIndex, inputFileIndex);
|
||||
|
@ -50,7 +51,7 @@ await arguments
|
|||
.ProcessAsynchronously();
|
||||
|
||||
ms.Position = 0;
|
||||
return new Bitmap(ms);
|
||||
return SKBitmap.Decode(ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue