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

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

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

普通處理

以下是一個使用 System.Drawing 調(diào)整 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 圖像寬度調(diào)整為指定像素(默認 365),高度按原比例自動計算,并保存為新文件。
    /// </summary>
    /// <param name="inputPath">輸入 JPG 文件路徑</param>
    /// <param name="outputPath">輸出 JPG 文件路徑</param>
    /// <param name="targetWidth">目標寬度,默認 365</param>
    /// <param name="quality">JPEG 質(zhì)量(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), "質(zhì)量值必須在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è)置高質(zhì)量縮放參數(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,可設(shè)置壓縮質(zhì)量
                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編碼器則使用默認保存(可能質(zhì)量較低)
                    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");

// 自定義質(zhì)量(例如 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。

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

性能優(yōu)化
InterpolationMode.HighQualityBicubic 提供較好的縮放質(zhì)量,但速度略慢。若對速度有更高要求,可改為 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ù)可直接復(fù)制使用,按需調(diào)整參數(shù)即可。

需要覆蓋原文件的方法

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

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

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

public static class ImageHelper
{
    /// <summary>
    /// 將 JPG 圖像寬度調(diào)整為指定像素(默認 365),高度按原比例自動計算。
    /// 若輸出路徑與輸入路徑相同,則自動覆蓋原文件(不會因文件鎖定而報錯)。
    /// </summary>
    /// <param name="inputPath">輸入 JPG 文件路徑</param>
    /// <param name="outputPath">輸出 JPG 文件路徑(可與輸入相同)</param>
    /// <param name="targetWidth">目標寬度,默認 365</param>
    /// <param name="quality">JPEG 質(zhì)量(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), "質(zhì)量值必須在1到100之間");

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

        if (isOverwrite)
        {
            // 覆蓋原文件:先將整個文件讀入內(nèi)存,釋放文件鎖
            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(內(nèi)部復(fù)用邏輯)
    /// </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);

            // 設(shè)置 JPEG 質(zhì)量
            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ī)范化路徑并忽略大小寫比較,準確判斷輸入、輸出是否為同一文件。

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

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

使用示例

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

注意事項

  • 格式校驗:該函數(shù)不強制檢查輸入文件是否為 JPEG,若輸入其他格式,縮放仍可執(zhí)行,但保存時會強行轉(zhuǎn)為 JPEG。如需嚴格校驗,可在 ResizeAndSave 前添加 if (originalImage.RawFormat.Guid != ImageFormat.Jpeg.Guid) throw ...
  • 性能:覆蓋原文件時多一次內(nèi)存拷貝,但對普通圖片影響極小。
  • 跨平臺:若使用 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 會自動處理覆蓋
    }
}

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

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

相關(guān)文章

最新評論

资中县| 洛扎县| 洪湖市| 手游| 安新县| 田林县| 大石桥市| 濉溪县| 读书| 潞城市| 繁峙县| 徐闻县| 乾安县| 唐海县| 吕梁市| 大理市| 阿拉善盟| 平昌县| 博兴县| 旺苍县| 馆陶县| 云浮市| 阳江市| 庆云县| 安阳市| 师宗县| 岳池县| 西昌市| 克拉玛依市| 广西| 镇原县| 巴中市| 沙河市| 湖州市| 宁乡县| 泰州市| 海淀区| 邢台市| 阿巴嘎旗| 新化县| 三江|