committed by
GitHub
7 changed files with 166 additions and 10 deletions
@ -0,0 +1,96 @@ |
|||
using System; |
|||
using Avalonia.Visuals.Media.Imaging; |
|||
|
|||
namespace Avalonia.Media.Imaging |
|||
{ |
|||
/// <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(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 as IBitmap)?.Dispose(); |
|||
} |
|||
|
|||
public Size Size { |
|||
get |
|||
{ |
|||
if (Source == null) |
|||
return Size.Empty; |
|||
if (SourceRect.IsEmpty) |
|||
return Source.Size; |
|||
return SourceRect.Size.ToSizeWithDpi((Source as IBitmap).Dpi); |
|||
} |
|||
} |
|||
|
|||
public void Draw(DrawingContext context, Rect sourceRect, Rect destRect, BitmapInterpolationMode bitmapInterpolationMode) |
|||
{ |
|||
if (Source == null) |
|||
return; |
|||
var topLeft = SourceRect.TopLeft.ToPointWithDpi((Source as IBitmap).Dpi); |
|||
Source.Draw(context, sourceRect.Translate(new Vector(topLeft.X, topLeft.Y)), destRect, bitmapInterpolationMode); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue