Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 77050

How to resize an image in Xamarin.Forms (iOS, Android and WP)?

$
0
0

Hi all

In my app, there is a registration-page, where the user can register to have access to more functions.
Among other he can load an image, that then is showed as his avatar.
To select an image, I user the media-picker.
The problem was, that the stored images are a lot larger as the avatar (only 71 x 61).
So I had to search a solution, how to downscale an image with correct aspect-ratio to the needed resolution.
I have found an base-example here: https://developer.xamarin.com/samples/xamarin-forms/XamFormsImageResize/
First, thanks to the authors for that example!

As I then had some problems with the iOS-Code and had further needs, I have replaced the code to iOS (with the help of another user) and added some more functionality for my needs (target resolution and calculation of the resize to hold aspect-ratio.)
Now, it works as I need it :sunglasses:

So... as I think (hope), that this may help some other users, I post the code here...

The implementation is very easy:
Just add the .cs-File t your project ad change the name-space in the .cs-file to your namespace.
You don't need to more, as the .cs-file contains #statements for the platform-stuff.

On the registration-page in my app:
- I show first a default-avatar-image (male / female) -> this is loaded from resources.
- The user that can click a button "load another image" and the select one over the media-picker
- The selected image then is scaled over the resizer and showed in an standard-image-object
- If the user tap on register-button and all data are valid, the resized image is submitted to our json-web-service and stored on a SQL-Server

Code-example on my registration-page:

 byte[] resizedImage = ImageResizer.ResizeImage(imageData, iZielBreite, iZielHoehe); // in this byte-array the resized image is given back
 Avatar.Source = ImageSource.FromStream(() => new MemoryStream(resizedImage)); / Show resized Image on an Image

where imageData contains the image that has to be resized (byte[]), iZielBreite is the target-width and iZielHoehe is the target-height.

Code-File (ImageResizer.cs):
Just copy it to a class-file in your shared-code and change namespace MatrixGuide to namespace 'your Namespace':

using System;
using System.Collections.Generic;
using System.Text;

using System;
using System.IO;

// Usings je Platform

#if __IOS__
using System.Drawing;
using UIKit;
using CoreGraphics;
#endif


#if __ANDROID__
using Android.Graphics;
#endif

#if WINDOWS_PHONE
using Microsoft.Phone;
using System.Windows.Media.Imaging;
#endif



namespace MatrixGuide
{
    public static class ImageResizer
    {
        static ImageResizer()
        {
        }


        public static byte[] ResizeImage(byte[] imageData, float width, float height)
        {
#if __IOS__
            return ResizeImageIOS(imageData, width, height);
#endif
#if __ANDROID__
            return ResizeImageAndroid(imageData, width, height);
#endif
#if WINDOWS_PHONE
            return ResizeImageWinPhone(imageData, width, height);
#endif
        }
        //
#if __IOS__

        public static byte[] ResizeImageIOS(byte[] imageData, float width, float height)
        {
            // Load the bitmap
            UIImage originalImage = ImageFromByteArray(imageData);
            //
            var Hoehe = originalImage.Size.Height;
            var Breite = originalImage.Size.Width;
            //
            nfloat ZielHoehe = 0;
            nfloat ZielBreite = 0;
            //

            if (Hoehe > Breite) // Höhe (71 für Avatar) ist Master
            {
                ZielHoehe = height;
                nfloat teiler = Hoehe / height;
                ZielBreite = Breite / teiler;
            }
            else // Breite (61 for Avatar) ist Master
            {
                ZielBreite = width;
                nfloat teiler = Breite / width;
                ZielHoehe = Hoehe / teiler;
            }
            //
            width = (float)ZielBreite;
            height = (float)ZielHoehe;
            //
            UIGraphics.BeginImageContext(new SizeF(width, height));
            originalImage.Draw(new RectangleF(0, 0, width, height));
            var resizedImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
            //
            var bytesImagen = resizedImage.AsJPEG().ToArray();
            resizedImage.Dispose();
            return bytesImagen;
        }
        //
        public static UIKit.UIImage ImageFromByteArray(byte[] data)
        {
            if (data == null)
            {
                return null;
            }
            //
            UIKit.UIImage image;
            try
            {
                image = new UIKit.UIImage(Foundation.NSData.FromArray(data));
            }
            catch (Exception e)
            {
                Console.WriteLine("Image load failed: " + e.Message);
                return null;
            }
            return image;
        }
#endif
        //
#if __ANDROID__
        public static byte[] ResizeImageAndroid(byte[] imageData, float width, float height)
        {
            // Load the bitmap 
            Bitmap originalImage = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length);
            //
            float ZielHoehe = 0;
            float ZielBreite = 0;
            //
            var Hoehe = originalImage.Height;
            var Breite = originalImage.Width;
            //
            if (Hoehe > Breite) // Höhe (71 für Avatar) ist Master
            {
                ZielHoehe = height;
                float teiler = Hoehe / height;
                ZielBreite = Breite / teiler;
            }
            else // Breite (61 für Avatar) ist Master
            {
                ZielBreite = width;
                float teiler = Breite / width;
                ZielHoehe = Hoehe / teiler;
            }
            //
            Bitmap resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int)ZielBreite, (int)ZielHoehe, false);
            // 
            using (MemoryStream ms = new MemoryStream())
            {
                resizedImage.Compress(Bitmap.CompressFormat.Jpeg, 100, ms);
                return ms.ToArray();
            }
        }
#endif
        //
#if WINDOWS_PHONE
        public static byte[] ResizeImageWinPhone(byte[] imageData, float width, float height)
        {
            byte[] resizedData;


            using (MemoryStream streamIn = new MemoryStream(imageData))
            {
                WriteableBitmap bitmap = PictureDecoder.DecodeJpeg(streamIn, (int)width, (int)height);
                //
                float ZielHoehe = 0;
                float ZielBreite = 0;
                //
                float Hoehe = bitmap.PixelHeight;
                float Breite = bitmap.PixelWidth;
                //
                if (Hoehe > Breite) // Höhe (71 für Avatar) ist Master
                {
                    ZielHoehe = height;
                    float teiler = Hoehe / height;
                    ZielBreite = Breite / teiler;
                }
                else // Breite (61 für Avatar) ist Master
                {
                    ZielBreite = width;
                    float teiler = Breite / width;
                    ZielHoehe = Hoehe / teiler;
                }
                //                
                using (MemoryStream streamOut = new MemoryStream())
                {
                    bitmap.SaveJpeg(streamOut, (int)ZielBreite, (int)ZielHoehe, 0, 100);
                    resizedData = streamOut.ToArray();
                }
            }
            return resizedData;
        }
#endif
    }
}

Viewing all articles
Browse latest Browse all 77050

Trending Articles