Resizing images with WPF 4.0

Microsoft changed the default behaviour for scaling images with WPF 4.0/.NET 4.0.
They opted for a faster but less accurate scaling algorithm named Linear instead of the default Fant that was used in WPF 3.0.

You can change this behaviour using the RenderOptions.BitmapScalingMode attached property.

<Image Source="Image.png"
    RenderOptions.BitmapScalingMode="HighQuality" />

Microsoft recommends to only use HighQuality if the image’s scaled size will be less that 30-50% of the original size.

The Resizer application will always use HighQuality so that it gives the best image quality for any image.

Using the attached property on images scaled in code using DrawingVisual/RenderTargetBitmap requires a bit of special code.

private static BitmapFrame CreateResizedImage(ImageSource source, int width, int height, int margin)
{
    var rect = new Rect(margin, margin, width - margin * 2, height - margin * 2);

    var group = new DrawingGroup();
    RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
    group.Children.Add(new ImageDrawing(source, rect));

    var drawingVisual = new DrawingVisual();
    using (var drawingContext = drawingVisual.RenderOpen())
        drawingContext.DrawDrawing(group);

    var resizedImage = new RenderTargetBitmap(
        width, height,         // Resized dimensions
        96, 96,                // Default DPI values
        PixelFormats.Default); // Default pixel format
    resizedImage.Render(drawingVisual);

    return BitmapFrame.Create(resizedImage);
}

Width and height contains the margin already, so if the image is scaled to 300px with a margin of 10px then the method will be called with width = 320px and margin = 10px. We can use the DrawingGroup to set the BitmapScalingMode and then add the ImageDrawing to it.

Posted in Uncategorized | Tagged , , | Leave a comment

Resizer

I’ve been working on a little project to demo the features of Vidyano.

It’s used internally to generate the thumbnails for our Wiki. The source code is available on codeplex and the application is deployed as click-once.

I’ll be talking about the specific Vidyano features and the resizing part with WPF 4 in the next blog posts.

Posted in Uncategorized | Tagged , , , | Leave a comment

iRail.be is back online

iRail.be is a website to find train information here in Belgium, it scraped the original complicated website of the NMBS and provided a clean/simple interface to access the information.

More info on the blogpost.

Posted in Uncategorized | Tagged | Leave a comment

Vidyano 2.0 released

I’m proud to announce that our team has finished our next major version of Vidyano.
Build from scratch to optimize everything for the latest .NET 4.0 release and using all latest features of it (MEF, Rx, …).
The User Interface now uses a MVVM based architecture with our Module/Page system on top of it.

You can download it directly from inside Visual Studio using the Extension Manager or at the Visual Studio Gallery Page.

Read more on our blog.

Posted in Uncategorized | Tagged , , , , | 1 Comment

.NET 4.0

Some updated download links for the latest .NET version:

1 Comment

Rails dynamic finders for .NET 4.0

Ruby on Rails allows you to use ‘dynamic’ finders to query the database. This is actually a feature from ActiveRecord to dynamicly use methods which will represent where clauses on the database.

Some examples:

User.find(:first, :conditions => ["name = ?", name])
User.find_by_name(name)

User.find(:all, :conditions => ["city = ?", city])
User.find_all_by_city(city)

User.find(:all, :conditions => ["street = ? AND city IN (?)", street, cities])
User.find_all_by_street_and_city(street, cities)

With .NET 4.0 we have dynamics of our own so I thought why not recreate this feature…

By creating an extension method for IEnumerable<T> and IQueryable<T> each enumerable source can now use the dynamic finder feature

public static class DynamicExtensions
{
    public static dynamic AsDynamic<T>(this IEnumerable<T> source)
    {
        return new DynamicEnumerable<T>(source);
    }

    public static dynamic AsDynamic<T>(this IQueryable<T> source)
    {
        return new DynamicQueryable<T>(source);
    }
}

The Dynamic classes will inherit from DynamicObject to give basic dynamics support.

sealed class DynamicQueryable<T> : DynamicObject
{
    private readonly IQueryable<T> source;

    public DynamicQueryable(IQueryable<T> source)
    {
        this.source = source;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        var match = methodMatcher.Match(binder.Name);
        if (match.Success)
        {
            var properties = match.Groups[2].Value.Split(new[] { "And" }, StringSplitOptions.RemoveEmptyEntries);
            var predicate = BuildExpression<T>(properties, args);

            if (match.Groups[1].Success)
                result = source.Where(predicate);
            else
                result = source.FirstOrDefault(predicate);

            return true;
        }
        return base.TryInvokeMember(binder, args, out result);
    }
}

With the only missing part the BuildExpression method which will create the expression tree:

private static Expression<Func<T, bool>> BuildExpression<T>(string[] properties, object[] args)
{
    if (properties.Length < 1)
       throw new InvalidOperationException("Need to specify at least one property.");
    if (args.Length != properties.Length)
       throw new InvalidOperationException("Method expects " + properties.Length + " parameters and only got " + args.Length + " values.");

    var param = Expression.Parameter(typeof(T), "p");
    var body = Expression.Equal(Expression.Property(param, properties[0]), Expression.Constant(args[0]));
    for (var i = 1; i < properties.Length; i++)
        body = Expression.AndAlso(body, Expression.Equal(Expression.Property(param, properties[i]), Expression.Constant(args[i])));
    return Expression.Lambda<Func<T, bool>>(body, param);
}

And the only difference with the DynamicEnumerable class is that the expression will be compiled to use for the Where/FirstOrDefault.

Full source at pastebin.

Leave a comment

Vidyano Release Candidate

UPDATE: Vidyano 2.0 released

The Vidyano Release Candidate is now available :)

Together with a new website we offer complete support now for any application build with Vidyano, think of it as a Go Live license.

More information (including documentation, tutorials and downloads) at:

http://www.vidyano.com/

Posted in Uncategorized | Tagged | Leave a comment