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

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

 更新時(shí)間:2025年05月18日 10:06:32   作者:MartinYangHJ  
C#處理超大圖片(1GB)需要特別注意內(nèi)存管理和性能優(yōu)化,這篇文章為大家整理了4種常見的處理方法,并進(jìn)行了對比,大家可以根據(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);
        }
 
        // 獲取圖片尺寸但不加載全部內(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)代跨平臺方案)

首先安裝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)使用場景
System.Drawing內(nèi)置庫,簡單內(nèi)存占用高Windows小圖處理
ImageSharp跨平臺,現(xiàn)代API    學(xué)習(xí)曲線需要跨平臺支持
內(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可能有壓縮問題

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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c# 實(shí)例——繪制波浪線(附源碼)

    c# 實(shí)例——繪制波浪線(附源碼)

    這篇文章主要介紹了c#如何繪制波浪線,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • C# 類庫打包dll文件的操作流程

    C# 類庫打包dll文件的操作流程

    在C#中,有多種方式可以對代碼進(jìn)行加密,以保護(hù)源代碼不被輕易查看或修改,這篇文章主要介紹將C# cs類文件加密為dll文件的方式進(jìn)行保護(hù),感興趣的朋友一起看看吧
    2025-03-03
  • C# Socket文件上傳至服務(wù)器的操作方法

    C# Socket文件上傳至服務(wù)器的操作方法

    文件上傳有FTP、WebApi、WebService等等,這次我們來實(shí)現(xiàn)一個(gè)基于socket通信的本地客戶端上傳文件到服務(wù)器的例子,這篇文章主要介紹了C# Socket文件上傳至服務(wù)器的操作方法,需要的朋友可以參考下
    2024-05-05
  • C# WPF自制白板工具

    C# WPF自制白板工具

    著電子屏幕技術(shù)的發(fā)展,普通的黑板已不再適用現(xiàn)在的教學(xué)和演示環(huán)境,電子白板應(yīng)運(yùn)而生,本文將通過C# WPF自制一個(gè)白板工具,感興趣的可以了解下
    2024-11-11
  • 一文搞懂C#實(shí)現(xiàn)讀寫文本文件中的數(shù)據(jù)

    一文搞懂C#實(shí)現(xiàn)讀寫文本文件中的數(shù)據(jù)

    這篇文章重點(diǎn)給大家介紹C#實(shí)現(xiàn)讀寫文本文件中的數(shù)據(jù)的一些知識,讀取.txt文件數(shù)據(jù)的實(shí)例代碼及寫入讀取過程完整代碼,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • C#閃退問題的排查全攻略

    C#閃退問題的排查全攻略

    作為 C# 開發(fā)者,最令人頭疼的莫過于程序在沒有任何報(bào)錯(cuò)提示的情況下瞬間閃退,本文將帶你從開發(fā)環(huán)境到生產(chǎn)環(huán)境,由淺入深地掌握排查 C# 閃退問題的四大絕招,需要的朋友可以參考下
    2025-12-12
  • C#使用Linq to XML進(jìn)行XPath查詢的代碼實(shí)現(xiàn)

    C#使用Linq to XML進(jìn)行XPath查詢的代碼實(shí)現(xiàn)

    最近在用到HtmlAgliltyPack進(jìn)行結(jié)點(diǎn)查詢時(shí),發(fā)現(xiàn)這里選擇結(jié)點(diǎn)使用的是XPath,所以這里總結(jié)一下在C#中使用XPath查詢XML的方法,習(xí)慣了用Linq,這里也是用的Linq to xml的,需要的朋友可以參考下
    2024-08-08
  • 使用C#進(jìn)行音頻處理的完整指南(從播放到編輯)

    使用C#進(jìn)行音頻處理的完整指南(從播放到編輯)

    在現(xiàn)代應(yīng)用程序中,音頻處理已經(jīng)成為不可或缺的一部分,無論是開發(fā)一個(gè)簡單的音頻播放器,還是構(gòu)建一個(gè)復(fù)雜的音頻編輯工具,C#都提供了豐富的工具和庫來實(shí)現(xiàn)這些功能,通過本文,我們將深入探索如何在C#中進(jìn)行音頻播放、錄制、編輯、格式轉(zhuǎn)換以及音頻分析
    2025-04-04
  • 淺談c# 浮點(diǎn)數(shù)計(jì)算

    淺談c# 浮點(diǎn)數(shù)計(jì)算

    本文通過具體的示例給大家演示了下C#中浮點(diǎn)數(shù)運(yùn)算所遇到的問題及解決方法,有需要的小伙伴可以參考下
    2017-09-09
  • 詳解如何實(shí)現(xiàn)C#和Python間實(shí)時(shí)視頻數(shù)據(jù)交互

    詳解如何實(shí)現(xiàn)C#和Python間實(shí)時(shí)視頻數(shù)據(jù)交互

    我們在做RTSP|RTMP播放的時(shí)候,遇到好多開發(fā)者,他們的視覺算法大多運(yùn)行在python下,需要高效率的實(shí)現(xiàn)C#和Python的視頻數(shù)據(jù)交互,本文給大家總結(jié)了一些常用的方法,感興趣的小伙伴跟著小編一起來看看吧
    2024-10-10

最新評論

扶绥县| 道真| 惠东县| 洪泽县| 大关县| 浙江省| 天长市| 渑池县| 长宁区| 孟州市| 定安县| 苏尼特左旗| 昌乐县| 弥勒县| 喜德县| 交口县| 册亨县| 伊金霍洛旗| 兴山县| 准格尔旗| 嘉义市| 永康市| 天门市| 西乌| 乾安县| 清丰县| 高淳县| 巴彦县| 将乐县| 金昌市| 乐平市| 泰宁县| 大同市| 克什克腾旗| 宜川县| 西宁市| 腾冲县| 阆中市| 荆门市| 嘉黎县| 虎林市|