使用图像而不是平铺填充纹理画笔
Fill texture brush using image, not tile
我有一个纹理画笔,它使用特定图像使纹理显示如下:
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);
}
}
这是它使用的图像:
结果是这样的:
我希望图像填满圆圈,使其看起来像这样(编辑后的图像):
如有任何帮助,我们将不胜感激。
您需要使用正确的数字进行缩放。
如果您想要一个尺寸 = 宽度 * 高度像素的图像来填充一个直径的圆,您应该像这样缩放:
int diameter = 100;
Image image = new Bitmap(yourImage);
float scaleX = 1f * diameter / image.Size.Width;
float scaleY = 1f * diameter / image.Size.Height;
但是请注意,您的 TextureBrush
将始终显示由您的图像制作的 平铺。这对您的 original question 来说似乎没问题,尤其是在尾部旋转图像以消除任何伪影时。
但这里可能根本不是你想要的。
如果你想让图像跟随鼠标,你需要绘制它。
这是一个示例,它使用复选框在平铺和绘图之间切换 .动画只用了一帧:
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 设置与您的屏幕不同,请注意此处需要的额外缩放 (**)。
此外:虽然快速创建和处理钢笔和画笔通常是个好主意,但在创建画笔时花费了很多精力 and/or 将它们甚至一系列图像缓存起来似乎更可取, 我。
我有一个纹理画笔,它使用特定图像使纹理显示如下:
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);
}
}
这是它使用的图像:
结果是这样的:
我希望图像填满圆圈,使其看起来像这样(编辑后的图像):
如有任何帮助,我们将不胜感激。
您需要使用正确的数字进行缩放。
如果您想要一个尺寸 = 宽度 * 高度像素的图像来填充一个直径的圆,您应该像这样缩放:
int diameter = 100;
Image image = new Bitmap(yourImage);
float scaleX = 1f * diameter / image.Size.Width;
float scaleY = 1f * diameter / image.Size.Height;
但是请注意,您的 TextureBrush
将始终显示由您的图像制作的 平铺。这对您的 original question 来说似乎没问题,尤其是在尾部旋转图像以消除任何伪影时。
但这里可能根本不是你想要的。
如果你想让图像跟随鼠标,你需要绘制它。
这是一个示例,它使用复选框在平铺和绘图之间切换 .动画只用了一帧:
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 设置与您的屏幕不同,请注意此处需要的额外缩放 (**)。
此外:虽然快速创建和处理钢笔和画笔通常是个好主意,但在创建画笔时花费了很多精力 and/or 将它们甚至一系列图像缓存起来似乎更可取, 我。