anand
anand

Reputation: 1459

How to resize images in xamarin.forms?

I am working on xamarin.forms. I have to select images from gallery and then resize them and then upload them on server. But I don't know how I can resize selected image in a given particular size? Please update me how I can do this?

Upvotes: 11

Views: 23192

Answers (5)

Ricko..
Ricko..

Reputation: 1054

I tried use CrossImageResizer.Current... but I did not find it in the Media Plugin. Instead I found an option called MaxWidthHeight, that worked only if you also add PhotoSize = PhotoSize.MaxWidthHeight option.

For Example :

 var file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions() { PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 600 });
 var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions { PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 600 });

UPDATE (12/05/2023) CrossMedia.Current.PickPhotoAsync and CrossMedia.Current.TakePhotoAsync don't work with Android 13 (API 33) for permission errore. Use Xamarin.Essentials 1.7.5

Upvotes: 6

Halim Bezek
Halim Bezek

Reputation: 1023

I fixed in my project, this was the best way for me .

when take photo or get image from gallery you can change size with properties

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    PhotoSize = PhotoSize.Custom,
    CustomPhotoSize = 90 //Resize to 90% of original
});

for more information: https://github.com/jamesmontemagno/MediaPlugin

Upvotes: 0

henda79
henda79

Reputation: 535

Here is the code taken from the link above.

iOS

public class MediaService : IMediaService
{

    public byte[] ResizeImage(byte[] imageData, float width, float height)
    {

        UIImage originalImage = ImageFromByteArray(imageData);

        var originalHeight = originalImage.Size.Height;
        var originalWidth = originalImage.Size.Width;

        nfloat newHeight = 0;
        nfloat newWidth = 0;

        if (originalHeight > originalWidth)
        {
            newHeight = height;
            nfloat ratio = originalHeight / height;
            newWidth = originalWidth / ratio;
        }
        else 
        {
            newWidth = width;
            nfloat ratio = originalWidth / width;
            newHeight = originalHeight / ratio;
        }

        width = (float)newWidth;
        height = (float)newHeight;

        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;
   }          
}

Android

public class MediaService : IMediaService
{

    public byte[] ResizeImage(byte[] imageData, float width, float height)
    {
        // Load the bitmap 
        BitmapFactory.Options options = new BitmapFactory.Options();// Create object of bitmapfactory's option method for further option use
        options.InPurgeable = true; // inPurgeable is used to free up memory while required
        Bitmap originalImage = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length, options);

        float newHeight = 0;
        float newWidth = 0;

        var originalHeight = originalImage.Height;
        var originalWidth = originalImage.Width;

        if (originalHeight > originalWidth)
        {
            newHeight = height;
            float ratio = originalHeight / height;
            newWidth = originalWidth / ratio;
        }
        else 
        {
            newWidth = width;
            float ratio = originalWidth / width;
            newHeight = originalHeight / ratio;
        }

        Bitmap resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int)newWidth, (int)newHeight, true);

        originalImage.Recycle();

        using (MemoryStream ms = new MemoryStream())
        {
            resizedImage.Compress(Bitmap.CompressFormat.Png, 100, ms);

            resizedImage.Recycle();

            return ms.ToArray();
        }
    }

WinPhone

public class MediaService : IMediaService
{
    private MediaImplementation mi = new MediaImplementation();

    public byte[] ResizeImage(byte[] imageData, float width, float height)
    {
        byte[] resizedData;

        using (MemoryStream streamIn = new MemoryStream(imageData))
        {
            WriteableBitmap bitmap = PictureDecoder.DecodeJpeg(streamIn, (int)width, (int)height);

            float Height = 0;
            float Width = 0;

            float originalHeight = bitmap.PixelHeight;
            float originalWidth = bitmap.PixelWidth;

            if (originalHeight > originalWidth)
            {
                Height = height;
                float ratio = originalHeight / height;
                Width = originalWidth / ratio;
            }
            else
            {
                Width = width;
                float ratio = originalWidth / width;
                Height = originalHeight / ratio;
            }

            using (MemoryStream streamOut = new MemoryStream())
            {
                bitmap.SaveJpeg(streamOut, (int)Width, (int)Height, 0, 100);
                resizedData = streamOut.ToArray();
            }
        }
        return resizedData;
    }
}

EDIT: If you are already using FFImageLoading in your project then you can just use that for your platform.

https://github.com/luberda-molinet/FFImageLoading

Upvotes: 3

MedievalCoder
MedievalCoder

Reputation: 657

Sadly enough there isn't a good cross-platform image resizer (that I've found at the time of this post). Image processing wasn't really designed to take place in a cross-platform environment for iOS and Android. It's much faster and cleaner to perform this on each platform using platform-specific code. You can do this using dependency injection and the DependencyService (or any other service or IOC).

AdamP gives a great response on how to do this Platform Specific Image Resizing

Upvotes: 4

Eng Soon Cheah
Eng Soon Cheah

Reputation: 257

This can be used with a stream (if you're using the Media Plugin https://github.com/jamesmontemagno/MediaPlugin) or standard byte arrays.

// If you already have the byte[]
byte[] resizedImage = await CrossImageResizer.Current.ResizeImageWithAspectRatioAsync(originalImageBytes, 500, 1000);

// If you have a stream, such as:
// var file = await CrossMedia.Current.PickPhotoAsync(options);
// var originalImageStream = file.GetStream();
byte[] resizedImage = await CrossImageResizer.Current.ResizeImageWithAspectRatioAsync(originalImageStream, 500, 1000);

Upvotes: 5

Related Questions