Browse Source

decode bitmaps at a specified size.

pull/3890/head
Dan Walmsley 6 years ago
parent
commit
ba75735848
  1. 12
      src/Avalonia.Visuals/Media/Imaging/Bitmap.cs
  2. 11
      src/Avalonia.Visuals/Media/Imaging/BitmapDecodeOptions.cs
  3. 5
      src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
  4. 19
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  5. 23
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  6. 18
      src/Skia/Avalonia.Skia/SkiaSharpExtensions.cs
  7. 11
      src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

12
src/Avalonia.Visuals/Media/Imaging/Bitmap.cs

@ -31,6 +31,18 @@ namespace Avalonia.Media.Imaging
PlatformImpl = RefCountable.Create(factory.LoadBitmap(stream));
}
public Bitmap(Stream stream, BitmapDecodeOptions decodeOptions)
{
IPlatformRenderInterface factory = AvaloniaLocator.Current.GetService<IPlatformRenderInterface>();
PlatformImpl = RefCountable.Create(factory.LoadBitmap(stream, decodeOptions));
}
public Bitmap(string file, BitmapDecodeOptions decodeOptions)
{
IPlatformRenderInterface factory = AvaloniaLocator.Current.GetService<IPlatformRenderInterface>();
PlatformImpl = RefCountable.Create(factory.LoadBitmap(file, decodeOptions));
}
/// <summary>
/// Initializes a new instance of the <see cref="Bitmap"/> class.
/// </summary>

11
src/Avalonia.Visuals/Media/Imaging/BitmapDecodeOptions.cs

@ -0,0 +1,11 @@
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Media.Imaging
{
public struct BitmapDecodeOptions
{
public PixelSize DecodePixelSize { get; set; }
public BitmapInterpolationMode InterpolationMode { get; set; }
}
}

5
src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Avalonia.Media;
using Avalonia.Media.Imaging;
namespace Avalonia.Platform
{
@ -84,6 +85,10 @@ namespace Avalonia.Platform
/// <returns>An <see cref="IWriteableBitmapImpl"/>.</returns>
IWriteableBitmapImpl CreateWriteableBitmap(PixelSize size, Vector dpi, PixelFormat? format = null);
IBitmapImpl LoadBitmap(string fileName, BitmapDecodeOptions decodeOptions);
IBitmapImpl LoadBitmap(Stream stream, BitmapDecodeOptions decodeOptions);
/// <summary>
/// Loads a bitmap implementation from a file..
/// </summary>

19
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -123,29 +123,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);
}
}
/// <inheritdoc />
public void DrawBitmap(IRef<IBitmapImpl> source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect)
{

23
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using Avalonia.OpenGL;
using Avalonia.Platform;
using SkiaSharp;
@ -77,6 +78,28 @@ namespace Avalonia.Skia
return new StreamGeometryImpl();
}
public IBitmapImpl LoadBitmap(string fileName, BitmapDecodeOptions decodeOptions)
{
using (var stream = File.OpenRead(fileName))
{
return LoadBitmap(stream, decodeOptions);
}
}
public unsafe IBitmapImpl LoadBitmap(Stream stream, BitmapDecodeOptions decodeOptions)
{
var skBitmap = SKBitmap.Decode(stream);
skBitmap = skBitmap.Resize(new SKImageInfo(decodeOptions.DecodePixelSize.Width, decodeOptions.DecodePixelSize.Height), decodeOptions.InterpolationMode.ToSKFilterQuality());
fixed (byte* p = skBitmap.Bytes)
{
IntPtr ptr = (IntPtr)p;
return LoadBitmap(PixelFormat.Bgra8888, ptr, new PixelSize(skBitmap.Width, skBitmap.Height), new Vector(96, 96), skBitmap.RowBytes);
}
}
/// <inheritdoc />
public IBitmapImpl LoadBitmap(Stream stream)
{

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

11
src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

@ -7,6 +7,7 @@ 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 SharpDX.DirectWrite;
using GlyphRun = Avalonia.Media.GlyphRun;
@ -194,6 +195,16 @@ namespace Avalonia.Direct2D1
return new WicBitmapImpl(format, data, size, dpi, stride);
}
public IBitmapImpl LoadBitmap(string fileName, BitmapDecodeOptions decodeOptions)
{
throw new NotImplementedException();
}
public IBitmapImpl LoadBitmap(Stream stream, BitmapDecodeOptions decodeOptions)
{
throw new NotImplementedException();
}
public IGlyphRunImpl CreateGlyphRun(GlyphRun glyphRun, out double width)
{
var glyphTypeface = (GlyphTypefaceImpl)glyphRun.GlyphTypeface.PlatformImpl;

Loading…
Cancel
Save