如何将IList <t>映射到位图?</t>

时间:2011-10-19 15:04:01

标签: c# linq

IList在xy平面上包含一组z样本(所有双精度数)。 GetColor()将任意z转换为像素颜色。 我计划缩放IList x和y限制以对应于位图宽度和高度,因为样本数通常不等于像素数。 采集样本作为光栅扫描,因此顺序不同。直到扫描完成,我才知道有多少样本。 有没有一种聪明的方法可以使用LINQ和/或Lambda表达式为每个位图像素找到最接近的IList x和y?

PictureBox pb;
Bitmap bmp = new Bitmap(pb.Width, pb.Height);
IList<Sample> samples = new List<Sample>();
// ... collect samples ...
// Find closest sample
Sample GetSample(int w, int h)
{
    // how to find closest x and y for each w and h?
}
// Map samples to bitmap
for (var w = 0; w < pb.Width; w++) 
{
    for (var h = 0; h < pb.Height; h++)
    {
        var sample = GetSample(w, h);
        var color = GetColor(sample.z, samples.Min().z, samples.Max().z);
        bmp.SetPixel(w, h, color);
    }
}
pb.Image = bmp;
Color GetColor(double z, double minZ, double maxZ)
{
    var red = (int) (255*(z - minZ)/(maxZ - minZ));
    var blue = 255 - red;
    var green = red*blue/65;
    return Color.FromArgb(red, green, blue);
}
// class Sample
public class Sample : IComparable<Sample>
{
    public double z { get; set; }
    public double x { get; set; }
    public double y { get; set; }
    int IComparable<Sample>.CompareTo(Sample s)
    {
        return z < s.z ? -1 : 1;
    }
}

2 个答案:

答案 0 :(得分:2)

也许我提供的方法可以帮助你,它允许找到最接近的数字。

找到最接近的样本的问题是处理以下情况:

w == 1
h == 1

Sample(x = 1, y = 8)
Sample(x = 8, x = 1)

Which one should be considered as closest?

<强>用法:

int closestX = this.FindClosest(samples.Select(p => p.x).ToList(), w);
int closestY = this.FindClosest(samples.Select(p => p.y).ToList(), h);

方式:

public int FindClosest(IList<int> points, int desiredNumber)
{
    int nearest = -1;
    int latestDistance = int.MaxValue;

    foreach (int t in points)
    {
        if (t == desiredNumber)
        {
            return t;
        }

        int currentDistance = Math.Abs(desiredNumber - t);
        if (currentDistance < latestDistance) 
        {                    
            nearest = t;
            latestDistance = currentDistance;
        }
    }

    return nearest;
}

答案 1 :(得分:1)

请记住,lambda只是一个函数,而Linq主要只是将函数应用于内容的循环。不会发生魔法优化。

看起来你问的是如何填写这个功能的主体:

Sample GetSample(int w, int h)
{
    // how to find closest x and y for each w and h?
}

实施应该检查IList<Sample> samples的内容。你怎么把它写成普通的循环代码?

可能您可以使用比普通IList更好的数据结构来优化它。取决于您在搜索samples时需要执行的操作。