首页 > 解决方案 > c#如何在保留图像类型的同时将任何图像的大小调整为特定的千字节

问题描述

我已经看到了大量用于减小图像大小的 stackoverflow 文章,但它们都没有保持原始图像类型(或者我发现了)。它们通常具有减小像素尺寸、降低图像质量以及转换为特定类型图像(通常是 jpeg)的步骤。

我有一组需要调整大小的图像。它们具有各种图像类型,并且文件名都存储在数据库中,这使得从一种图像类型转换为另一种图像类型有些问题。我不能只将文件名从 png 更改为 jpg,因为这样数据库就不会指向真实文件。

有没有人有如何将图像调整大小/缩小到“256 KB”并保持原始图像类型的示例?

例如,这是我目前正在摆弄的代码。

public static byte[] ResizeImageFile(Image oldImage, int targetSize) // Set targetSize to 1024
    {
        Size newSize = CalculateDimensions(oldImage.Size, targetSize);
        using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb))
        {
            using (Graphics canvas = Graphics.FromImage(newImage))
            {
                canvas.SmoothingMode = SmoothingMode.AntiAlias;
                canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
                canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
                MemoryStream m = new MemoryStream();
                newImage.Save(m, ImageFormat.Jpeg);
                return m.GetBuffer();
            }
        }
    }

也许有一种方法可以让我先获取文件 fileinfo 或 mime 类型,然后打开 .Save 以获取图像类型?

标签: c#imageimage-resizing

解决方案


这是我想出的(基于我在网上找到的一些不是 100% 完整的示例。

private void EnsureImageRequirements(string filePath)
    {
        try
        {
            if (File.Exists(filePath))
            {
                // If images are larger than 300 kilobytes
                FileInfo fInfo = new FileInfo(filePath);
                if (fInfo.Length > 300000)
                {
                    Image oldImage = Image.FromFile(filePath);

                    ImageFormat originalFormat = oldImage.RawFormat;

                    // manipulate the image / Resize
                    Image tempImage = RefactorImage(oldImage, 1200); ;

                    // Dispose before deleting the file
                    oldImage.Dispose();

                    // Delete the existing file and copy the image to it
                    File.Delete(filePath);

                    // Ensure encoding quality is set to an acceptable level
                    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();

                    // Set encoder to fifty percent compression
                    EncoderParameters eps = new EncoderParameters
                    {
                        Param = { [0] = new EncoderParameter(Encoder.Quality, 50L) }
                    };

                    ImageCodecInfo ici = (from codec in encoders where codec.FormatID == originalFormat.Guid select codec).FirstOrDefault();

                    // Save the reformatted image and use original file format (jpeg / png / etc) and encoding
                    tempImage.Save(filePath, ici, eps);

                    // Clean up RAM
                    tempImage.Dispose();
                }

            }
        }
        catch (Exception ex)
        {
            this._logger.Error("Could not resize oversized image " + filePath, ex);
        }

    }

    private static Image RefactorImage(Image imgToResize, int maxPixels)
    {
        int sourceWidth = imgToResize.Width;
        int sourceHeight = imgToResize.Height;

        int destWidth = sourceWidth;
        int destHeight = sourceHeight;

        // Resize if needed
        if (sourceWidth > maxPixels || sourceHeight > maxPixels)
        {
            float thePercent = 0;
            float thePercentW = 0;
            float thePercentH = 0;

            thePercentW = maxPixels / (float) sourceWidth;
            thePercentH = maxPixels / (float) sourceHeight;

            if (thePercentH < thePercentW)
            {
                thePercent = thePercentH;
            }
            else
            {
                thePercent = thePercentW;
            }

            destWidth = (int)(sourceWidth * thePercent);
            destHeight = (int)(sourceHeight * thePercent);
        }

        Bitmap tmpImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);

        Graphics g = Graphics.FromImage(tmpImage);
        g.InterpolationMode = InterpolationMode.HighQualityBilinear;

        g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
        g.Dispose();

        return tmpImage;
    }

推荐阅读