Search code examples
c#wpfimage-processingwindows-phone-8bitmap

How to resize BitmapImage using Writeable Bitmap Extension


I am using WriteableBitmap extension Available here for BitMapImage related operations.I am developing a windows phone 8 and 8.1 app where i am trying to load some images from a Zipfile. I need to Resize images based on the screen size of the device when i load Images.

  1. How can i achieve this using WritableBitMapEx?I couldn't find any documentation for this framework.
  2. Or how can i achieve this without WritableBitMapEx?

Note:

I am developing a cross platform mobile application which support WPF ,Windows Phone 8,Windows Phone 8.1.I implemented the same senario in WPF using following code.

    private Bitmap LoadAndResizeBitmap()
    {
        Bitmap bitmap = (Bitmap)Bitmap.FromStream(fileEntry.OpenEntryStream());

        if (bitmap.Height > _primaryscreenHeight)
        {
            System.Drawing.Size oldSize = new System.Drawing.Size(bitmap.Width, bitmap.Height);
            System.Drawing.Size newSize = GetNewImageSize(oldSize);
            Bitmap newImage = ResizeImage(bitmap, newSize);
            bitmap = newImage;
        }
        return bitmap;
    }


    /// <summary>


    /// <summary>
    /// Resize the Image
    /// </summary>
    /// <param name="image"></param>
    /// <param name="newSize"></param>
    /// <returns></returns>
    private Bitmap ResizeImage(Image image, System.Drawing.Size newSize)
    {
        // Make a rectangle that is the new size
        Rectangle destRect = new Rectangle(0, 0, newSize.Width, newSize.Height);

        // Make a bitmap that is the new size
        Bitmap destImage = new Bitmap(newSize.Width, newSize.Height);

        // Set new image to the resolution of the original
        destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        // Create a GDI holder and use it
        using (Graphics graphics = Graphics.FromImage(destImage))
        {
            // Set our quality options
            graphics.CompositingMode = CompositingMode.SourceCopy;
            graphics.CompositingQuality = CompositingQuality.HighQuality;
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

            // Resize original image into new one
            using (var wrapMode = new ImageAttributes())
            {
                wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
            }
        }
        return destImage;
    }

    /// <summary>
    /// Get new Image Size
    /// </summary>
    /// <param name="oldSize"></param>
    /// <returns></returns>
    private System.Drawing.Size GetNewImageSize(System.Drawing.Size oldSize)
    {
        float ratio;
        if (oldSize.Height > oldSize.Width)
        {
            ratio = (float) oldSize.Width/oldSize.Height;
        }
        else
        {
            ratio = (float) oldSize.Height/oldSize.Width;
        }
        int newWidth = (int) (_maxImageHeight*ratio);
        System.Drawing.Size newSize = new System.Drawing.Size(newWidth, _maxImageHeight);
        return newSize;
    }

I cant use the same implementation in windows hone 8 or 8.1 since we dont have system.Drawing in these platfoms.Thus i selected WritableBitmap extension.Beside it supports Win 8,win Phone 8,8.1 and WPF


Solution

  • This has worked for me in the past. What you'd be interested in mainly is the decoding pixel width and height. P.s. this code successfully converts a byte[] (database friendly) to a BitmapImage:

    using(MemoryStream strmImg = new MemoryStream(profileImage.Image))
    {
        BitmapImage myBitmapImage = new BitmapImage();               
        myBitmapImage.BeginInit();
        myBitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        myBitmapImage.StreamSource = strmImg;
        myBitmapImage.DecodePixelWidth = 200;
        myBitmapImage.DecodePixelHeight= 250;
        myBitmapImage.EndInit();
        EmployeeProfileImage = myBitmapImage;
    }
    

    I hope this helps,

    Roka