如何用颜色填充图像的一部分? [英] How can i fill part of image with color?

查看:113
本文介绍了如何用颜色填充图像的一部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有添加在表单中的图像。如何填充图像的一部分?

I have image which i add in my form.How can i fill part of image?

我有此图像

我有什么正在尝试实现:

What I'm trying to achieve:

推荐答案

填充区域,您需要执行常规的食物填充程序。

To floodfill an area you need a foodfill routine and very little else.

请参见以下示例:

它使用两个图片框,也使用一个标签显示所选的颜色。

It uses two pictureboxes, also a label to display the chosen color.

和两个鼠标单击事件,一个用于选择颜色:

And two mouse click events, one to pick the color:

private void pictureBoxPalette_MouseClick(object sender, MouseEventArgs e)
{
    Point sPt = scaledPoint(pictureBoxPalette, e.Location);
    lbl_color.BackColor = ((Bitmap)pictureBoxPalette.Image).GetPixel(sPt.X, sPt.Y);
}

..和调用填充的人:

..and one to call the fill:

private void pictureBoxTgt_MouseClick(object sender, MouseEventArgs e)
{
    Point sPt = scaledPoint(pictureBoxTgt, e.Location);
    Bitmap bmp = (Bitmap)pictureBoxTgt.Image;
    Color c0 = bmp.GetPixel(sPt.X, sPt.Y); 
    Fill4(bmp, sPt, c0, lbl_color.BackColor);
    pictureBoxTgt.Image = bmp;
}

Floodfill例程取自此信息;它基本上是维基百科算法的直接实现。.:

The Floodfill routine is taken from this post; it is basically a direct implementation of a wikipedia algorithm..:

static void Fill4(Bitmap bmp, Point pt, Color c0, Color c1)
{
    Color cx = bmp.GetPixel(pt.X, pt.Y);
    if (cx.GetBrightness() < 0.01f) return;  // optional, to prevent filling a black grid
    Rectangle bmpRect = new Rectangle(Point.Empty, bmp.Size);
    Stack<Point> stack = new Stack<Point>();
    int x0 = pt.X;
    int y0 = pt.Y;

    stack.Push(new Point(x0, y0) );
    while (stack.Any() )
    {
        Point p = stack.Pop();
        if (!bmpRect.Contains(p)) continue;
        cx = bmp.GetPixel(p.X, p.Y);
        if (cx == c0)
        {
            bmp.SetPixel(p.X, p.Y, c1);
            stack.Push(new Point(p.X, p.Y + 1));
            stack.Push(new Point(p.X, p.Y - 1));
            stack.Push(new Point(p.X + 1, p.Y));
            stack.Push(new Point(p.X - 1, p.Y));
        }
    }
}

更新

我更新了代码,以包含将鼠标单击位置缩放到图像像素点的功能;现在它也可以与 SizeMode = StretchImage 一起使用,因此您可以处理整个图像。

I have updated the code to include a function that will scale a mouse click location to an image pixel point; now it will work with SizeMode=StretchImage as well, so you can work on the whole image..

static Point scaledPoint(PictureBox pb, Point pt)
{
    float scaleX = 1f * pb.Image.Width / pb.ClientSize.Width;
    float scaleY = 1f * pb.Image.Height / pb.ClientSize.Height;
    return  new Point((int)(pt.X * scaleX), (int)(pt.Y * scaleY));
}

当然,您可以保存图像。

Of course you can then save the Image.

请注意,您的原始图像为4bpp,并且在着色之前必须转换为24bpp或更高。.

Note that your original image is 4bpp and must be converted to 24bpp or better before coloring..

也请注意,对于 SizeMode = Zoom 的计算要复杂得多。这是一个可以与任何 SizeMode 一起使用的示例:

Also note that for SizeMode=Zoom the calculations are a little more involved. Here is an example that should work with any SizeMode.:

static Point scaledPoint(PictureBox pbox, Point pt)
{
    Size si = pbox.Image.Size;
    Size sp = pbox.ClientSize;
    int left = 0;
    int top = 0;

    if (pbox.SizeMode == PictureBoxSizeMode.Normal ||
        pbox.SizeMode == PictureBoxSizeMode.AutoSize) return pt;
    if (pbox.SizeMode == PictureBoxSizeMode.CenterImage)
    {
        left = (sp.Width - si.Width) / 2;
        top = (sp.Height - si.Height) / 2;
        return new Point(pt.X - left, pt.Y - top);
    }                   
    if (pbox.SizeMode == PictureBoxSizeMode.Zoom)
    {
        if (1f * si.Width / si.Height < 1f * sp.Width / sp.Height)
            left = (sp.Width - si.Width * sp.Height / si.Height) / 2;
        else
            top = (sp.Height - si.Height * sp.Width / si.Width) / 2;
    }

    pt = new Point(pt.X  - left, pt.Y - top);
    float scaleX = 1f * pbox.Image.Width / (pbox.ClientSize.Width - 2 * left) ;
    float scaleY = 1f * pbox.Image.Height / (pbox.ClientSize.Height - 2 * top);
    return new Point((int)(pt.X * scaleX), (int)(pt.Y * scaleY));
}

这篇关于如何用颜色填充图像的一部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