28 changed files with 505 additions and 7 deletions
@ -0,0 +1,107 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="ImageTests.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Direct2D1.RenderTests.Controls |
||||
|
{ |
||||
|
using System.IO; |
||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting; |
||||
|
using Perspex.Controls; |
||||
|
using Perspex.Layout; |
||||
|
using Perspex.Media; |
||||
|
using Perspex.Media.Imaging; |
||||
|
|
||||
|
[TestClass] |
||||
|
public class ImageTests : TestBase |
||||
|
{ |
||||
|
private Bitmap bitmap; |
||||
|
|
||||
|
public ImageTests() |
||||
|
: base(@"Controls\Image") |
||||
|
{ |
||||
|
this.bitmap = new Bitmap(Path.Combine(this.OutputPath, "test.png")); |
||||
|
} |
||||
|
|
||||
|
[TestMethod] |
||||
|
public void Image_Stretch_None() |
||||
|
{ |
||||
|
Decorator target = new Decorator |
||||
|
{ |
||||
|
Padding = new Thickness(20, 8), |
||||
|
Width = 200, |
||||
|
Height = 200, |
||||
|
Content = new Image |
||||
|
{ |
||||
|
Background = Brushes.Red, |
||||
|
Source = this.bitmap, |
||||
|
Stretch = Stretch.None, |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
this.RenderToFile(target); |
||||
|
this.CompareImages(); |
||||
|
} |
||||
|
|
||||
|
[TestMethod] |
||||
|
public void Image_Stretch_Fill() |
||||
|
{ |
||||
|
Decorator target = new Decorator |
||||
|
{ |
||||
|
Padding = new Thickness(20, 8), |
||||
|
Width = 200, |
||||
|
Height = 200, |
||||
|
Content = new Image |
||||
|
{ |
||||
|
Background = Brushes.Red, |
||||
|
Source = this.bitmap, |
||||
|
Stretch = Stretch.Fill, |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
this.RenderToFile(target); |
||||
|
this.CompareImages(); |
||||
|
} |
||||
|
|
||||
|
[TestMethod] |
||||
|
public void Image_Stretch_Uniform() |
||||
|
{ |
||||
|
Decorator target = new Decorator |
||||
|
{ |
||||
|
Padding = new Thickness(20, 8), |
||||
|
Width = 200, |
||||
|
Height = 200, |
||||
|
Content = new Image |
||||
|
{ |
||||
|
Background = Brushes.Red, |
||||
|
Source = this.bitmap, |
||||
|
Stretch = Stretch.Uniform, |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
this.RenderToFile(target); |
||||
|
this.CompareImages(); |
||||
|
} |
||||
|
|
||||
|
[TestMethod] |
||||
|
public void Image_Stretch_UniformToFill() |
||||
|
{ |
||||
|
Decorator target = new Decorator |
||||
|
{ |
||||
|
Padding = new Thickness(20, 8), |
||||
|
Width = 200, |
||||
|
Height = 200, |
||||
|
Content = new Image |
||||
|
{ |
||||
|
Background = Brushes.Red, |
||||
|
Source = this.bitmap, |
||||
|
Stretch = Stretch.UniformToFill, |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
this.RenderToFile(target); |
||||
|
this.CompareImages(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,115 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="Image.cs" company="Steven Kirk">
|
||||
|
// Copyright 2013 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls |
||||
|
{ |
||||
|
using System; |
||||
|
using Perspex.Media; |
||||
|
using Perspex.Media.Imaging; |
||||
|
|
||||
|
public class Image : Control |
||||
|
{ |
||||
|
public static readonly PerspexProperty<Bitmap> SourceProperty = |
||||
|
PerspexProperty.Register<Image, Bitmap>("Source"); |
||||
|
|
||||
|
public static readonly PerspexProperty<Stretch> StretchProperty = |
||||
|
PerspexProperty.Register<Image, Stretch>("Stretch", Stretch.Uniform); |
||||
|
|
||||
|
public Bitmap Source |
||||
|
{ |
||||
|
get { return this.GetValue(SourceProperty); } |
||||
|
set { this.SetValue(SourceProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public Stretch Stretch |
||||
|
{ |
||||
|
get { return (Stretch)this.GetValue(StretchProperty); } |
||||
|
set { this.SetValue(StretchProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public override void Render(IDrawingContext drawingContext) |
||||
|
{ |
||||
|
Brush background = this.Background; |
||||
|
Bitmap source = this.Source; |
||||
|
|
||||
|
if (background != null) |
||||
|
{ |
||||
|
drawingContext.FillRectange(background, new Rect(this.ActualSize)); |
||||
|
} |
||||
|
|
||||
|
if (source != null) |
||||
|
{ |
||||
|
Rect viewPort = new Rect(this.ActualSize); |
||||
|
Size sourceSize = new Size(source.PixelWidth, source.PixelHeight); |
||||
|
Vector scale = CalculateScaling(this.ActualSize, sourceSize, this.Stretch); |
||||
|
Size scaledSize = sourceSize * scale; |
||||
|
Rect destRect = viewPort |
||||
|
.Center(new Rect(scaledSize)) |
||||
|
.Intersect(viewPort); |
||||
|
Rect sourceRect = new Rect(sourceSize) |
||||
|
.Center(new Rect(destRect.Size / scale)); |
||||
|
|
||||
|
drawingContext.DrawImage(source, 1, sourceRect, destRect); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static Vector CalculateScaling(Size availableSize, Size imageSize, Stretch stretch) |
||||
|
{ |
||||
|
double scaleX = 1; |
||||
|
double scaleY = 1; |
||||
|
|
||||
|
if (stretch != Stretch.None) |
||||
|
{ |
||||
|
scaleX = availableSize.Width / imageSize.Width; |
||||
|
scaleY = availableSize.Height / imageSize.Height; |
||||
|
|
||||
|
switch (stretch) |
||||
|
{ |
||||
|
case Stretch.Uniform: |
||||
|
scaleX = scaleY = Math.Min(scaleX, scaleY); |
||||
|
break; |
||||
|
case Stretch.UniformToFill: |
||||
|
scaleX = scaleY = Math.Max(scaleX, scaleY); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return new Vector(scaleX, scaleY); |
||||
|
} |
||||
|
|
||||
|
protected override Size MeasureOverride(Size availableSize) |
||||
|
{ |
||||
|
double width = 0; |
||||
|
double height = 0; |
||||
|
Vector scale = new Vector(); |
||||
|
|
||||
|
if (this.Source != null) |
||||
|
{ |
||||
|
width = this.Source.PixelWidth; |
||||
|
height = this.Source.PixelHeight; |
||||
|
|
||||
|
if (this.Width > 0) |
||||
|
{ |
||||
|
availableSize = new Size(this.Width, availableSize.Height); |
||||
|
} |
||||
|
|
||||
|
if (this.Height > 0) |
||||
|
{ |
||||
|
availableSize = new Size(availableSize.Width, this.Height); |
||||
|
} |
||||
|
|
||||
|
scale = CalculateScaling(availableSize, new Size(width, height), this.Stretch); |
||||
|
} |
||||
|
|
||||
|
return new Size(width * scale.X, height * scale.Y); |
||||
|
} |
||||
|
|
||||
|
protected override Size ArrangeOverride(Size finalSize) |
||||
|
{ |
||||
|
return finalSize; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="IBitmap.cs" company="Steven Kirk">
|
||||
|
// Copyright 2013 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Media.Imaging |
||||
|
{ |
||||
|
public interface IBitmap |
||||
|
{ |
||||
|
int PixelHeight { get; } |
||||
|
|
||||
|
int PixelWidth { get; } |
||||
|
|
||||
|
void Save(string fileName); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,72 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="Vector.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex |
||||
|
{ |
||||
|
using System.Globalization; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines a vector.
|
||||
|
/// </summary>
|
||||
|
public struct Vector |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The X vector.
|
||||
|
/// </summary>
|
||||
|
private double x; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The Y vector.
|
||||
|
/// </summary>
|
||||
|
private double y; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Vector"/> structure.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The X vector.</param>
|
||||
|
/// <param name="y">The Y vector.</param>
|
||||
|
public Vector(double x, double y) |
||||
|
{ |
||||
|
this.x = x; |
||||
|
this.y = y; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the X vector.
|
||||
|
/// </summary>
|
||||
|
public double X |
||||
|
{ |
||||
|
get { return this.x; } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the Y vector.
|
||||
|
/// </summary>
|
||||
|
public double Y |
||||
|
{ |
||||
|
get { return this.y; } |
||||
|
} |
||||
|
|
||||
|
public static Vector operator +(Vector a, Vector b) |
||||
|
{ |
||||
|
return new Vector(a.x + b.x, a.y + b.y); |
||||
|
} |
||||
|
|
||||
|
public static Vector operator -(Vector a, Vector b) |
||||
|
{ |
||||
|
return new Vector(a.x - b.x, a.y - b.y); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the string representation of the point.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The string representation of the point.</returns>
|
||||
|
public override string ToString() |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, "{0}, {1}", this.x, this.y); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 17 KiB |
Loading…
Reference in new issue