Browse Source

Initial implementation of BitmapScaleMode

pull/1762/head
Benedikt Schroeder 8 years ago
parent
commit
b108ffcab4
  1. 1
      .gitignore
  2. 42
      Avalonia.sln
  3. 19
      src/Avalonia.Controls/Image.cs
  4. 9
      src/Avalonia.Visuals/Media/DrawingContext.cs
  5. 2
      src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs
  6. 32
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs

1
.gitignore

@ -182,3 +182,4 @@ project.lock.json
## BenchmarkDotNet
##################
BenchmarkDotNet.Artifacts/
/src/ImageInterpRepro

42
Avalonia.sln

@ -187,6 +187,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Designer.HostApp.N
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.UnitTests", "tests\Avalonia.Skia.UnitTests\Avalonia.Skia.UnitTests.csproj", "{E1240B49-7B4B-4371-A00E-068778C5CF0B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ImageInterpRepro", "src\ImageInterpRepro\ImageInterpRepro.csproj", "{54A1062E-126E-4813-98A7-8DB9D949CD93}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@ -2514,6 +2516,46 @@ Global
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|NetCoreOnly.Build.0 = Release|Any CPU
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|x86.ActiveCfg = Release|Any CPU
{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|x86.Build.0 = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|NetCoreOnly.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|NetCoreOnly.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|iPhone.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|NetCoreOnly.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|NetCoreOnly.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|x86.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.AppStore|x86.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|iPhone.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|NetCoreOnly.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|NetCoreOnly.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|x86.ActiveCfg = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Debug|x86.Build.0 = Debug|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|Any CPU.Build.0 = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|iPhone.ActiveCfg = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|iPhone.Build.0 = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|NetCoreOnly.ActiveCfg = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|NetCoreOnly.Build.0 = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|x86.ActiveCfg = Release|Any CPU
{54A1062E-126E-4813-98A7-8DB9D949CD93}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

19
src/Avalonia.Controls/Image.cs

@ -7,6 +7,8 @@ using Avalonia.Media.Imaging;
namespace Avalonia.Controls
{
using Avalonia.Visuals.Media.Imaging;
/// <summary>
/// Displays a <see cref="Bitmap"/> image.
/// </summary>
@ -24,10 +26,17 @@ namespace Avalonia.Controls
public static readonly StyledProperty<Stretch> StretchProperty =
AvaloniaProperty.Register<Image, Stretch>(nameof(Stretch), Stretch.Uniform);
/// <summary>
/// Defines the <see cref="ScalingMode"/> property.
/// </summary>
public static readonly StyledProperty<BitmapScalingMode> ScalingModeProperty =
AvaloniaProperty.Register<Image, BitmapScalingMode>(nameof(BitmapScalingMode));
static Image()
{
AffectsRender(SourceProperty);
AffectsRender(StretchProperty);
AffectsRender(ScalingModeProperty);
}
/// <summary>
@ -48,6 +57,12 @@ namespace Avalonia.Controls
set { SetValue(StretchProperty, value); }
}
public BitmapScalingMode ScalingMode
{
get { return (BitmapScalingMode)GetValue(ScalingModeProperty); }
set { SetValue(ScalingModeProperty, value); }
}
/// <summary>
/// Renders the control.
/// </summary>
@ -68,7 +83,7 @@ namespace Avalonia.Controls
Rect sourceRect = new Rect(sourceSize)
.CenterRect(new Rect(destRect.Size / scale));
context.DrawImage(source, 1, sourceRect, destRect);
context.DrawImage(source, 1, sourceRect, destRect, ScalingMode);
}
}
@ -100,4 +115,4 @@ namespace Avalonia.Controls
}
}
}
}
}

9
src/Avalonia.Visuals/Media/DrawingContext.cs

@ -5,6 +5,8 @@ using Avalonia.Platform;
namespace Avalonia.Media
{
using Avalonia.Visuals.Media.Imaging;
public sealed class DrawingContext : IDisposable
{
private int _currentLevel;
@ -68,11 +70,12 @@ namespace Avalonia.Media
/// <param name="opacity">The opacity to draw with.</param>
/// <param name="sourceRect">The rect in the image to draw.</param>
/// <param name="destRect">The rect in the output to draw to.</param>
public void DrawImage(IBitmap source, double opacity, Rect sourceRect, Rect destRect)
/// <param name="scalingMode"></param>
public void DrawImage(IBitmap source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode scalingMode = default)
{
Contract.Requires<ArgumentNullException>(source != null);
PlatformImpl.DrawImage(source.PlatformImpl, opacity, sourceRect, destRect);
PlatformImpl.DrawImage(source.PlatformImpl, opacity, sourceRect, destRect, scalingMode);
}
/// <summary>
@ -309,4 +312,4 @@ namespace Avalonia.Media
return pen?.Brush != null && pen.Thickness > 0;
}
}
}
}

2
src/Avalonia.Visuals/Platform/IDrawingContextImpl.cs

@ -33,7 +33,7 @@ namespace Avalonia.Platform
/// <param name="sourceRect">The rect in the image to draw.</param>
/// <param name="destRect">The rect in the output to draw to.</param>
/// <param name="scalingMode">Controls</param>
void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode scalingMode = BitmapScalingMode.LowQuality);
void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode scalingMode = default);
/// <summary>
/// Draws a bitmap image.

32
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -14,6 +14,8 @@ using SkiaSharp;
namespace Avalonia.Skia
{
using Avalonia.Visuals.Media.Imaging;
/// <summary>
/// Skia based drawing context.
/// </summary>
@ -95,24 +97,44 @@ namespace Avalonia.Skia
}
/// <inheritdoc />
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect)
public void DrawImage(IRef<IBitmapImpl> source, double opacity, Rect sourceRect, Rect destRect, BitmapScalingMode scalingMode)
{
var drawableImage = (IDrawableBitmapImpl) source.Item;
var drawableImage = (IDrawableBitmapImpl)source.Item;
var s = sourceRect.ToSKRect();
var d = destRect.ToSKRect();
using (var paint =
new SKPaint {Color = new SKColor(255, 255, 255, (byte) (255 * opacity * _currentOpacity))})
new SKPaint
{
Color = new SKColor(255, 255, 255, (byte)(255 * opacity * _currentOpacity))
})
{
paint.FilterQuality = GetInterpolationMode(scalingMode);
drawableImage.Draw(this, s, d, paint);
}
}
private static SKFilterQuality GetInterpolationMode(BitmapScalingMode scalingMode)
{
switch (scalingMode)
{
case BitmapScalingMode.LowQuality:
return SKFilterQuality.Low;
case BitmapScalingMode.MediumQuality:
return SKFilterQuality.Medium;
case BitmapScalingMode.HighQuality:
return SKFilterQuality.High;
default:
throw new ArgumentOutOfRangeException(nameof(scalingMode), scalingMode, null);
}
}
/// <inheritdoc />
public void DrawImage(IRef<IBitmapImpl> source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect)
{
PushOpacityMask(opacityMask, opacityMaskRect);
DrawImage(source, 1, new Rect(0, 0, source.Item.PixelWidth, source.Item.PixelHeight), destRect);
DrawImage(source, 1, new Rect(0, 0, source.Item.PixelWidth, source.Item.PixelHeight), destRect, default(BitmapScalingMode));
PopOpacityMask();
}
@ -686,4 +708,4 @@ namespace Avalonia.Skia
}
}
}
}
}

Loading…
Cancel
Save