瀏覽代碼

High quality scaling for layer previews and recent file previews

Equbuxu 3 年之前
父節點
當前提交
4728bac4b6

+ 27 - 0
PixiEditor/Helpers/Converters/WidthToBitmapScalingModeConverter.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Media;
+
+namespace PixiEditor.Helpers.Converters
+{
+    internal class WidthToBitmapScalingModeConverter : SingleInstanceMultiValueConverter<WidthToBitmapScalingModeConverter>
+    {
+        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+        {
+            int? pixelWidth = values[0] as int?;
+            double? actualWidth = values[1] as double?;
+            if (pixelWidth == null || actualWidth == null)
+                return DependencyProperty.UnsetValue;
+            double zoomLevel = actualWidth.Value / pixelWidth.Value;
+            if (zoomLevel < 1)
+                return BitmapScalingMode.HighQuality;
+            return BitmapScalingMode.NearestNeighbor;
+        }
+
+        public override object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 3 - 1
PixiEditor/Models/Controllers/SurfaceRenderer.cs

@@ -12,6 +12,7 @@ namespace PixiEditor.Models.Controllers
         public SKSurface BackingSurface { get; private set; }
         public WriteableBitmap FinalBitmap { get; private set; }
         private SKPaint BlendingPaint { get; } = new SKPaint() { BlendMode = SKBlendMode.SrcOver };
+        private SKPaint HighQualityResizePaint { get; } = new SKPaint() { FilterQuality = SKFilterQuality.High };
         public SurfaceRenderer(int width, int height)
         {
             FinalBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Pbgra32, null);
@@ -23,6 +24,7 @@ namespace PixiEditor.Models.Controllers
         {
             BackingSurface.Dispose();
             BlendingPaint.Dispose();
+            HighQualityResizePaint.Dispose();
         }
 
         public void Draw(Surface otherSurface, byte opacity)
@@ -31,7 +33,7 @@ namespace PixiEditor.Models.Controllers
             FinalBitmap.Lock();
             BlendingPaint.Color = new SKColor(255, 255, 255, opacity);
             using (var snapshot = otherSurface.SkiaSurface.Snapshot())
-                BackingSurface.Canvas.DrawImage(snapshot, new SKRect(0, 0, FinalBitmap.PixelWidth, FinalBitmap.PixelHeight));
+                BackingSurface.Canvas.DrawImage(snapshot, new SKRect(0, 0, FinalBitmap.PixelWidth, FinalBitmap.PixelHeight), HighQualityResizePaint);
             FinalBitmap.AddDirtyRect(new Int32Rect(0, 0, FinalBitmap.PixelWidth, FinalBitmap.PixelHeight));
             FinalBitmap.Unlock();
         }

+ 8 - 1
PixiEditor/Views/Dialogs/HelloTherePopup.xaml

@@ -119,7 +119,14 @@
                                                 Style="{StaticResource DarkRoundButton}"
                                                 x:Name="fileButton">
                                             <Grid Width="100" Height="100">
-                                                <Image Source="{Binding PreviewBitmap}" RenderOptions.BitmapScalingMode="NearestNeighbor" Margin="20"/>
+                                                <Image Source="{Binding PreviewBitmap}" x:Name="image" Margin="20">
+                                                    <RenderOptions.BitmapScalingMode>
+                                                        <MultiBinding Converter="{converters:WidthToBitmapScalingModeConverter}">
+                                                            <Binding Path="PreviewBitmap.PixelWidth"/>
+                                                            <Binding ElementName="image" Path="ActualWidth"/>
+                                                        </MultiBinding>
+                                                    </RenderOptions.BitmapScalingMode>
+                                                </Image>
                                                 <Border Grid.Row="1" Height="8" Width="8" x:Name="extensionBorder" Margin="5"
                                                         Background="{Binding FileExtension, Converter={converters:FileExtensionToColorConverter}}" 
                                                         VerticalAlignment="Bottom" HorizontalAlignment="Right">

+ 8 - 2
PixiEditor/Views/UserControls/Layers/LayerGroupControl.xaml

@@ -36,8 +36,14 @@
                     <StackPanel Grid.Row="1" Orientation="Horizontal" Grid.Column="0" HorizontalAlignment="Left">
                         <Border Width="30" Height="30" BorderThickness="1" BorderBrush="Black" Background="{StaticResource MainColor}"
                            Margin="5, 0, 10, 0">
-                            <Image Source="{Binding PreviewImage, ElementName=groupControl}" Stretch="Uniform" Width="20" Height="20" 
-                       RenderOptions.BitmapScalingMode="NearestNeighbor"/>
+                            <Image Source="{Binding PreviewImage, ElementName=groupControl}" Stretch="Uniform" Width="20" Height="20">
+                                <RenderOptions.BitmapScalingMode>
+                                    <MultiBinding Converter="{converters:WidthToBitmapScalingModeConverter}">
+                                        <Binding Path="PreviewImage.PixelWidth" ElementName="groupControl"/>
+                                        <Binding RelativeSource="{RelativeSource Mode=Self}" Path="ActualWidth"/>
+                                    </MultiBinding>
+                                </RenderOptions.BitmapScalingMode>
+                            </Image>
                         </Border>
                         <userControls:EditableTextBlock
                     FontSize="16"

+ 9 - 1
PixiEditor/Views/UserControls/PlainLayerView.xaml

@@ -4,9 +4,17 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:PixiEditor.Views.UserControls"
+             xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters"
              mc:Ignorable="d" 
              x:Name="uc"
              d:DesignHeight="450" d:DesignWidth="800">
     <Image x:Name="image" Width="{Binding Width, ElementName=uc}" Height="{Binding Height, ElementName=uc}" 
-           RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Uniform"/>
+           Stretch="Uniform">
+        <RenderOptions.BitmapScalingMode>
+            <MultiBinding Converter="{converters:WidthToBitmapScalingModeConverter}">
+                <Binding RelativeSource="{RelativeSource Mode=Self}" Path="Source.PixelWidth"/>
+                <Binding RelativeSource="{RelativeSource Mode=Self}" Path="ActualWidth"/>
+            </MultiBinding>
+        </RenderOptions.BitmapScalingMode>
+    </Image>
 </UserControl>