29-11-2008 21:37:30
Lựa chọn 1 vùng giống magic wand trong photo shop
Đây là kỹ thuật khó. Ban đầu chúng ta sẽ xuất phát từ 1 điểm, nếu điểm bên cạnh có màu tương đương. Tức là hiệu của màu nằm trong 1 ngưỡng nào đó giả sử là distance thì coi như chúng có màu tương đương. Với 2 màu tương đương ở cạnh nhau ta mở rộng vùng được chọn. Như vậy Load Selection sẽ từ 1 điểm lan ra các phía để tạo thành vùng selêction kết quả là 1 mảng int với tọa độ chính là tọa độ x,y của vùng trên ảnh.
Code
--------------------------------------
private static bool Inbound(int x, int y, int wid, int hei)
{
if (x < 0 || x >= wid) return false;
if (y < 0 || y >= hei) return false;
return true;
}
public static int[,] LoadSelection(Bitmap source, int start_x, int start_y)
{
Color c = source.GetPixel(start_x, start_y);
int wid = source.Width;
int hei = source.Height;
int[,] sel = new int[wid, hei];
for (int x = 0; x < wid; x++)
{
for (int y = 0; y < hei; y++)
sel[x, y] = 0;
}
for (int x = 0; x < wid; x++)
{
for (int y = 0; y < hei; y++)
sel[x, y] = 0;
}
sel[start_x, start_y] = 1;
Stack st = new Stack();
st.Push(new Point(start_x, start_y));
do
{
Point p = (Point)st.Pop();
Color c2 = source.GetPixel(p.X, p.Y);
if (System.Math.Abs(c2.R - c.R) < distance)
{
int x = p.X;
int y = p.Y;
sel[x, y] = 1;
if (Inbound(x - 1, y, wid, hei))
if(sel[x-1, y] == 0) st.Push(new Point(x - 1, y));
if (Inbound(x + 1, y, wid, hei))
if (sel[x + 1, y] == 0) st.Push(new Point(x + 1, y));
if (Inbound(x, y - 1, wid, hei))
if (sel[x, y - 1] == 0) st.Push(new Point(x, y - 1));
if (Inbound(x, y + 1, wid, hei))
if (sel[x, y + 1] == 0) st.Push(new Point(x, y + 1));
}
}
while (st.Count > 0);
return sel;
}
---