欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#實(shí)現(xiàn)將超大圖片(1GB)裁剪為8張小圖片

 更新時(shí)間:2025年05月18日 10:06:32   作者:MartinYangHJ  
C#處理超大圖片(1GB)需要特別注意內(nèi)存管理和性能優(yōu)化,這篇文章為大家整理了4種常見(jiàn)的處理方法,并進(jìn)行了對(duì)比,大家可以根據(jù)自己的需要進(jìn)行選擇

C#處理超大圖片(1GB)需要特別注意內(nèi)存管理和性能優(yōu)化。以下是幾種高效裁剪方案:

方法1:使用System.Drawing分塊處理(內(nèi)存優(yōu)化版)

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
 
class Program
{
    static void Main()
    {
        string sourceImagePath = "1GB_Image.bmp";
        string outputFolder = "CroppedImages";
        
        if (!Directory.Exists(outputFolder))
        {
            Directory.CreateDirectory(outputFolder);
        }
 
        // 獲取圖片尺寸但不加載全部?jī)?nèi)容
        using (var image = Image.FromFile(sourceImagePath))
        {
            int totalWidth = image.Width;
            int totalHeight = image.Height;
            
            // 計(jì)算每塊尺寸 (2x4網(wǎng)格)
            int chunkWidth = totalWidth / 2;
            int chunkHeight = totalHeight / 4;
 
            // 分塊裁剪
            for (int row = 0; row < 4; row++)
            {
                for (int col = 0; col < 2; col++)
                {
                    int x = col * chunkWidth;
                    int y = row * chunkHeight;
                    
                    // 確保最后一塊包含剩余部分
                    int width = (col == 1) ? totalWidth - x : chunkWidth;
                    int height = (row == 3) ? totalHeight - y : chunkHeight;
 
                    CropImage(
                        sourceImagePath,
                        Path.Combine(outputFolder, $"part_{row}_{col}.jpg"),
                        x, y, width, height);
                }
            }
        }
    }
 
    static void CropImage(string sourcePath, string destPath, int x, int y, int width, int height)
    {
        // 使用流式處理避免全圖加載
        using (var source = new Bitmap(sourcePath))
        using (var dest = new Bitmap(width, height))
        using (var graphics = Graphics.FromImage(dest))
        {
            graphics.DrawImage(
                source,
                new Rectangle(0, 0, width, height),
                new Rectangle(x, y, width, height),
                GraphicsUnit.Pixel);
            
            // 保存為JPEG減少體積
            dest.Save(destPath, ImageFormat.Jpeg);
            Console.WriteLine($"已保存: {destPath} ({width}x{height})");
        }
    }
}

方法2:使用ImageSharp(現(xiàn)代跨平臺(tái)方案)

首先安裝NuGet包:

Install-Package SixLabors.ImageSharp

實(shí)現(xiàn)代碼:

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Jpeg;
 
class Program
{
    static async Task Main()
    {
        string sourcePath = "1GB_Image.jpg";
        string outputDir = "CroppedImages";
        
        Directory.CreateDirectory(outputDir);
 
        // 配置內(nèi)存選項(xiàng)處理大圖
        var configuration = Configuration.Default.Clone();
        configuration.MemoryAllocator = new SixLabors.ImageSharp.Memory.ArrayPoolMemoryAllocator();
 
        // 分塊加載和處理
        using (var image = await Image.LoadAsync(configuration, sourcePath))
        {
            int totalWidth = image.Width;
            int totalHeight = image.Height;
            
            int chunkWidth = totalWidth / 2;
            int chunkHeight = totalHeight / 4;
 
            for (int row = 0; row < 4; row++)
            {
                for (int col = 0; col < 2; col++)
                {
                    int x = col * chunkWidth;
                    int y = row * chunkHeight;
                    int width = (col == 1) ? totalWidth - x : chunkWidth;
                    int height = (row == 3) ? totalHeight - y : chunkHeight;
 
                    // 克隆并裁剪區(qū)域
                    using (var cropped = image.Clone(ctx => ctx
                        .Crop(new Rectangle(x, y, width, height))))
                    {
                        string outputPath = Path.Combine(outputDir, $"part_{row}_{col}.jpg");
                        await cropped.SaveAsync(outputPath, new JpegEncoder 
                        {
                            Quality = 80 // 適當(dāng)壓縮
                        });
                        Console.WriteLine($"已保存: {outputPath}");
                    }
                }
            }
        }
    }
}

方法3:使用內(nèi)存映射文件處理超大圖

using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Drawing;
using System.Drawing.Imaging;
 
