0

Hey all I found this image resize code here and I am trying to adapt it to my current code.

private void resizeImage(string path, string originalFilename, 
                     /* note changed names */
                     int canvasWidth, int canvasHeight, 
                     /* new */
                     int originalWidth, int originalHeight)
{
    Image image = Image.FromFile(path + originalFilename);

    System.Drawing.Image thumbnail = 
        new Bitmap(canvasWidth, canvasHeight); // changed parm names
    System.Drawing.Graphics graphic = 
                 System.Drawing.Graphics.FromImage(thumbnail);

    graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graphic.SmoothingMode = SmoothingMode.HighQuality;
    graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
    graphic.CompositingQuality = CompositingQuality.HighQuality;

    /* ------------------ new code --------------- */

    // Figure out the ratio
    double ratioX = (double) canvasWidth / (double) originalWidth;
    double ratioY = (double) canvasHeight / (double) originalHeight;
    // use whichever multiplier is smaller
    double ratio = ratioX < ratioY ? ratioX : ratioY;

    // now we can get the new height and width
    int newHeight = Convert.ToInt32(originalHeight * ratio);
    int newWidth = Convert.ToInt32(originalWidth * ratio);

    // Now calculate the X,Y position of the upper-left corner 
    // (one of these will always be zero)
    int posX = Convert.ToInt32((canvasWidth - (originalWidth * ratio)) / 2);
    int posY = Convert.ToInt32((canvasHeight - (originalHeight * ratio)) / 2);

    graphic.Clear(Color.White); // white padding
    graphic.DrawImage(image, posX, posY, newWidth, newHeight);

    /* ------------- end new code ---------------- */

    System.Drawing.Imaging.ImageCodecInfo[] info =
                     ImageCodecInfo.GetImageEncoders();
    EncoderParameters encoderParameters;
    encoderParameters = new EncoderParameters(1);
    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
                     100L);            
    thumbnail.Save(path + newWidth + "." + originalFilename, info[1], 
                     encoderParameters);
}

And my current code:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    string path = value as string;

    if (path != null) {
       //create new stream and create bitmap frame
       var bitmapImage = new BitmapImage();

       bitmapImage.BeginInit();
       bitmapImage.StreamSource = new FileStream(path, FileMode.Open, FileAccess.Read);
       //load the image now so we can immediately dispose of the stream
       bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
       bitmapImage.EndInit();

       //clean up the stream to avoid file access exceptions when attempting to delete images
       bitmapImage.StreamSource.Dispose();

       return bitmapImage;
    } else {
       return DependencyProperty.UnsetValue;
    }
}

Problem being is that the resizeImage code uses Image and my current code uses BitmapImage.

I've been trying to find ways to convert either/or to one format or the other but I do not seem to be successful in doing that.

Not sure if the resizeImage is what I am needing since I am unable to run it as is but all I am looking to do is detect if the image is horizontal or vertical. If its vertical then resize it (either being bigger or smaller) so that it fits into my designated area. Likewise, the horizontal would be the same way as the vertical.

StealthRT
  • 10,108
  • 40
  • 183
  • 342
  • So if a bitmap's aspect ratio is *portrait* (i.e. it is taller than it is wide) you want to somehow convert it to *landscape*, but not rotate it. How is that supposed to be done? By cutting parts off, or by distorting it (e.g. by scaling in only one direction)? The BitmapImage is certainly shown by an Image element, which is already capabable of stretching its Source, either uniformly or not, so it might not be necessary to manipulate the BitmapImage at all. – Clemens Dec 19 '17 at 15:05
  • Possible duplicate of [Changing the dimensions of a BitMapImage in WPF, and what kind of objects can I put in an element?](https://stackoverflow.com/questions/17072775/changing-the-dimensions-of-a-bitmapimage-in-wpf-and-what-kind-of-objects-can-i) – PaulF Dec 19 '17 at 15:06
  • 1
    I suspect you could junk all this code and use the `Stretch` attribute of the Image. – 15ee8f99-57ff-4f92-890c-b56153 Dec 19 '17 at 15:24

1 Answers1

0

There are many ways to convert sizes, but I wanted to answer your question directly since there's not much on the web about converting from a BitmapSource to a System.Drawing.Bitmap. (There are many articles on going the other way).

This function will convert any WPF BitmapSource -- including BitmapImage, which is a BitmapSource -- to a System.Drawing.Bitmap:

private System.Drawing.Bitmap ConvertBitmapSourceToDrawingBitmap(BitmapSource image)
{
    int width = Convert.ToInt32(image.Width);
    int height = Convert.ToInt32(image.Height);
    int stride = Convert.ToInt32(width * ((image.Format.BitsPerPixel + 7) / 8) + 0.5);

    byte[] bits = new byte[height * stride];
    image.CopyPixels(bits, stride, 0);

    System.Drawing.Bitmap bitmap = null;
    unsafe
    {
        fixed (byte* pBits = bits)
        {
            IntPtr ptr = new IntPtr(pBits);
            bitmap = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, ptr);
        }
    }

    return bitmap;
}

To test it, I used this code:

    System.Windows.Media.Imaging.BitmapSource bitmapSource;
    using (System.IO.Stream stm = System.IO.File.Open("c:\\foo_in.png", System.IO.FileMode.Open, System.IO.FileAccess.Read))
    {
        // Since we're not specifying a System.Windows.Media.Imaging.BitmapCacheOption, the pixel format
        // will be System.Windows.Media.PixelFormats.Pbgra32.
        bitmapSource = System.Windows.Media.Imaging.BitmapFrame.Create(
            stm,
            System.Windows.Media.Imaging.BitmapCreateOptions.None,
            System.Windows.Media.Imaging.BitmapCacheOption.OnLoad);
    }
    System.Drawing.Bitmap bmp = ConvertBitmapSourceToDrawingBitmap(bitmapSource);
    bmp.Save("c:\\foo_out.png", System.Drawing.Imaging.ImageFormat.Png);
Ed Bayiates
  • 11,060
  • 4
  • 43
  • 62