如何在下载时调整图片大小?

3
我想在下载图片时或下载后调整其大小。这是我的代码。质量不重要。
public void downloadPicture(string fileName, string url,string path) {
        string fullPath = string.Empty;
        fullPath = path + @"\" + fileName + ".jpg"; //imagePath
        byte[] content;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        WebResponse response = request.GetResponse();

        Stream stream = response.GetResponseStream();

        using (BinaryReader br = new BinaryReader(stream)) {
            content = br.ReadBytes(500000);
            br.Close();
        }
        response.Close();

        FileStream fs = new FileStream(fullPath, FileMode.Create); // Starting create
        BinaryWriter bw = new BinaryWriter(fs);
        try {
            bw.Write(content); // Created
        }
        finally {
            fs.Close();
            bw.Close();
        }
    }

那么我该怎么做呢?
5个回答

7

表面上看,图片调整大小似乎非常简单,但一旦开始操作,则涉及许多复杂性。我建议不要自己尝试,而是使用一个体面的库。

您可以使用Image Resizer,它是一个易于使用、开源且免费的库。

您可以使用Nuget或下载安装。

使用nuget安装

var settings = new ResizeSettings {
  MaxWidth = thumbnailSize,
  MaxHeight = thumbnailSize,
  Format = "jpg"
};

ImageBuilder.Current.Build(inStream, outStream, settings);
resized = outStream.ToArray();

4
在try / finally块之后放置以下代码 -
这将把图像大小调整为其原始大小的1/4。
        using (System.Drawing.Image original = System.Drawing.Image.FromFile(fullPath))
        {
            int newHeight = original.Height / 4;
            int newWidth = original.Width / 4;

            using (System.Drawing.Bitmap newPic = new System.Drawing.Bitmap(newWidth, newHeight))
            {
                using (System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(newPic))
                {
                    gr.DrawImage(original, 0, 0, (newWidth), (newHeight));
                    string newFilename = ""; /* Put new file path here */
                    newPic.Save(newFilename, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
            }
        }

您当然可以通过更改newHeight和newWidth变量来将其更改为任何大小。

更新: 根据下面的评论,修改了代码以使用using() {}而不是dispose。


fullPath = path + @"" + fileName + "RESIZE.jpg"; string newFilename = fullPath.Replace("RESIZE",""); File.Delete(fullPath); 我将它们添加进去,效果很好。谢谢。 - Zyn
1
如果不使用 using(){},GDI 操作可能会任意失败并导致内存泄漏,这将进一步触发更多异常和额外的泄漏内存,直到服务器崩溃。.NET GC 不知道像 Image、Graphics 或 Bitmap 这样的 GDI 对象。它们在未托管堆中分配数十兆字节的 RAM,对 .NET 不可见。一个 500KB 的 12MP 图像需要 48MB 的连续 RAM 才能简单地被解码。 - Lilith River
@ComputerLinguist 同意,感谢提醒,已修改代码以备将来的谷歌参考 :) - Blachshma

0

您可以使用 Image.FromFile(String) 方法获取一个 Image 对象,而这个网站 Image Resizing 则提供了扩展方法来实际调整图像大小。


0

我几天前问了同样的问题,然后被引导到这个帖子,但我的情况是我想调整位图图像的大小。我的意思是,您可以将下载的流转换为位图图像,然后调整大小,如果您只指定宽度或高度,则仍将保持纵横比。

public static async void DownloadImagesAsync(BitmapImage list, String Url)
{
   try
   {
       HttpClient httpClient = new HttpClient();
       // Limit the max buffer size for the response so we don't get overwhelmed
       httpClient.MaxResponseContentBufferSize = 256000;
       httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE           10.0; Windows NT 6.2; WOW64; Trident/6.0)");
       HttpResponseMessage response = await httpClient.GetAsync(Url);
       response.EnsureSuccessStatusCode();
       byte[] str = await response.Content.ReadAsByteArrayAsync();
       InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
       DataWriter writer = new DataWriter(randomAccessStream.GetOutputStreamAt(0));
       writer.WriteBytes(str);
       await writer.StoreAsync();
       BitmapImage img = new BitmapImage();
       img.SetSource(randomAccessStream);
       //img.DecodePixelHeight = 92;
       img.DecodePixelWidth = 60; //specify only width, aspect ratio maintained
       list.ImageBitmap = img;                   
   }catch(Exception e){
      System.Diagnostics.Debug.WriteLine(ex.StackTrace);
   }
}

