Jason94
Jason94

Reputation: 13620

How can I crop and resize a image?

I'm trying to crop out and resize the head of Steve, the default skin for Minecraft! :-)

But I'm having some problems, I got the cropping down, but the resizing does not work and the image is all blurry :-(

My XAML:

<Image Height="60" Width="60" Name="ProfileImage" Stretch="UniformToFill" />

My code behind:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        System.Drawing.Rectangle cropRect = new System.Drawing.Rectangle(8,8,8,8);
        Bitmap source = System.Drawing.Image.FromFile("steve.png") as Bitmap;
        Bitmap target = new Bitmap(60, 60);

        using(Graphics g = Graphics.FromImage(target))
        {
            g.DrawImage(source, 
                new System.Drawing.Rectangle(0, 0, target.Width, target.Height), 
                cropRect, 
                GraphicsUnit.Pixel);
            g.Dispose();

           ProfileImage.Source = CreateBitmapSourceFromBitmap(target);
        }
    }

    public static BitmapSource CreateBitmapSourceFromBitmap(Bitmap bitmap)
    {
        if (bitmap == null)
            throw new ArgumentNullException("bitmap");

        return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
            bitmap.GetHbitmap(),
            IntPtr.Zero,
            Int32Rect.Empty,
            BitmapSizeOptions.FromEmptyOptions());
    }

Does anyone have a clue? The skin looks like this, and the head portion I want is (8,8,8 (width),8 (height)):

enter image description here

Upvotes: 0

Views: 1572

Answers (2)

Clemens
Clemens

Reputation: 128106

You could do this without any WinForms (System.Drawing) stuff by setting RenderOptions.BitmapScalingMode to NearestNeighbor on the Image control

<Image Height="60" Width="60" Name="ProfileImage" Stretch="UniformToFill"
       RenderOptions.BitmapScalingMode="NearestNeighbor"/>

and using a CroppedBitmap for the Image's Source:

var steve = new BitmapImage(new Uri("steve.png", UriKind.Relative));
ProfileImage.Source = new CroppedBitmap(steve, new Int32Rect(8, 8, 8, 8));

You might even do it entirely in XAML:

<Image Height="60" Width="60" RenderOptions.BitmapScalingMode="NearestNeighbor">
    <Image.Source>
        <CroppedBitmap Source="steve.png" SourceRect="8,8,8,8"/>
    </Image.Source>
</Image>

Upvotes: 2

J...
J...

Reputation: 31453

If you wish to retain the square pixel shape when resizing then you simply need to change the interpolation mode of the Graphics object you are using to do the drawing :

g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

g.DrawImage(source,
            new System.Drawing.Rectangle(0, 0, target.Width, target.Height),
            cropRect,
            GraphicsUnit.Pixel);

Below shows the NearestNeighbor interpolation on the left and the Default (Bilinear) interpolation on the right.

enter image description here

Upvotes: 2

Related Questions