使用图像填充纹理笔刷,而不是平铺。

3
我有一款纹理笔刷,它使用特定的图像来制作纹理,使其显示如下:
Image image = new Bitmap("Untitled.png");
for (int i = 0; i < points.Count; i++)
{
    using (TextureBrush tbr = new TextureBrush(image))
    {
          tbr.RotateTransform(i * 4);
          var p = PointToClient(Cursor.Position);
          tbr.Transform = new Matrix(
          75.0f / 640.0f,
          0.0f,
          0.0f,
          75.0f / 480.0f,
          0.0f,
          0.0f);
          e.Graphics.FillEllipse(tbr, p.X - 50, p.Y - 50, 100, 100);
          Pen p3 = new Pen(tbr);
          e.Graphics.DrawEllipse(Pens.DeepSkyBlue, p.X - 50, p.Y - 50, 100, 100);
    }
}

下面是它正在使用的图片:

Image

这就是最终效果:

Initial

我希望图片填满圆形,看起来像这样(编辑后的图片):

Final

任何帮助都将不胜感激。


这是一个与http://stackoverflow.com/questions/26845921/draw-image-into-shape 重复的问题吗? - Nige Jones
2
你为什么要在变换时将画笔缩小那么多? - Dan Byström
1个回答

5

你需要使用正确的数字进行缩放。

如果你想要一个尺寸为 width * height 像素的图像填充直径为 d 的圆形,你应该按以下方式进行缩放:

 int diameter = 100;
 Image image = new Bitmap(yourImage);
 float scaleX = 1f * diameter / image.Size.Width;
 float scaleY = 1f * diameter / image.Size.Height;

请注意,您的TextureBrush将始终显示来自您的图像的平铺。对于您的原始问题,这似乎是可以接受的,特别是在旋转图像以消除任何伪影时。
但是,在这里,这可能不是您想要的。
如果您希望图像跟随鼠标移动,则需要绘制它。
以下是一个示例,使用复选框在平铺和绘制之间进行切换。动画仅使用一帧: enter image description here
    for (int i = 0; i < points.Count; i++)
    {
        using (TextureBrush tbr = new TextureBrush(image))
        {
            tbr.RotateTransform(i * 4);   // optional
            var p = PointToClient(Cursor.Position);
            tbr.Transform = new Matrix(
                scaleX,
                0.0f,
                0.0f,
                scaleY,
                0.0f,
                0.0f);
            // any tile mode will work, though not all the same way
            tbr.WrapMode = WrapMode.TileFlipXY;
            if (cbx_tileFunny.Checked)
                e.Graphics.FillEllipse(tbr, p.X - diameter/2, 
                                            p.Y - diameter/2, diameter, diameter);
            else
            {
               ((Bitmap)image).SetResolution(e.Graphics.DpiX, e.Graphics.DpiY);   // (**)
                e.Graphics.ScaleTransform(scaleX, scaleY);
                e.Graphics.DrawImage( image, (p.X - diameter/2) / scaleX,
                                             (p.Y - diameter/2 ) / scaleY);
                e.Graphics.ResetTransform();

            }
                /// ? Pen p3 = new Pen(tbr);
                e.Graphics.DrawEllipse(Pens.DeepSkyBlue, p.X - diameter/2,
                                       p.Y - diameter/2, diameter, diameter);
        }
    }

请注意,如果图像的dpi设置与您的屏幕不同,则需要进行额外的缩放(**)。

此外:通常建议快速创建和处理笔和画刷,但是当我们付出这么多努力来创建画刷和/或图像时,缓存它们甚至一系列它们似乎更可取,我个人认为。


非常感谢您的回答。它帮了我很多,我只有一个问题想问您,您是如何将图像变成圆形的?我的图像仍然有白色的角落。 - Cleaven
你是使用白色背景吗? - Cleaven
不用担心,我已经解决了,再次感谢你! :) - Cleaven
1
我在 Photoshop 中将角落变成了透明的 :-) - TaW
你有看过我们的聊天吗? - Cleaven
好的 :-) 我今天得离开了,晚上回来会接着处理。 - TaW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接