我正在开展一个涉及来自相机的图像的项目。我创建了一个新的class
,我在其中定义了一个方法,我可以调用该方法从图像中提取数据。以下是class
的代码:
class DataFromBitmap
{
static public Bitmap ImageToTreat;
double[] ValeurPixelsExperiment = new double[132];
double[] ValeurPixelsReference = new double[132];
double[] ValeurPixelsSumExperiment = new double[1024];
double[] ValeurPixelsSumReference = new double[1024];
int[] PixelColorCount = new int[256];
int[] PixelColorCountReady = new int[256];
/// <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[1024] under ExpOutput() and RefOutput(), and int[256] 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 maxPointerLength = width * height * bytesPerPixel;
int stride = width * bytesPerPixel;
System.Drawing.Imaging.BitmapData bData = ImageToTreat.LockBits(new System.Drawing.Rectangle(0, 0, ImageToTreat.Width, ImageToTreat.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, ImageToTreat.PixelFormat);
byte* scan0 = (byte*)bData.Scan0.ToPointer();
byte B;
for (int i = 0; i < ImageToTreat.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;
}
ValeurPixelsSumExperiment[i] = ValeurPixelsExperiment.Sum() / 131;
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() / 131;
}
ImageToTreat.UnlockBits(bData);
PixelColorCountReady = PixelColorCount.DeepClone();
}
}
public double[] ExpOutput()
{
return ValeurPixelsSumExperiment;
}
public double[] RefOutput()
{
return ValeurPixelsSumReference;
}
public int[] ColorCountOutput()
{
return PixelColorCountReady;
}
}
你可以看到它并不复杂。不过我有一个问题。我想在创建数组时避免直接使用数字(1024,256 ......)。我宁愿做这样的事情:
double[] ValeurPixelsSumExperiment = new double[ImageToTreat.Width];
如果我想更改传入图像的大小,这将更加方便。问题是,如果我在DataFromBitmap方法中创建这些数组,那么它们最终将不再存在于Output方法中。
有没有一种方便的方法可以避免在我的情况下使用数字?这个特例只是一个例子,我有几个我想要适应的课程。
非常感谢。
答案 0 :(得分:1)
您可以将数组的实例化移动到方法DataFromBitmap
中。在那里你可以访问位图的大小。
所以你会有类似的东西:
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[1024] under ExpOutput() and RefOutput(), and int[256] under ColorCountOutput
/// </summary>
/// <param Bitmap to treat="pImageToTreat"></param>
public DataFromBitmap(Bitmap pImageToTreat)
{
ValeurPixelsSumExperiment = new double[pImageToTreat.Width];
...
答案 1 :(得分:1)
我认为这是完美的情况,您应该使用set
方法而不是简单字段来定义属性:
public static Bitmap ImageToTreat {
set
{
ValeurPixelsExperiment = new double[value.Width];
ImageToTreat = value;
}
}
public double[] ValeurPixelsExperiment { get; private set; }
请注意,两者都必须static
或不是!
您可以将相同的逻辑应用于其余阵列。
答案 2 :(得分:1)
这是一个常见问题,对于此类事物使用类级别或静态类常量是明智的。它允许您在一个地方更改一次
Constants (C# Programming Guide)
常量是在编译时已知的不可变值 不改变计划的生命。常量声明为 const修饰符。只有C#内置类型(不包括 System.Object)可以声明为const。有关内置列表 类型,请参阅内置类型表。用户定义的类型,包括 类,结构和数组不能是const。使用readonly 修饰符,用于创建初始化的类,结构或数组 运行时的时间(例如在构造函数中),之后不能 改变了。
如果你想更频繁地更改它们,你也可以将它们放在配置文件中,即缓冲区大小或类似的东西。然而,对于你所描述的常数似乎很合适
答案 3 :(得分:1)
您可以尝试创建一个表示处理输出的类,它将存储所有数组 - 它们具有高内聚性,只要由单个逻辑构建,因此将此关系显式化会更方便。 然后,您不是将数据存储在字段中并使用单独的方法来访问它们,而只是将结果作为此类的实例从您的方法返回 - 在这种情况下,您将能够根据输入创建适当大小的数组。
作为旁注,在构造函数中执行复杂的逻辑并不是一个好主意,从客户的角度来看并不明显。通常,构造者通常只执行构造所需的动作。根据我的提议,您应该将逻辑转换为方法;否则你将无法退货。