C# 在 WPF 中调整图像大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15779564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:55:42  来源:igfitidea点击:

Resize image in WPF

c#wpfimageimage-resizing

提问by DevT

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......

编辑:正如 Erti-Chris Eelmaa 提到的上述答案所述,我已将代码更改如下。它有效......

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

采纳答案by Erti-Chris Eelmaa

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

使用此方法获取BitmapFrame,然后您可以使用PngBitmapEncoder将其保存到HDD。

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

回答by Gábor

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

至于调整大小本身,使用 WPFTransformedBitmap似乎更容易一些:

var bitmap = new TransformedBitmap(bitmapSource, 
    new ScaleTransform(
        newWidth / bitmapSource.PixelWidth, 
        newHeight / bitmapSource.PixelHeight));