Browse Source

Added functionality to use CroppedBitmap directly in XAML

pull/3589/head
Вадим Мельников 7 years ago
parent
commit
3aab2d5619
  1. 8
      samples/ControlCatalog/Pages/ImagePage.xaml
  2. 18
      samples/ControlCatalog/Pages/ImagePage.xaml.cs
  3. 69
      src/Avalonia.Visuals/Media/Imaging/CroppedBitmap.cs
  4. 3
      src/Avalonia.Visuals/Properties/AssemblyInfo.cs

8
samples/ControlCatalog/Pages/ImagePage.xaml

@ -23,7 +23,7 @@
<DockPanel Grid.Column="1" Grid.Row="1" Margin="16">
<TextBlock DockPanel.Dock="Top" Classes="h3" Margin="0 8">Crop</TextBlock>
<ComboBox Name="bitmapCrop" DockPanel.Dock="Top" SelectedIndex="0" SelectionChanged="BitmapCropChanged">
<ComboBox Name="bitmapCrop" DockPanel.Dock="Top" SelectedIndex="2" SelectionChanged="BitmapCropChanged">
<ComboBoxItem>None</ComboBoxItem>
<ComboBoxItem>Center</ComboBoxItem>
<ComboBoxItem>TopLeft</ComboBoxItem>
@ -31,7 +31,11 @@
<ComboBoxItem>BottomLeft</ComboBoxItem>
<ComboBoxItem>BottomRight</ComboBoxItem>
</ComboBox>
<Image Name="croppedImage"/>
<Image Name="croppedImage">
<Image.Source>
<CroppedBitmap Source="/Assets/delicate-arch-896885_640.jpg" SourceRect="0 0 320 240"/>
</Image.Source>
</Image>
</DockPanel>
<DockPanel Grid.Column="2" Grid.Row="1" Margin="16">

18
samples/ControlCatalog/Pages/ImagePage.xaml.cs

@ -13,7 +13,6 @@ namespace ControlCatalog.Pages
private readonly Image _bitmapImage;
private readonly Image _drawingImage;
private readonly Image _croppedImage;
private readonly IBitmap _croppedBitmapSource;
public ImagePage()
{
@ -21,8 +20,6 @@ namespace ControlCatalog.Pages
_bitmapImage = this.FindControl<Image>("bitmapImage");
_drawingImage = this.FindControl<Image>("drawingImage");
_croppedImage = this.FindControl<Image>("croppedImage");
_croppedBitmapSource = LoadBitmap("avares://ControlCatalog/Assets/delicate-arch-896885_640.jpg");
_croppedImage.Source = new CroppedBitmap(_croppedBitmapSource, default);
}
private void InitializeComponent()
@ -53,15 +50,16 @@ namespace ControlCatalog.Pages
if (_croppedImage != null)
{
var comboxBox = (ComboBox)sender;
_croppedImage.Source = new CroppedBitmap( _croppedBitmapSource, GetCropRect(comboxBox.SelectedIndex));
var croppedBitmap = _croppedImage.Source as CroppedBitmap;
croppedBitmap.SourceRect = GetCropRect(comboxBox.SelectedIndex);
}
}
private PixelRect GetCropRect(int index)
{
var bitmapWidth = _croppedBitmapSource.PixelSize.Width;
var bitmapHeight = _croppedBitmapSource.PixelSize.Height;
var cropSize = new PixelSize(bitmapWidth / 2, bitmapHeight / 2);
var bitmapWidth = 640;
var bitmapHeight = 426;
var cropSize = new PixelSize(320, 240);
return index switch
{
1 => new PixelRect(new PixelPoint((bitmapWidth - cropSize.Width) / 2, (bitmapHeight - cropSize.Width) / 2), cropSize),
@ -73,11 +71,5 @@ namespace ControlCatalog.Pages
};
}
private IBitmap LoadBitmap(string uri)
{
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
return new Bitmap(assets.Open(new Uri(uri)));
}
}
}

69
src/Avalonia.Visuals/Media/Imaging/CroppedBitmap.cs

@ -1,25 +1,77 @@
using System;
using System.Collections.Generic;
using System.Text;
using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Media.Imaging
{
public class CroppedBitmap : IImage, IDisposable
/// <summary>
/// Crops a Bitmap.
/// </summary>
public class CroppedBitmap : AvaloniaObject, IImage, IAffectsRender, IDisposable
{
/// <summary>
/// Defines the <see cref="Source"/> property.
/// </summary>
public static readonly StyledProperty<IImage> SourceProperty =
AvaloniaProperty.Register<CroppedBitmap, IImage>(nameof(Source));
/// <summary>
/// Defines the <see cref="SourceRect"/> property.
/// </summary>
public static readonly StyledProperty<PixelRect> SourceRectProperty =
AvaloniaProperty.Register<CroppedBitmap, PixelRect>(nameof(SourceRect));
public event EventHandler Invalidated;
static CroppedBitmap()
{
SourceRectProperty.Changed.AddClassHandler<CroppedBitmap>((x, e) => x.SourceRectChanged(e));
SourceProperty.Changed.AddClassHandler<CroppedBitmap>((x, e) => x.SourceChanged(e));
}
/// <summary>
/// Gets or sets the source for the bitmap.
/// </summary>
public IImage Source
{
get => GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
/// <summary>
/// Gets or sets the rectangular area that the bitmap is cropped to.
/// </summary>
public PixelRect SourceRect
{
get => GetValue(SourceRectProperty);
set => SetValue(SourceRectProperty, value);
}
public CroppedBitmap()
{
Source = null;
SourceRect = default;
}
public CroppedBitmap(IBitmap source, PixelRect sourceRect)
public CroppedBitmap(IImage source, PixelRect sourceRect)
{
Source = source;
SourceRect = sourceRect;
}
private void SourceChanged(AvaloniaPropertyChangedEventArgs e)
{
if (e.NewValue == null)
return;
if (!(e.NewValue is IBitmap))
throw new ArgumentException("Only IBitmap supported as source");
Invalidated?.Invoke(this, e);
}
private void SourceRectChanged(AvaloniaPropertyChangedEventArgs e) => Invalidated?.Invoke(this, e);
public virtual void Dispose()
{
Source?.Dispose();
(Source as IBitmap)?.Dispose();
}
public Size Size {
@ -29,7 +81,7 @@ namespace Avalonia.Media.Imaging
return Size.Empty;
if (SourceRect.IsEmpty)
return Source.Size;
return SourceRect.Size.ToSizeWithDpi(Source.Dpi);
return SourceRect.Size.ToSizeWithDpi((Source as IBitmap).Dpi);
}
}
@ -37,11 +89,8 @@ namespace Avalonia.Media.Imaging
{
if (Source == null)
return;
var topLeft = SourceRect.TopLeft.ToPointWithDpi(Source.Dpi);
var topLeft = SourceRect.TopLeft.ToPointWithDpi((Source as IBitmap).Dpi);
Source.Draw(context, sourceRect.Translate(new Vector(topLeft.X, topLeft.Y)), destRect, bitmapInterpolationMode);
}
public IBitmap Source { get; }
public PixelRect SourceRect { get; }
}
}

3
src/Avalonia.Visuals/Properties/AssemblyInfo.cs

@ -8,7 +8,8 @@ using Avalonia.Metadata;
[assembly: InternalsVisibleTo("Avalonia.Visuals.UnitTests")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media.Imaging")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia")]
[assembly: InternalsVisibleTo("Avalonia.Direct2D1.RenderTests")]
[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests")]
[assembly: InternalsVisibleTo("Avalonia.Skia.RenderTests")]

Loading…
Cancel
Save