8

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;
}
5
  • You need to change Height and Width of the bitmap after creation. What you are doing here is that you are making a new Bitmap of small size and filling it with original picture without resizing. You create a bitmap of original size and then use its height and width to change its size.
    – fhnaseer
    Commented Apr 3, 2013 at 5:35
  • @FaisalHafeez can u explain more about it? how can i re size it
    – DevT
    Commented Apr 3, 2013 at 5:37
  • Here you are making a bitmap of width and height size. Now this is of reduced size. But when you will fill it with image, it will copy only some part of the image (this is happening in your case). You need to use some other function to implement this.
    – fhnaseer
    Commented Apr 3, 2013 at 5:47
  • @FaisalHafeez can u suggest me what do in here please.
    – DevT
    Commented Apr 3, 2013 at 5:55
  • Try the solution provided by Erti, It looks fine.
    – fhnaseer
    Commented Apr 3, 2013 at 6:26

2 Answers 2

33

As to the resizing itself, using WPF's TransformedBitmap seems a bit easier:

var bitmap = new TransformedBitmap(bitmapSource, 
    new ScaleTransform(
        newWidth / bitmapSource.PixelWidth, 
        newHeight / bitmapSource.PixelHeight));
2
  • I'd say - a lot easier :) Commented Jun 7, 2018 at 1:51
  • Simple and concise! Thanks!
    – hfann
    Commented Sep 19, 2023 at 10:43
22

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);
}
4
  • i have used this function and u mean instead of RenderTargetBitmap use PngBitmapEncoder r8? if so how can i save enc.Frames.Add(BitmapFrame.Create(rtb)); because in here it needed visual object.
    – DevT
    Commented Apr 3, 2013 at 9:40
  • i edited my question. when i save like that it saves black picture. why is that?
    – DevT
    Commented Apr 3, 2013 at 10:19
  • 1
    Even if this is a pretty old answer, it still works as a charm! Thank you for saving my day! Commented Jun 30, 2022 at 8:52
  • Works great! You will not believe how difficult it is to do anything with images. Commented Feb 5, 2023 at 21:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.