committed by
GitHub
4 changed files with 148 additions and 1 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