Search code examples
c#wpfimageimage-resizing

Resize image in WPF


i have a image and i want to re size it and need to save in my temp folder.

what i have tried is as below :

UIElement uie = CanvasHost.Child;
int width = 800;
int height = (int)((width / (double)((FrameworkElement)uie).Width) * (int)((FrameworkElement)uie).Height);          
RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(uie);

string dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\temp\";
if (!Directory.Exists(dir))
      Directory.CreateDirectory(dir);

long size = 0;

string filePath = dir + DateTime.Now.Ticks.ToString() + (isPng ? ".png" : ".jpg");
BitmapEncoder enc = null;

using (FileStream fs = File.Create(filePath))
{
    if (isPng)
        enc = new PngBitmapEncoder();
    else
        enc = new JpegBitmapEncoder();

    enc.Frames.Add(BitmapFrame.Create(rtb));
    enc.Save(fs);

    size = fs.Length;
}

but when i create image like this it saves part of the image in temp folder. (as shown in the above pic)

enter image description here

how can i re size full image? what i missed here?

EDIT : As mentioned in the above answer as mentioned by Erti-Chris Eelmaa i have changed the code as below. and it works......

UIElement uie = CanvasHost.Child;
int width = DataCache.Instance.CurrentProject.MaxPhotoEdgeSize;
int height = (int)((width / (double)((FrameworkElement)uie).Width) * (int)((FrameworkElement)uie).Height);

RenderTargetBitmap rtb = new RenderTargetBitmap((int)((FrameworkElement)uie).Width, (int)((FrameworkElement)uie).Height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(uie);

ImageSource im = (ImageSource)rtb.Clone();
BitmapFrame bp = CreateResizedImage(im, width, height, 1); //method suggested by Erti-Chris Eelmaa
string dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\temp\";

if (!Directory.Exists(dir))
    Directory.CreateDirectory(dir);

long size = 0;

string filePath = dir + DateTime.Now.Ticks.ToString() + (isPng ? ".png" : ".jpg");
BitmapEncoder enc = null;

using (FileStream fs = File.Create(filePath))
{
    if (isPng)
         enc = new PngBitmapEncoder();
    else
         enc = new JpegBitmapEncoder();


    enc.Frames.Add(BitmapFrame.Create(bp));
    enc.Save(fs);

    size = fs.Length;
}

Solution

  • Just use this method to obtain BitmapFrame, after that you can just save it to HDD using PngBitmapEncoder.

    private static BitmapFrame CreateResizedImage(ImageSource source, int width, int height, int margin)
    {
        var rect = new Rect(margin, margin, width - margin * 2, height - margin * 2);
    
        var group = new DrawingGroup();
        RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
        group.Children.Add(new ImageDrawing(source, rect));
    
        var drawingVisual = new DrawingVisual();
        using (var drawingContext = drawingVisual.RenderOpen())
            drawingContext.DrawDrawing(group);
    
        var resizedImage = new RenderTargetBitmap(
            width, height,         // Resized dimensions
            96, 96,                // Default DPI values
            PixelFormats.Default); // Default pixel format
        resizedImage.Render(drawingVisual);
    
        return BitmapFrame.Create(resizedImage);
    }