You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# Bitmap数据处理类中避免使用硬编码数值

解决动态图像尺寸下数组初始化的问题

嘿,这问题其实很好搞定——核心就是把数组的声明和初始化分开,让数组字段在构造函数里根据图像的动态尺寸来创建,这样输出方法就能正常访问啦。我给你一步步拆解解决方案:

关键修改思路

  • 把原来硬编码初始化的数组字段,改成只做声明(不指定长度)
  • 在构造函数里,根据ImageToTreat的Width、以及你需要的行范围长度,动态初始化每个数组
  • 顺便把代码里硬编码的数值(比如131)也改成动态计算的,彻底摆脱硬编码的限制

修改后的完整代码

class DataFromBitmap 
{
    static public Bitmap ImageToTreat;
    // 只声明数组,不初始化长度
    double[] ValeurPixelsExperiment;
    double[] ValeurPixelsReference;
    double[] ValeurPixelsSumExperiment;
    double[] ValeurPixelsSumReference;
    int[] PixelColorCount;
    int[] PixelColorCountReady;

    /// <summary>
    /// Retrieves data from an input bitmap. Retrieved data : Ref and Exp pixel column mean values and count of each color level population. Output : double[] under ExpOutput() and RefOutput(), and int[] under ColorCountOutput
    /// </summary>
    /// <param Bitmap to treat="pImageToTreat"></param>
    public DataFromBitmap(Bitmap pImageToTreat) 
    {
        ImageToTreat = pImageToTreat;
        unsafe 
        {
            int width = ImageToTreat.Width;
            int height = ImageToTreat.Height;
            int bytesPerPixel = 1;
            int stride = width * bytesPerPixel;

            // 动态计算需要的数组长度,替代硬编码数值
            int experimentRowRange = 288 - 157; // 对应原来的131
            int referenceRowRange = 615 - 484; // 同样是131,这里也动态计算
            int colorLevelCount = 256; // 如果这个也需要动态,可根据PixelFormat调整

            // 动态初始化所有数组
            ValeurPixelsExperiment = new double[experimentRowRange];
            ValeurPixelsReference = new double[referenceRowRange];
            ValeurPixelsSumExperiment = new double[width];
            ValeurPixelsSumReference = new double[width];
            PixelColorCount = new int[colorLevelCount];
            PixelColorCountReady = new int[colorLevelCount];

            System.Drawing.Imaging.BitmapData bData = ImageToTreat.LockBits(
                new System.Drawing.Rectangle(0, 0, width, height), 
                System.Drawing.Imaging.ImageLockMode.ReadWrite, 
                ImageToTreat.PixelFormat);
            byte* scan0 = (byte*)bData.Scan0.ToPointer();
            byte B;

            for (int i = 0; i < width; i++) 
            {
                // 处理实验像素行
                for (int j = 157; j < 288; j++) 
                {
                    int Pixel = bytesPerPixel * i + stride * j;
                    B = scan0[Pixel + 0];
                    ValeurPixelsExperiment[j - 157] = B;
                    PixelColorCount[B] += 1;
                }
                // 用动态计算的长度替代硬编码的131
                ValeurPixelsSumExperiment[i] = ValeurPixelsExperiment.Sum() / (experimentRowRange - 1);

                // 处理参考像素行
                for (int j = 484; j < 615; j++) 
                {
                    int Pixel = bytesPerPixel * i + stride * j;
                    B = scan0[Pixel + 0];
                    ValeurPixelsReference[j - 484] = B;
                    PixelColorCount[B] += 1;
                }
                ValeurPixelsSumReference[i] = ValeurPixelsReference.Sum() / (referenceRowRange - 1);
            }

            ImageToTreat.UnlockBits(bData);
            PixelColorCountReady = PixelColorCount.DeepClone();
        }
    }

    public double[] ExpOutput() 
    {
        return ValeurPixelsSumExperiment;
    }

    public double[] RefOutput() 
    {
        return ValeurPixelsSumReference;
    }

    public int[] ColorCountOutput() 
    {
        return PixelColorCountReady;
    }
}

重点说明

  1. 数组字段的声明:把原来带硬编码长度的初始化去掉,只保留字段类型和名称,这样我们就能在构造函数里动态分配内存。
  2. 动态长度计算:
    • ValeurPixelsSumExperiment和ValeurPixelsSumReference的长度直接用width(也就是ImageToTreat.Width),完美适配不同宽度的图像。
    • 对于ValeurPixelsExperiment这类依赖行范围的数组,我们用288-157计算出长度,避免硬编码131,后续如果行范围调整,只需要改这两个数字就行。
  3. 输出方法的访问性:因为数组字段是类的成员变量,构造函数初始化后,ExpOutput()等方法自然能访问到这些数组,完全没问题。

另外提个小建议:ImageToTreat设为static可能会有线程安全问题,如果你的项目是多线程处理图像,最好改成实例字段哦。

内容的提问来源于stack exchange,提问作者Trion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:13:43