【问题标题】:How to reduce the size of image (in KB) on uploading and scaling?如何在上传和缩放时减小图像的大小(以 KB 为单位)?
【发布时间】:2019-04-22 19:58:54
【问题描述】:

我正在上传图片并缩小尺寸。这样做的原因之一是我还想减小大小,以便更好地优化并且不会长时间加载。

尽管尺寸减半,但图像并没有缩小,而是放大了。

这是我的功能:

    public Image ScaleProportionally(Image imgPhoto, int shortestEdge = 0)
    {
        float sourceWidth = imgPhoto.Width;
        float sourceHeight = imgPhoto.Height;
        float destHeight = 0;
        float destWidth = 0;
        int sourceX = 0;
        int sourceY = 0;
        int destX = 0;
        int destY = 0;

        if (shortestEdge > 0)
        {
            if(sourceWidth < sourceHeight)
            {
                destWidth = shortestEdge;
                destHeight = (float)(sourceHeight * shortestEdge / sourceWidth);
            }
            else
            {
                destWidth = (float)(shortestEdge * sourceWidth) / sourceHeight;
                destHeight = shortestEdge;
            }

            Bitmap bmPhoto = new Bitmap((int)destWidth, (int)destHeight,
                                        PixelFormat.Format32bppPArgb);
            bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.InterpolationMode = InterpolationMode.Low;
            grPhoto.CompositingQuality = CompositingQuality.AssumeLinear;

            grPhoto.DrawImage(imgPhoto,
                new Rectangle(destX, destY, (int)destWidth, (int)destHeight),
                new Rectangle(sourceX, sourceY, (int)sourceWidth, (int)sourceHeight),
                GraphicsUnit.Pixel);

            grPhoto.Dispose();

        return bmPhoto;

        }
        else
        {

            return imgPhoto;
        }
    }

我最初在下面为InterpolationModeCompositingQuality 设置了这个,但是像上面那样更改它们并没有真正减小缩放照片的大小:

            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
            grPhoto.CompositingQuality = CompositingQuality.HighSpeed;

原始图像大小为 546KB,而缩放后的图像大小为 1MB,几乎是原来的两倍。

如何在重新缩放时减小尺寸?

我正在使用 .NET 4.5

编辑

保存文件功能:

    public int CreateAndSaveMedia(HttpPostedFileBase file, string fileName, string mediaType, string caption, int folderId, Dictionary<string,string> additionalProperties = null)
    {
        // Create temp mediaitem folder
        string mediaDirectory = System.Web.HttpContext.Current.Server.MapPath($"~/media/");
        var path = Path.Combine(mediaDirectory, fileName);
        file.SaveAs(path);

        Image imgOriginal = Image.FromFile(path);

        //pass in whatever value you want
        Image imgActual = _imageService.ScaleProportionally(imgOriginal, 450);
        imgOriginal.Dispose();
        imgActual.Save(path);
        imgActual.Dispose();

        // Open file and assign media url to media content
        FileStream s = new FileStream(path, FileMode.Open);

        // Save media content
        IMedia media = _mediaService.CreateMedia(caption, folderId, mediaType);
        _mediaService.Save(media);
        media.SetValue("umbracoFile", Path.GetFileName(path), s);

        if (additionalProperties != null)
        {
            foreach (var itm in additionalProperties)
            {
                media.SetValue(itm.Key, itm.Value);
            }
        }

        _mediaService.Save(media);

        // Get media Id
        int mediaId = media.Id;

        s.Close();
        System.IO.File.Delete(path);

        return mediaId;
    }

编辑

根据@Nyerguds 的评论,我专门将新的图像类型设置为 jpg,这完全不同:

imgActual.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);

谢谢!

【问题讨论】:

  • 这只是调整大小的代码。您将图像保存为字节的代码在哪里?毕竟,这是产生文件大小的部分。
  • 我已经添加了我的保存功能。我应该如何保存新图像以减小尺寸呢? @Nyerguds
  • 保存时没有设置类型。如果原来是png,新的会保存为png。从 png 中获得的压缩很大程度上取决于图像中的内容。 png 不太擅长压缩像照片这样的复杂图像,并且将其调整为更小的尺寸实际上可能会增加所述复杂性。此外,.Net 框架的 png 压缩算法不如实际图形处理程序中的算法好。为了减小尺寸,您可能需要考虑重新保存为 jpeg。
  • 我正在调整 jpg 的大小而不是更改类型,所以我正在调整为 jpg @Nyerguds
  • 这是一个非常好的建议来设置保存类型 - 请参阅我的编辑 - 您可以将其添加为答案,以便我可以将其标记为解决方案吗?谢谢!

标签: c# .net image-processing image-resizing system.drawing


【解决方案1】:

保存时您没有设置类型,这会使 Image.Save 默认为检测到的原始图像类型,如果无法以从输入中检测到的确切格式保存,则默认为 PNG。

从 png 中获得的压缩很大程度上取决于图像中的内容; png 不太擅长压缩像照片这样的复杂图像,并且将其调整为更小的尺寸实际上可能会增加所述复杂性。此外,.Net 框架的 png 压缩算法不如实际图形处理程序中的算法好。

为了减小尺寸,您可能需要专门重新另存为 jpeg。

这可以通过两种方式完成。简单的方法是只指定 Jpeg 作为保存类型:

imgActual.Save(path, ImageFormat.Jpeg);

更高级的方法是使用 JPEG 编码器。如果这样做,您可以将图像的保存质量(实际上是压缩率的倒数)设置为百分比(值从 1 到 100)。不幸的是,没有简单的方法可以得到它。您需要通过查看可用编码器的完整列表通过 GUID 检索它:

Int32 quality = 80;
ImageCodecInfo jpegEncoder = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid);
EncoderParameters encparams = new EncoderParameters(1);
encparams.Param[0] = new EncoderParameter(Encoder.Quality, quality);
imgActual.Save(path, jpegEncoder, encparams);

【讨论】:

    猜你喜欢
    • 2014-02-19
    • 2016-06-10
    • 2020-06-14
    • 2018-11-05
    • 2020-04-20
    • 2011-09-10
    • 1970-01-01
    • 2015-05-22
    相关资源
    最近更新 更多