class Program
{
    static void Main()
    {
        string sourcePath = "1GB_Image.bmp";
        string outputDir = "CroppedImages";
        
        Directory.CreateDirectory(outputDir);
 
        // 獲取BMP文件頭信息
        var bmpInfo = GetBmpInfo(sourcePath);
        int width = bmpInfo.Width;
        int height = bmpInfo.Height;
        int bytesPerPixel = bmpInfo.BitsPerPixel / 8;
        int stride = width * bytesPerPixel;
 
        // 計(jì)算分塊
        int chunkWidth = width / 2;
        int chunkHeight = height / 4;
 
        // 使用內(nèi)存映射文件處理
        using (var mmf = MemoryMappedFile.CreateFromFile(sourcePath, FileMode.Open))
        {
            for (int row = 0; row < 4; row++)
            {
                for (int col = 0; col < 2; col++)
                {
                    int x = col * chunkWidth;
                    int y = row * chunkHeight;
                    int cropWidth = (col == 1) ? width - x : chunkWidth;
                    int cropHeight = (row == 3) ? height - y : chunkHeight;
 
                    // 創(chuàng)建目標(biāo)位圖
                    using (var dest = new Bitmap(cropWidth, cropHeight, PixelFormat.Format24bppRgb))
                    {
                        var destData = dest.LockBits(
                            new Rectangle(0, 0, cropWidth, cropHeight),
                            ImageLockMode.WriteOnly,
                            dest.PixelFormat);
 
                        try
                        {
                            // 計(jì)算源文件偏移量(BMP文件頭54字節(jié) + 數(shù)據(jù)偏移)
                            long offset = 54 + (height - y - 1) * stride + x * bytesPerPixel;
                            
                            // 逐行復(fù)制
                            for (int line = 0; line < cropHeight; line++)
                            {
                                using (var accessor = mmf.CreateViewAccessor(
                                    offset - line * stride, 
                                    cropWidth * bytesPerPixel))
                                {
                                    byte[] lineData = new byte[cropWidth * bytesPerPixel];
                                    accessor.ReadArray(0, lineData, 0, lineData.Length);
                                    
                                    IntPtr destPtr = destData.Scan0 + (line * destData.Stride);
                                    System.Runtime.InteropServices.Marshal.Copy(lineData, 0, destPtr, lineData.Length);
                                }
                            }
                        }
                        finally
                        {
                            dest.UnlockBits(destData);
                        }
 
                        string outputPath = Path.Combine(outputDir, $"part_{row}_{col}.jpg");
                        dest.Save(outputPath, ImageFormat.Jpeg);
                        Console.WriteLine($"已保存: {outputPath}");
                    }
                }
            }
        }
    }
 
    static (int Width, int Height, int BitsPerPixel) GetBmpInfo(string filePath)
    {
        using (var fs = new FileStream(filePath, FileMode.Open))
        using (var reader = new BinaryReader(fs))
        {
            // 讀取BMP頭
            if (reader.ReadChar() != 'B' || reader.ReadChar() != 'M')
                throw new Exception("不是有效的BMP文件");
            
            fs.Seek(18, SeekOrigin.Begin); // 跳轉(zhuǎn)到寬度信息
            int width = reader.ReadInt32();
            int height = reader.ReadInt32();
            fs.Seek(28, SeekOrigin.Begin); // 跳轉(zhuǎn)到位深信息
            int bitsPerPixel = reader.ReadInt16();
            
            return (width, height, bitsPerPixel);
        }
    }
}

方法4:使用Magick.NET(專業(yè)圖像處理)

首先安裝NuGet包:

Install-Package Magick.NET-Q16-x64

實(shí)現(xiàn)代碼:

using ImageMagick;
using System;
using System.IO;
 
class Program
{
    static void Main()
    {
        string sourcePath = "1GB_Image.tif";
        string outputDir = "CroppedImages";
        
        Directory.CreateDirectory(outputDir);
 
        // 設(shè)置資源限制
        MagickNET.SetResourceLimit(ResourceType.Memory, 1024 * 1024 * 1024); // 1GB
 
        // 使用像素流處理大圖
        using (var image = new MagickImage(sourcePath))
        {
            int width = image.Width;
            int height = image.Height;
            
            int chunkWidth = width / 2;
            int chunkHeight = height / 4;
 
            for (int row = 0; row < 4; row++)
            {
                for (int col = 0; col < 2; col++)
                {
                    int x = col * chunkWidth;
                    int y = row * chunkHeight;
                    int cropWidth = (col == 1) ? width - x : chunkWidth;
                    int cropHeight = (row == 3) ? height - y : chunkHeight;
 
                    using (var cropped = image.Clone(new MagickGeometry
                    {
                        X = x,
                        Y = y,
                        Width = cropWidth,
                        Height = cropHeight
                    }))
                    {
                        string outputPath = Path.Combine(outputDir, $"part_{row}_{col}.jpg");
                        cropped.Quality = 85;
                        cropped.Write(outputPath);
                        Console.WriteLine($"已保存: {outputPath}");
                    }
                }
            }
        }
    }
}

裁剪方案選擇建議

