最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#縮放jpg文件的尺寸的操作方法

 更新時間:2026年02月25日 08:47:51   作者:Never_Satisfied  
該文章介紹了如何使用System.Drawing調整JPG圖像的寬度為365像素并按比例縮放,適用于.NET?Framework?4.6+和.NET?Core/.NET?5+,文章還討論了性能優(yōu)化、內存管理、替代方案(如SixLabors.ImageSharp)以及處理覆蓋原文件的特殊情況,需要的朋友可以參考下

普通處理

以下是一個使用 System.Drawing 調整 JPG 圖像寬度為 365 像素、高度按比例自動縮放的 C# 函數(shù)。該方法適用于 .NET Framework 4.6+ 或 .NET Core/.NET 5+(需安裝 System.Drawing.Common NuGet 包)。

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

public static class ImageHelper
{
    /// <summary>
    /// 將 JPG 圖像寬度調整為指定像素(默認 365),高度按原比例自動計算,并保存為新文件。
    /// </summary>
    /// <param name="inputPath">輸入 JPG 文件路徑</param>
    /// <param name="outputPath">輸出 JPG 文件路徑</param>
    /// <param name="targetWidth">目標寬度,默認 365</param>
    /// <param name="quality">JPEG 質量(1-100),默認 90</param>
    public static void ResizeJpgToWidth(string inputPath, string outputPath, int targetWidth = 365, int quality = 90)
    {
        if (string.IsNullOrEmpty(inputPath))
            throw new ArgumentNullException(nameof(inputPath));
        if (string.IsNullOrEmpty(outputPath))
            throw new ArgumentNullException(nameof(outputPath));
        if (targetWidth <= 0)
            throw new ArgumentOutOfRangeException(nameof(targetWidth), "目標寬度必須大于0");
        if (quality < 1 || quality > 100)
            throw new ArgumentOutOfRangeException(nameof(quality), "質量值必須在1到100之間");

        using (var originalImage = Image.FromFile(inputPath))
        {
            // 計算等比例高度
            float ratio = (float)targetWidth / originalImage.Width;
            int newHeight = (int)(originalImage.Height * ratio);

            // 創(chuàng)建目標位圖
            using (var resizedImage = new Bitmap(targetWidth, newHeight))
            {
                using (var graphics = Graphics.FromImage(resizedImage))
                {
                    // 設置高質量縮放參數(shù)
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.SmoothingMode = SmoothingMode.HighQuality;
                    graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    graphics.CompositingQuality = CompositingQuality.HighQuality;

                    // 繪制縮放后的圖像
                    graphics.DrawImage(originalImage, 0, 0, targetWidth, newHeight);
                }

                // 保存為 JPEG,可設置壓縮質量
                var encoderParams = new EncoderParameters(1);
                encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);

                var jpegCodec = GetEncoder(ImageFormat.Jpeg);
                if (jpegCodec != null)
                {
                    resizedImage.Save(outputPath, jpegCodec, encoderParams);
                }
                else
                {
                    // 若找不到JPEG編碼器則使用默認保存(可能質量較低)
                    resizedImage.Save(outputPath, ImageFormat.Jpeg);
                }
            }
        }
    }

    private static ImageCodecInfo GetEncoder(ImageFormat format)
    {
        var codecs = ImageCodecInfo.GetImageEncoders();
        foreach (var codec in codecs)
        {
            if (codec.FormatID == format.Guid)
                return codec;
        }
        return null;
    }
}

使用示例

// 將 "photo.jpg" 寬度改為 365 像素,高度自動等比例,輸出為 "resized.jpg"
ImageHelper.ResizeJpgToWidth(@"C:\temp\photo.jpg", @"C:\temp\resized.jpg");

// 自定義質量(例如 80%)
ImageHelper.ResizeJpgToWidth(@"C:\temp\photo.jpg", @"C:\temp\resized.jpg", quality: 80);

注意事項

環(huán)境要求

  • .NET Framework 4.6+ 可直接使用 System.Drawing。
  • .NET Core / .NET 5+ 需通過 NuGet 安裝 System.Drawing.Common。
  • 該方案在 Windows 上完全支持,跨平臺(Linux/macOS)需安裝 libgdiplus

