C# new Bitmap(32043, 32043, PixelFormat.Format32bppArgb)报错:参数无效,如何将图像分块化处理?

C#处理非常大的图像(如 32043x32043 像素)时,确实需要采取分块化处理的方法来避免内存不足的问题。分块化处理可以将大图像分割成多个较小的块,分别进行处理和保存,最后再合并这些块以形成完整的图像。以下是一个详细的示例,展示如何在C#中使用 System.Drawing 和 Bitmap 类来实现这一目标。

步骤

定义块大小:选择合适的块大小,确保每个块可以在内存中处理。

创建和处理块:遍历整个图像区域,逐块创建、处理并保存每个块。

合并块:如果需要,可以将这些块合并成一个完整的图像文件。

示例代码

以下是一个完整的示例代码,展示了如何将大图像分块化处理:

复制代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;

class Program
{
    static void Main()
    {
        int width = 32043;
        int height = 32043;
        int chunkSize = 8192; // 每个块的大小,可以根据内存情况调整

        string outputFolder = "./chunks";
        string outputFile = "./output/large_image.png";

        // 创建输出文件夹
        Directory.CreateDirectory(outputFolder);

        // 分块处理图像
        ProcessImageInChunks(width, height, chunkSize, outputFolder);

        // 合并块(可选)
        MergeChunksIntoSingleImage(width, height, chunkSize, outputFolder, outputFile);
    }

    static void ProcessImageInChunks(int width, int height, int chunkSize, string outputFolder)
    {
        for (int y = 0; y < height; y += chunkSize)
        {
            for (int x = 0; x < width; x += chunkSize)
            {
                int chunkWidth = Math.Min(chunkSize, width - x);
                int chunkHeight = Math.Min(chunkSize, height - y);

                using (Bitmap chunk = new Bitmap(chunkWidth, chunkHeight, PixelFormat.Format32bppArgb))
                {
                    // 处理每个块(例如,填充颜色)
                    using (Graphics g = Graphics.FromImage(chunk))
                    {
                        g.Clear(Color.White); // 设置背景颜色
                        // 可以在这里添加更多的图像处理逻辑
                    }

                    // 保存块到文件
                    string chunkFileName = $"{outputFolder}/chunk_{x}_{y}.png";
                    chunk.Save(chunkFileName, ImageFormat.Png);
                    Console.WriteLine($"Saved chunk: {chunkFileName}");
                }
            }
        }
    }

    static void MergeChunksIntoSingleImage(int width, int height, int chunkSize, string inputFolder, string outputFile)
    {
        using (Bitmap finalImage = new Bitmap(width, height, PixelFormat.Format32bppArgb))
        {
            for (int y = 0; y < height; y += chunkSize)
            {
                for (int x = 0; x < width; x += chunkSize)
                {
                    int chunkWidth = Math.Min(chunkSize, width - x);
                    int chunkHeight = Math.Min(chunkSize, height - y);

                    string chunkFileName = $"{inputFolder}/chunk_{x}_{y}.png";
                    using (Bitmap chunk = new Bitmap(chunkFileName))
                    {
                        using (Graphics g = Graphics.FromImage(finalImage))
                        {
                            g.DrawImage(chunk, new Rectangle(x, y, chunkWidth, chunkHeight));
                        }
                    }
                }
            }

            // 保存最终图像
            finalImage.Save(outputFile, ImageFormat.Png);
            Console.WriteLine($"Merged image saved to {outputFile}");
        }
    }
}

解释

  • 定义参数:

width 和 height:图像的总尺寸。

chunkSize:每个块的大小,可以根据可用内存调整。

outputFolder:保存块的文件夹。

outputFile:合并后的完整图像文件路径。

  • 创建输出文件夹:

使用 Directory.CreateDirectory(outputFolder) 创建保存块的文件夹。

  • 分块处理图像:

ProcessImageInChunks 方法遍历整个图像区域,逐块创建、处理并保存每个块。

每个块的宽度和高度根据剩余的图像尺寸计算。

使用 Graphics 对象处理每个块(例如,填充颜色)。

将每个块保存为单独的 PNG 文件。

  • 合并块:

MergeChunksIntoSingleImage 方法遍历所有块,并将它们合并成一个完整的图像。

使用 Graphics 对象将每个块绘制到最终图像上。

保存合并后的完整图像。

相关推荐
hez201020 小时前
在 .NET 上构建超大托管数组
c#·.net·.net core·gc·clr
雨落倾城夏未凉6 天前
第四章c#方法-参数数组和可选参数(16)
后端·c#
唐青枫7 天前
线程不是越多越快:C#.NET Thread 生命周期、同步与后台工作线程实战
c#·.net
唐青枫8 天前
别只会反射:C#.NET Emit 动态生成代码实战详解
c#·.net
咕白m6258 天前
.NET 环境下 Word 超链接批量提取方案
c#·.net
用户91721561902118 天前
C# 通信协议增量解析:用状态机处理半包和粘包
c#
小码编匠9 天前
C# 工控上位机必备:数据转换工具类与十个核心模块
后端·c#·.net
唐青枫11 天前
别再乱用 StartNew:C#.NET TaskFactory 任务调度实战详解
c#·.net
Artech11 天前
[MAF预定义的AIContextProvider-03]ChatHistoryMemoryProvider——赋予Agent从经验中学习的能力
ai·c#·agent·memory·maf
Scout-leaf13 天前
C#摸鱼实录——IoC与DI案例详解
c#