方法        優(yōu)點(diǎn)缺點(diǎn)使用場(chǎng)景
System.Drawing內(nèi)置庫(kù),簡(jiǎn)單內(nèi)存占用高Windows小圖處理
ImageSharp跨平臺(tái),現(xiàn)代API    學(xué)習(xí)曲線需要跨平臺(tái)支持
內(nèi)存映射內(nèi)存效率高復(fù)雜,僅限BMP超大圖處理
Magick.NET功能強(qiáng)大需要安裝專業(yè)圖像處理

注意事項(xiàng)

1.內(nèi)存管理:處理1GB圖片需要至少2-3GB可用內(nèi)存

2.文件格式:BMP/TIFF適合處理,JPEG可能有壓縮問(wèn)題

3.磁盤空間:確保有足夠空間存放輸出文件

4.異常處理:添加try-catch處理IO和內(nèi)存不足情況

5.性能優(yōu)化:

  • 使用64位應(yīng)用程序
  • 增加GC內(nèi)存限制:<gcAllowVeryLargeObjects enabled="true"/>
  • 分批處理減少內(nèi)存壓力

到此這篇關(guān)于C#實(shí)現(xiàn)將超大圖片(1GB)裁剪為8張小圖片的文章就介紹到這了,更多相關(guān)C#圖片裁剪內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c#讀取excel內(nèi)容內(nèi)容示例分享

    c#讀取excel內(nèi)容內(nèi)容示例分享

    這篇文章主要介紹了c#讀取excel內(nèi)容內(nèi)容示例,要求Excel需是.xls格式,需要的朋友可以參考下
    2014-03-03
  • C#/VB.NET 給Excel添加、刪除數(shù)字簽名的方法

    C#/VB.NET 給Excel添加、刪除數(shù)字簽名的方法

    這篇文章主要介紹了C#/VB.NET 給Excel添加、刪除數(shù)字簽名的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • C#多線程的ResetAbort()方法

    C#多線程的ResetAbort()方法

    這篇文章介紹了C#多線程的ResetAbort()方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#中用管理員身份運(yùn)行程序代碼實(shí)例

    C#中用管理員身份運(yùn)行程序代碼實(shí)例

    這篇文章主要介紹了C#中用管理員身份運(yùn)行程序代碼實(shí)例,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-02-02
  • 詳解C#泛型的類型參數(shù)約束

    詳解C#泛型的類型參數(shù)約束

    這篇文章主要介紹了C#泛型的類型參數(shù)約束的相關(guān)資料,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下
    2020-07-07
  • Unity Shader實(shí)現(xiàn)3D翻頁(yè)效果

    Unity Shader實(shí)現(xiàn)3D翻頁(yè)效果

    這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)3D翻頁(yè)效果,Plane實(shí)現(xiàn)翻頁(yè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 基于WPF平臺(tái)使用純C#實(shí)現(xiàn)動(dòng)態(tài)處理json字符串

    基于WPF平臺(tái)使用純C#實(shí)現(xiàn)動(dòng)態(tài)處理json字符串

    在當(dāng)今的軟件開發(fā)領(lǐng)域,數(shù)據(jù)的交換與存儲(chǔ)變得愈發(fā)頻繁,JSON作為一種輕量級(jí)的數(shù)據(jù)交換格式,在 WPF平臺(tái)開發(fā)的桌面應(yīng)用里,我們常常需要與各種數(shù)據(jù)源交互,動(dòng)態(tài)處理JSON字符串就成為了一項(xiàng)必備技能,本文將深入探討如何在 WPF 平臺(tái)上,僅使用純C#代碼實(shí)現(xiàn)對(duì)JSON字符串的動(dòng)態(tài)處理
    2025-01-01
  • c# EnumHelper枚舉常用操作類

    c# EnumHelper枚舉常用操作類

    在項(xiàng)目中需要把枚舉填充到下拉框中,所以使用統(tǒng)一的方法實(shí)現(xiàn),測(cè)試代碼如下,需要的朋友可以參考下
    2016-11-11
  • 一文帶你搞懂什么是WPF中的依賴屬性

    一文帶你搞懂什么是WPF中的依賴屬性

    依賴屬性是?WPF?的一個(gè)核心概念,它為傳統(tǒng)的?.NET?屬性提供了增強(qiáng)功能,支持綁定、樣式、動(dòng)畫和默認(rèn)值等功能,下面我們就來(lái)看看WPF依賴屬性的具體應(yīng)用吧
    2024-11-11
  • C#中的DataSet、string、DataTable、對(duì)象轉(zhuǎn)換成Json的實(shí)現(xiàn)代碼

    C#中的DataSet、string、DataTable、對(duì)象轉(zhuǎn)換成Json的實(shí)現(xiàn)代碼

    這篇文章主要介紹了C#中的DataSet、string、DataTable、對(duì)象轉(zhuǎn)換成Json的實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2014-09-09

最新評(píng)論