輸出格式
即使輸入文件擴展名不是 .jpg,只要文件本身是 JPEG 格式,函數(shù)依然可以處理并輸出為 JPEG。如需嚴格校驗輸入格式,可在 Image.FromFile 后檢查 originalImage.RawFormat。

內存管理
使用了多個 using 塊,確保非托管資源(GDI+ 句柄)及時釋放。

性能優(yōu)化
InterpolationMode.HighQualityBicubic 提供較好的縮放質量,但速度略慢。若對速度有更高要求,可改為 InterpolationMode.BilinearInterpolationMode.Default。

替代方案(跨平臺推薦)

如果需要在非 Windows 環(huán)境(如 Linux 容器)中運行,推薦使用 SixLabors.ImageSharp,無需依賴系統(tǒng)庫:

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

public static void ResizeJpgToWidth(string inputPath, string outputPath, int targetWidth = 365)
{
    using (var image = Image.Load(inputPath))
    {
        image.Mutate(x => x.Resize(targetWidth, 0)); // 0 表示保持縱橫比
        image.Save(outputPath);
    }
}

使用 ImageSharp 更簡潔,且完全托管,無需額外配置。建議在 .NET 6+ 項目中優(yōu)先考慮。

以上函數(shù)可直接復制使用,按需調整參數(shù)即可。

需要覆蓋原文件的方法

要讓函數(shù)直接覆蓋原文件,只需在調用時將輸出路徑設為與輸入路徑相同,但需處理文件鎖問題:Image.FromFile 會一直鎖定文件,導致無法直接寫回原路徑。
解決方案:當輸入和輸出路徑相同時,先將原始圖像完整讀入內存(釋放文件鎖),再執(zhí)行縮放并保存。

以下是改造后的函數(shù),自動判斷路徑是否相同,并采用安全的內存加載方式:

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

public static class ImageHelper
{
    /// <summary>
    /// 將 JPG 圖像寬度調整為指定像素(默認 365),高度按原比例自動計算。
    /// 若輸出路徑與輸入路徑相同,則自動覆蓋原文件(不會因文件鎖定而報錯)。
    /// </summary>
    /// <param name="inputPath">輸入 JPG 文件路徑</param>
    /// <param name="outputPath">輸出 JPG 文件路徑(可與輸入相同)</param>
    /// <param name="targetWidth">目標寬度,默認 365</param>
    /// <param name="quality">JPEG 質量(1-100),默認 90</param>
    public static void ResizeJpgToWidth(string inputPath, string outputPath, int targetWidth = 365, int quality = 90)
    {
        if (string.IsNullOrEmpty(inputPath))
            throw new ArgumentNullException(nameof(inputPath));
        if (string.IsNullOrEmpty(outputPath))
            throw new ArgumentNullException(nameof(outputPath));
        if (targetWidth <= 0)
            throw new ArgumentOutOfRangeException(nameof(targetWidth), "目標寬度必須大于0");
        if (quality < 1 || quality > 100)
            throw new ArgumentOutOfRangeException(nameof(quality), "質量值必須在1到100之間");

        // 判斷是否為同一物理文件(忽略大小寫,并規(guī)范化路徑)
        bool isOverwrite = string.Equals(
            Path.GetFullPath(inputPath),
            Path.GetFullPath(outputPath),
            StringComparison.OrdinalIgnoreCase);

        if (isOverwrite)
        {
            // 覆蓋原文件:先將整個文件讀入內存,釋放文件鎖
            byte[] imageBytes = File.ReadAllBytes(inputPath);
            using (var ms = new MemoryStream(imageBytes))
            using (var originalImage = Image.FromStream(ms))
            {
                ResizeAndSave(originalImage, outputPath, targetWidth, quality);
            }
        }
        else
        {
            // 不同文件:直接從文件加載(保留原有邏輯)
            using (var originalImage = Image.FromFile(inputPath))
            {
                ResizeAndSave(originalImage, outputPath, targetWidth, quality);
            }
        }
    }

