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 对象将每个块绘制到最终图像上。

保存合并后的完整图像。

相关推荐
阿波罗尼亚22 分钟前
ExcelUtils实现 设置内容 插入行 复制行列格式
java·开发语言
我不是程序猿儿1 小时前
【C#】观察者模式 + UI 线程调度、委托讲解
观察者模式·ui·c#
专注VB编程开发20年1 小时前
c# .net支持 NativeAOT 或 Trimming 的库是什么原理
前端·javascript·c#·.net
啊吧怪不啊吧2 小时前
C++之list类的代码及其逻辑详解 (中)
开发语言·数据结构·c++·list
钢铁男儿2 小时前
C# 简单工厂模式(简单工厂模式如何工作)
前端·c#·简单工厂模式
THMAIL2 小时前
大模型0基础开发入门与实践:第11章 进阶:LangChain与外部工具调用
开发语言·langchain·php
hfd19902 小时前
JavaScript 性能优化实战技术文章大纲
开发语言·javascript·性能优化
楼田莉子3 小时前
C++算法学习专题:滑动窗口
开发语言·数据结构·c++·学习·算法·leetcode
炸膛坦客3 小时前
C++ 学习与 CLion 使用:(四)常量和变量,包括字面常量和符号常量
开发语言·c++·学习
java1234_小锋3 小时前
说说你对Integer缓存的理解?
java·开发语言