来自源代码


0
在我制作的应用程序中,需要创建一个具有多个选项的函数。它非常庞大,但可以调整图像大小,保持纵横比,并可以裁剪边缘以仅返回图像的中心部分:
/// <summary>
    /// Resize image with an URL as source
    /// </summary>
    /// <param name="OriginalFileURL">Link to the image</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <param name="keepAspectRatio">keep the aspect ratio</param>
    /// <param name="getCenter">return the center bit of the image</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromURL(String OriginalFileURL, int heigth, int width, Boolean keepAspectRatio, Boolean getCenter)
    {
        int newheigth = heigth;
        WebResponse response = null;
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(OriginalFileURL);
            response = request.GetResponse();
        }
        catch
        {
            return (System.Drawing.Image) new Bitmap(1, 1);
        }
        Stream imageStream = response.GetResponseStream();

        System.Drawing.Image FullsizeImage = System.Drawing.Image.FromStream(imageStream);

        // Prevent using images internal thumbnail
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

        if (keepAspectRatio || getCenter)
        {
            int bmpY = 0;
            double resize = (double)FullsizeImage.Width / (double)width;//get the resize vector
            if (getCenter)
            {
                bmpY = (int)((FullsizeImage.Height - (heigth * resize)) / 2);// gives the Y value of the part that will be cut off, to show only the part in the center
                Rectangle section = new Rectangle(new System.Drawing.Point(0, bmpY), new System.Drawing.Size(FullsizeImage.Width, (int)(heigth * resize)));// create the section to cut of the original image
                Bitmap orImg = new Bitmap((Bitmap)FullsizeImage);//for the correct effect convert image to bitmap.
                FullsizeImage.Dispose();//clear the original image
                using (Bitmap tempImg = new Bitmap(section.Width, section.Height))
                {
                    Graphics cutImg = Graphics.FromImage(tempImg);//              set the file to save the new image to.
                    cutImg.DrawImage(orImg, 0, 0, section, GraphicsUnit.Pixel);// cut the image and save it to tempImg
                    FullsizeImage = tempImg;//save the tempImg as FullsizeImage for resizing later
                    orImg.Dispose();
                    cutImg.Dispose();
                    return FullsizeImage.GetThumbnailImage(width, heigth, null, IntPtr.Zero);
                }
            }
            else newheigth = (int)(FullsizeImage.Height / resize);//  set the new heigth of the current image
        }//return the image resized to the given heigth and width
        return FullsizeImage.GetThumbnailImage(width, newheigth, null, IntPtr.Zero);
    }

为了更容易地访问该函数,可以添加一些重载函数:

/// <summary>
    /// Resize image with an URL as source
    /// </summary>
    /// <param name="OriginalFileURL">Link to the image</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromURL(String OriginalFileURL, int heigth, int width)
    {
        return resizeImageFromURL(OriginalFileURL, heigth, width, false, false);
    }

    /// <summary>
    /// Resize image with an URL as source
    /// </summary>
    /// <param name="OriginalFileURL">Link to the image</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <param name="keepAspectRatio">keep the aspect ratio</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromURL(String OriginalFileURL, int heigth, int width, Boolean keepAspectRatio)
    {
        return resizeImageFromURL(OriginalFileURL, heigth, width, keepAspectRatio, false);
    }

现在最后两个布尔值是可选的。像这样调用函数:

System.Drawing.Image ResizedImage = resizeImageFromURL(LinkToPicture, 800, 400, true, true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接