    /// <summary>
    /// 縮放圖像并保存為 JPEG(內部復用邏輯)
    /// </summary>
    private static void ResizeAndSave(Image originalImage, string outputPath, int targetWidth, int quality)
    {
        // 計算等比例高度
        float ratio = (float)targetWidth / originalImage.Width;
        int newHeight = (int)(originalImage.Height * ratio);

        using (var resizedImage = new Bitmap(targetWidth, newHeight))
        using (var graphics = Graphics.FromImage(resizedImage))
        {
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphics.SmoothingMode = SmoothingMode.HighQuality;
            graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            graphics.CompositingQuality = CompositingQuality.HighQuality;

            graphics.DrawImage(originalImage, 0, 0, targetWidth, newHeight);

            // 設置 JPEG 質量
            var encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);

            var jpegCodec = GetEncoder(ImageFormat.Jpeg);
            if (jpegCodec != null)
            {
                resizedImage.Save(outputPath, jpegCodec, encoderParams);
            }
            else
            {
                resizedImage.Save(outputPath, ImageFormat.Jpeg);
            }
        }
    }

    private static ImageCodecInfo GetEncoder(ImageFormat format)
    {
        var codecs = ImageCodecInfo.GetImageEncoders();
        foreach (var codec in codecs)
        {
            if (codec.FormatID == format.Guid)
                return codec;
        }
        return null;
    }

    // --- 便捷方法:直接覆蓋原文件 ---
    public static void ResizeJpgToWidthAndOverwrite(string filePath, int targetWidth = 365, int quality = 90)
    {
        ResizeJpgToWidth(filePath, filePath, targetWidth, quality);
    }
}

核心改動說明

自動檢測覆蓋場景
使用 Path.GetFullPath 規(guī)范化路徑并忽略大小寫比較,準確判斷輸入、輸出是否為同一文件。

內存加載解除文件鎖
當需要覆蓋原文件時,通過 File.ReadAllBytes 將圖片數(shù)據載入內存,再用 Image.FromStream 加載,此時原文件已完全釋放,后續(xù)可安全寫入。

提取共用縮放保存邏輯
將縮放和保存代碼抽離為 ResizeAndSave 方法,避免重復代碼。

使用示例

// 直接覆蓋原文件(兩種寫法等價)
ImageHelper.ResizeJpgToWidth(@"C:\photo.jpg", @"C:\photo.jpg");
// 或使用專用方法
ImageHelper.ResizeJpgToWidthAndOverwrite(@"C:\photo.jpg");

注意事項

  • 格式校驗:該函數(shù)不強制檢查輸入文件是否為 JPEG,若輸入其他格式,縮放仍可執(zhí)行,但保存時會強行轉為 JPEG。如需嚴格校驗,可在 ResizeAndSave 前添加 if (originalImage.RawFormat.Guid != ImageFormat.Jpeg.Guid) throw ...。
  • 性能:覆蓋原文件時多一次內存拷貝,但對普通圖片影響極小。
  • 跨平臺:若使用 System.Drawing.Common 在非 Windows 環(huán)境運行,仍需安裝 libgdiplus??缙脚_場景推薦改用 SixLabors.ImageSharp(完全托管,無文件鎖問題)。

如果需要更簡潔的跨平臺方案(無需處理文件鎖),可直接采用 ImageSharp:

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

public static void ResizeAndOverwrite(string filePath, int targetWidth = 365)
{
    using (var image = Image.Load(filePath))
    {
        image.Mutate(x => x.Resize(targetWidth, 0));
        image.Save(filePath);  // ImageSharp 會自動處理覆蓋
    }
}

根據項目環(huán)境選擇合適方案即可。

以上就是C#縮放jpg文件的尺寸的操作方法的詳細內容,更多關于C#縮放jpg文件尺寸的資料請關注腳本之家其它相關文章!

相關文章

最新評論

剑阁县| 巩义市| 广水市| 突泉县| 土默特右旗| 拉萨市| 昌宁县| 定襄县| 博爱县| 噶尔县| 高淳县| 洛宁县| 呼伦贝尔市| 新平| 玉环县| 措勤县| 通州区| 太仆寺旗| 安龙县| 祥云县| 吉隆县| 迁西县| 兴山县| 华安县| 吕梁市| 河津市| 鞍山市| 牙克石市| 金寨县| 苏尼特左旗| 济宁市| 铜鼓县| 高雄市| 卓资县| 延边| 东宁县| 西青区| 晋州市| 镇原县| 社会| 兴文县|