diff --git a/FFMpegCore.Examples/Program.cs b/FFMpegCore.Examples/Program.cs
index ac4bce5..f926d94 100644
--- a/FFMpegCore.Examples/Program.cs
+++ b/FFMpegCore.Examples/Program.cs
@@ -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
}
diff --git a/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs b/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs
index 14cecaa..b8a0c83 100644
--- a/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs
+++ b/FFMpegCore.Extensions.System.Drawing.Common/BitmapExtensions.cs
@@ -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);
diff --git a/FFMpegCore.Extensions.System.Drawing.Common/BitmapVideoFrameWrapper.cs b/FFMpegCore.Extensions.System.Drawing.Common/BitmapVideoFrameWrapper.cs
index 5462ca2..0439721 100644
--- a/FFMpegCore.Extensions.System.Drawing.Common/BitmapVideoFrameWrapper.cs
+++ b/FFMpegCore.Extensions.System.Drawing.Common/BitmapVideoFrameWrapper.cs
@@ -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}");
}
diff --git a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj
index aafb577..b0d6349 100644
--- a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj
+++ b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs
index f36f83d..8cd0f26 100644
--- a/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs
+++ b/FFMpegCore.Extensions.System.Drawing.Common/FFMpegImage.cs
@@ -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
/// Selected video stream index.
/// Input file index
/// Bitmap with the requested snapshot.
- 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();
}
///
/// Saves a 'png' thumbnail to an in-memory bitmap
@@ -38,7 +39,7 @@ public static Bitmap Snapshot(string input, Size? size = null, TimeSpan? capture
/// Selected video stream index.
/// Input file index
/// Bitmap with the requested snapshot.
- public static async Task SnapshotAsync(string input, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
+ public static async Task 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);
}
}
}