diff --git a/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs b/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs
index 42ee35133e..86e2700c04 100644
--- a/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs
+++ b/src/Avalonia.Visuals/Media/Imaging/Bitmap.cs
@@ -11,6 +11,46 @@ namespace Avalonia.Media.Imaging
///
public class Bitmap : IBitmap
{
+ ///
+ /// Loads a Bitmap from a stream and decodes at the desired width. Aspect ratio is maintained.
+ /// This is more efficient than loading and then resizing.
+ ///
+ /// The stream to read the bitmap from. This can be any supported image format.
+ /// The desired width of the resulting bitmap.
+ /// The to use should any scaling be required.
+ /// An instance of the class.
+ public static Bitmap DecodeToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ IPlatformRenderInterface factory = AvaloniaLocator.Current.GetService();
+ return new Bitmap(factory.LoadBitmapToWidth(stream, width, interpolationMode));
+ }
+
+ ///
+ /// Loads a Bitmap from a stream and decodes at the desired height. Aspect ratio is maintained.
+ /// This is more efficient than loading and then resizing.
+ ///
+ /// The stream to read the bitmap from. This can be any supported image format.
+ /// The desired height of the resulting bitmap.
+ /// The to use should any scaling be required.
+ /// An instance of the class.
+ public static Bitmap DecodeToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ IPlatformRenderInterface factory = AvaloniaLocator.Current.GetService();
+ return new Bitmap(factory.LoadBitmapToHeight(stream, height, interpolationMode));
+ }
+
+ ///
+ /// Creates a Bitmap scaled to a specified size from the current bitmap.
+ ///
+ /// The destination size.
+ /// The to use should any scaling be required.
+ /// An instance of the class.
+ public Bitmap CreateScaledBitmap(PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ IPlatformRenderInterface factory = AvaloniaLocator.Current.GetService();
+ return new Bitmap(factory.ResizeBitmap(PlatformImpl.Item, destinationSize, interpolationMode));
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -39,7 +79,7 @@ namespace Avalonia.Media.Imaging
{
PlatformImpl = impl.Clone();
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -48,7 +88,7 @@ namespace Avalonia.Media.Imaging
{
PlatformImpl = RefCountable.Create(impl);
}
-
+
///
public virtual void Dispose()
{
diff --git a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
index a0102a0f33..ba30272b7b 100644
--- a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
+++ b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
@@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.IO;
using Avalonia.Media;
+using Avalonia.Media.Imaging;
+using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Platform
{
@@ -87,17 +89,37 @@ namespace Avalonia.Platform
///
/// Loads a bitmap implementation from a file..
///
- /// The filename of the bitmap.
+ /// The filename of the bitmap.
/// An .
IBitmapImpl LoadBitmap(string fileName);
///
/// Loads a bitmap implementation from a file..
///
- /// The stream to read the bitmap from.
+ /// The stream to read the bitmap from.
/// An .
IBitmapImpl LoadBitmap(Stream stream);
+ ///
+ /// Loads a bitmap implementation from a stream to a specified width maintaining aspect ratio.
+ ///
+ /// The stream to read the bitmap from.
+ /// The desired width of the resulting bitmap.
+ /// The to use should resizing be required.
+ /// An .
+ IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality);
+
+ ///
+ /// Loads a bitmap implementation from a stream to a specified height maintaining aspect ratio.
+ ///
+ /// The stream to read the bitmap from.
+ /// The desired height of the resulting bitmap.
+ /// The to use should resizing be required.
+ /// An .
+ IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality);
+
+ IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality);
+
///
/// Loads a bitmap implementation from a pixels in memory.
///
diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index 44bbf0590a..26fdb08a4b 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -124,29 +124,12 @@ namespace Avalonia.Skia
Color = new SKColor(255, 255, 255, (byte)(255 * opacity * _currentOpacity))
})
{
- paint.FilterQuality = GetInterpolationMode(bitmapInterpolationMode);
+ paint.FilterQuality = bitmapInterpolationMode.ToSKFilterQuality();
drawableImage.Draw(this, s, d, paint);
}
}
- private static SKFilterQuality GetInterpolationMode(BitmapInterpolationMode interpolationMode)
- {
- switch (interpolationMode)
- {
- case BitmapInterpolationMode.LowQuality:
- return SKFilterQuality.Low;
- case BitmapInterpolationMode.MediumQuality:
- return SKFilterQuality.Medium;
- case BitmapInterpolationMode.HighQuality:
- return SKFilterQuality.High;
- case BitmapInterpolationMode.Default:
- return SKFilterQuality.None;
- default:
- throw new ArgumentOutOfRangeException(nameof(interpolationMode), interpolationMode, null);
- }
- }
-
///
public void DrawBitmap(IRef source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect)
{
diff --git a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs
index 9222c5ac61..e84c7e34de 100644
--- a/src/Skia/Avalonia.Skia/ImmutableBitmap.cs
+++ b/src/Skia/Avalonia.Skia/ImmutableBitmap.cs
@@ -1,7 +1,11 @@
using System;
using System.IO;
+using System.Runtime.CompilerServices;
+using System.Security.Cryptography;
+using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Skia.Helpers;
+using Avalonia.Visuals.Media.Imaging;
using SkiaSharp;
namespace Avalonia.Skia
@@ -36,6 +40,75 @@ namespace Avalonia.Skia
}
}
+ public ImmutableBitmap(ImmutableBitmap src, PixelSize destinationSize, BitmapInterpolationMode interpolationMode)
+ {
+ SKImageInfo info = new SKImageInfo(destinationSize.Width, destinationSize.Height, SKColorType.Bgra8888);
+ SKImage output = SKImage.Create(info);
+ src._image.ScalePixels(output.PeekPixels(), interpolationMode.ToSKFilterQuality());
+
+ _image = output;
+
+ PixelSize = new PixelSize(_image.Width, _image.Height);
+
+ // TODO: Skia doesn't have an API for DPI.
+ Dpi = new Vector(96, 96);
+ }
+
+ public ImmutableBitmap(Stream stream, int decodeSize, bool horizontal, BitmapInterpolationMode interpolationMode)
+ {
+ using (var skStream = new SKManagedStream(stream))
+ using (var codec = SKCodec.Create(skStream))
+ {
+ var info = codec.Info;
+
+ // get the scale that is nearest to what we want (eg: jpg returned 512)
+ var supportedScale = codec.GetScaledDimensions(horizontal ? ((float)decodeSize / info.Width) : ((float)decodeSize / info.Height));
+
+ // decode the bitmap at the nearest size
+ var nearest = new SKImageInfo(supportedScale.Width, supportedScale.Height);
+ var bmp = SKBitmap.Decode(codec, nearest);
+
+ // now scale that to the size that we want
+ var realScale = horizontal ? ((double)info.Height / info.Width) : ((double)info.Width / info.Height);
+
+ SKImageInfo desired;
+
+
+ if (horizontal)
+ {
+ desired = new SKImageInfo(decodeSize, (int)(realScale * decodeSize));
+ }
+ else
+ {
+ desired = new SKImageInfo((int)(realScale * decodeSize), decodeSize);
+ }
+
+ if (bmp.Width != desired.Width || bmp.Height != desired.Height)
+ {
+ if (bmp.Height != bmp.Width)
+ {
+
+ }
+ var scaledBmp = bmp.Resize(desired, interpolationMode.ToSKFilterQuality());
+ bmp.Dispose();
+ bmp = scaledBmp;
+ }
+
+ _image = SKImage.FromBitmap(bmp);
+ bmp.Dispose();
+
+ if (_image == null)
+ {
+ throw new ArgumentException("Unable to load bitmap from provided data");
+ }
+
+ PixelSize = new PixelSize(_image.Width, _image.Height);
+
+ // TODO: Skia doesn't have an API for DPI.
+ Dpi = new Vector(96, 96);
+ }
+ }
+
///
/// Create immutable bitmap from given pixel data copy.
///
diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
index 2fee282860..0bc5dd56ac 100644
--- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
+++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
@@ -1,13 +1,16 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.IO;
+using System.IO;
+using System.Security.Cryptography;
using System.Linq;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Media;
+using Avalonia.Media.Imaging;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Imaging;
using Avalonia.Platform;
+using Avalonia.Visuals.Media.Imaging;
using SkiaSharp;
namespace Avalonia.Skia
@@ -57,12 +60,6 @@ namespace Avalonia.Skia
return new StreamGeometryImpl();
}
- ///
- public IBitmapImpl LoadBitmap(Stream stream)
- {
- return new ImmutableBitmap(stream);
- }
-
///
public IBitmapImpl LoadBitmap(string fileName)
{
@@ -72,12 +69,43 @@ namespace Avalonia.Skia
}
}
+ ///
+ public IBitmapImpl LoadBitmap(Stream stream)
+ {
+ return new ImmutableBitmap(stream);
+ }
+
///
public IBitmapImpl LoadBitmap(PixelFormat format, IntPtr data, PixelSize size, Vector dpi, int stride)
{
return new ImmutableBitmap(size, dpi, stride, format, data);
}
+ ///
+ public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ return new ImmutableBitmap(stream, width, true, interpolationMode);
+ }
+
+ ///
+ public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ return new ImmutableBitmap(stream, height, false, interpolationMode);
+ }
+
+ ///
+ public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ if (bitmapImpl is ImmutableBitmap ibmp)
+ {
+ return new ImmutableBitmap(ibmp, destinationSize, interpolationMode);
+ }
+ else
+ {
+ throw new Exception("Invalid source bitmap type.");
+ }
+ }
+
///
public IRenderTargetBitmapImpl CreateRenderTargetBitmap(PixelSize size, Vector dpi)
{
diff --git a/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs b/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs
index 459486f784..6375f74c59 100644
--- a/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs
+++ b/src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs
@@ -1,12 +1,30 @@
using System;
using Avalonia.Media;
using Avalonia.Platform;
+using Avalonia.Visuals.Media.Imaging;
using SkiaSharp;
namespace Avalonia.Skia
{
public static class SkiaSharpExtensions
{
+ public static SKFilterQuality ToSKFilterQuality(this BitmapInterpolationMode interpolationMode)
+ {
+ switch (interpolationMode)
+ {
+ case BitmapInterpolationMode.LowQuality:
+ return SKFilterQuality.Low;
+ case BitmapInterpolationMode.MediumQuality:
+ return SKFilterQuality.Medium;
+ case BitmapInterpolationMode.HighQuality:
+ return SKFilterQuality.High;
+ case BitmapInterpolationMode.Default:
+ return SKFilterQuality.None;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(interpolationMode), interpolationMode, null);
+ }
+ }
+
public static SKPoint ToSKPoint(this Point p)
{
return new SKPoint((float)p.X, (float)p.Y);
diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
index 96bd96341c..c4c0541d53 100644
--- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
+++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
@@ -7,7 +7,9 @@ using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Direct2D1.Media;
using Avalonia.Direct2D1.Media.Imaging;
using Avalonia.Media;
+using Avalonia.Media.Imaging;
using Avalonia.Platform;
+using Avalonia.Visuals.Media.Imaging;
using SharpDX.DirectWrite;
using GlyphRun = Avalonia.Media.GlyphRun;
using TextAlignment = Avalonia.Media.TextAlignment;
@@ -179,16 +181,38 @@ namespace Avalonia.Direct2D1
public IGeometryImpl CreateRectangleGeometry(Rect rect) => new RectangleGeometryImpl(rect);
public IStreamGeometryImpl CreateStreamGeometry() => new StreamGeometryImpl();
+ ///
public IBitmapImpl LoadBitmap(string fileName)
{
return new WicBitmapImpl(fileName);
}
+ ///
public IBitmapImpl LoadBitmap(Stream stream)
{
return new WicBitmapImpl(stream);
}
+ ///
+ public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ return new WicBitmapImpl(stream, width, true, interpolationMode);
+ }
+
+ ///
+ public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ return new WicBitmapImpl(stream, height, false, interpolationMode);
+ }
+
+ ///
+ public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ // https://github.com/sharpdx/SharpDX/issues/959 blocks implementation.
+ throw new NotImplementedException();
+ }
+
+ ///
public IBitmapImpl LoadBitmap(PixelFormat format, IntPtr data, PixelSize size, Vector dpi, int stride)
{
return new WicBitmapImpl(format, data, size, dpi, stride);
diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs
index f5159b1f84..743abddd1e 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Security.Cryptography;
using Avalonia.Win32.Interop;
using SharpDX.WIC;
using APixelFormat = Avalonia.Platform.PixelFormat;
@@ -14,6 +15,26 @@ namespace Avalonia.Direct2D1.Media
{
private BitmapDecoder _decoder;
+ private static BitmapInterpolationMode ConvertInterpolationMode(Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode interpolationMode)
+ {
+ switch (interpolationMode)
+ {
+ case Visuals.Media.Imaging.BitmapInterpolationMode.Default:
+ return BitmapInterpolationMode.Fant;
+
+ case Visuals.Media.Imaging.BitmapInterpolationMode.LowQuality:
+ return BitmapInterpolationMode.NearestNeighbor;
+
+ case Visuals.Media.Imaging.BitmapInterpolationMode.MediumQuality:
+ return BitmapInterpolationMode.Fant;
+
+ default:
+ case Visuals.Media.Imaging.BitmapInterpolationMode.HighQuality:
+ return BitmapInterpolationMode.HighQualityCubic;
+
+ }
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -27,6 +48,12 @@ namespace Avalonia.Direct2D1.Media
}
}
+ private WicBitmapImpl(Bitmap bmp)
+ {
+ WicImpl = bmp;
+ Dpi = new Vector(96, 96);
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -60,7 +87,7 @@ namespace Avalonia.Direct2D1.Media
size.Height,
pixelFormat.Value.ToWic(),
BitmapCreateCacheOption.CacheOnLoad);
- WicImpl.SetResolution(dpi.X, dpi.Y);
+
Dpi = dpi;
}
@@ -84,6 +111,43 @@ namespace Avalonia.Direct2D1.Media
}
}
+ public WicBitmapImpl(Stream stream, int decodeSize, bool horizontal, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode interpolationMode)
+ {
+ _decoder = new BitmapDecoder(Direct2D1Platform.ImagingFactory, stream, DecodeOptions.CacheOnLoad);
+
+ var frame = _decoder.GetFrame(0);
+
+ // now scale that to the size that we want
+ var realScale = horizontal ? ((double)frame.Size.Height / frame.Size.Width) : ((double)frame.Size.Width / frame.Size.Height);
+
+ PixelSize desired;
+
+ if (horizontal)
+ {
+ desired = new PixelSize(decodeSize, (int)(realScale * decodeSize));
+ }
+ else
+ {
+ desired = new PixelSize((int)(realScale * decodeSize), decodeSize);
+ }
+
+ if (frame.Size.Width != desired.Width || frame.Size.Height != desired.Height)
+ {
+ using (var scaler = new BitmapScaler(Direct2D1Platform.ImagingFactory))
+ {
+ scaler.Initialize(frame, desired.Width, desired.Height, ConvertInterpolationMode(interpolationMode));
+
+ WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, scaler, BitmapCreateCacheOption.CacheOnLoad);
+ }
+ }
+ else
+ {
+ WicImpl = new Bitmap(Direct2D1Platform.ImagingFactory, frame, BitmapCreateCacheOption.CacheOnLoad);
+ }
+
+ Dpi = new Vector(96, 96);
+ }
+
public override Vector Dpi { get; }
public override PixelSize PixelSize => WicImpl.Size.ToAvalonia();
diff --git a/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs b/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs
index 5e29893946..d9fb5e03fc 100644
--- a/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs
+++ b/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs
@@ -4,6 +4,7 @@ using System.IO;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.UnitTests;
+using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Benchmarks
{
@@ -65,6 +66,21 @@ namespace Avalonia.Benchmarks
throw new NotImplementedException();
}
+ public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ throw new NotImplementedException();
+ }
+
public IFontManagerImpl CreateFontManager()
{
return new MockFontManagerImpl();
diff --git a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs
index afdf95430b..5f2c6d1a69 100644
--- a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs
+++ b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using Avalonia.Media;
using Avalonia.Platform;
+using Avalonia.Visuals.Media.Imaging;
using Moq;
namespace Avalonia.UnitTests
@@ -69,6 +70,21 @@ namespace Avalonia.UnitTests
return Mock.Of();
}
+ public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ return Mock.Of();
+ }
+
+ public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ return Mock.Of();
+ }
+
+ public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ return Mock.Of();
+ }
+
public IBitmapImpl LoadBitmap(
PixelFormat format,
IntPtr data,
diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs
index 019eefe1a6..558a9a5968 100644
--- a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs
+++ b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs
@@ -4,6 +4,7 @@ using System.IO;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.UnitTests;
+using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Visuals.UnitTests.VisualTree
{
@@ -83,6 +84,21 @@ namespace Avalonia.Visuals.UnitTests.VisualTree
throw new NotImplementedException();
}
+ public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality)
+ {
+ throw new NotImplementedException();
+ }
+
class MockStreamGeometry : IStreamGeometryImpl
{
private MockStreamGeometryContext _impl = new MockStreamGeometryContext();