C# 如何在WindowsForms Picturebox上绘制字符串?
我有自己的简单3d引擎类(C# 如何在WindowsForms Picturebox上绘制字符串?,c#,winforms,graphics,bitmap,C#,Winforms,Graphics,Bitmap,我有自己的简单3d引擎类(myGraphics),它将结果保存在位图变量中。 然后将该位图放置在PictureBox中(PictureBox.Image=myGraphics.bmp) 这是工作得很好,问题来了,当我需要在图纸上标记一些点。由于没有内置的方法在位图上绘制字符串,我遵循了类似问题的解决方案,现在我在myGraphics上得到了一个Graphics变量,因此我可以在那里绘制数字。代码的重要部分如下所示: public class myGraphics { public Gra
myGraphics
),它将结果保存在位图变量中。
然后将该位图放置在PictureBox中(PictureBox.Image=myGraphics.bmp
)
这是工作得很好,问题来了,当我需要在图纸上标记一些点。由于没有内置的方法在位图上绘制字符串,我遵循了类似问题的解决方案,现在我在myGraphics
上得到了一个Graphics
变量,因此我可以在那里绘制数字。代码的重要部分如下所示:
public class myGraphics
{
public Graphics g;
public void initialize(int W, int H )
{
//sets some values
g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
}
public void draw()
{
// code to draw on myGraphics.bmp
markpoints();
}
public void markpoints()
{
if (draw_points) {
foreach (objecto ob in solidos) {
for (int p = 0; p < ob.viewpoints.Count; p++)
{
// determine position of text (x, y)
SolidBrush drawBrush = new SolidBrush(Color.Black);
g.DrawString(p.ToString(), new Font("Arial", 10), drawBrush, x, y);
g.Flush();
}
}
}
}
公共类myGraphics
{
公共图形g;
公共无效初始化(整数W,整数H)
{
//设置一些值
g=图形。来自图像(bmp);
g、 SmoothingMode=SmoothingMode.AntiAlias;
g、 插值模式=插值模式。高质量双三次;
g、 PixelOffsetMode=PixelOffsetMode.HighQuality;
}
公众抽签()
{
//在myGraphics.bmp上绘制的代码
标记点();
}
公共无效标记点()
{
如果(绘制点){
foreach(以solidos表示的对象对象){
for(int p=0;p
现在,如果我做对了,g.Flush()应该合并位图上的图形g,但它不是这样工作的,所以我得到了正确的图像,但没有刺痛
我还尝试了以下方法:myGraphics.g=PictureBox.CreateGraphics();
来解决这个问题。在调试模式下使用断点,我意识到字符串确实会使用此方法显示在控件上,但在PictureBox更新后会立即被删除
那么,我该如何解决这个问题,才能得到图形上显示的数字呢?当更新
PictureBox.Image
时,图形将被清除。因此,必须在更新PictureBox.Image
之后,从类外调用markpoints()
另外,分配myGraphics.g=Picturebox.CreateGraphics()
无效,myGraphics.g上的更改将不会更新到控件Picturebox。控件的图形必须在绘制事件时更新,并将e.graphics
传递到标记点
另外,g.flush()
不会将图形与位图合并,这段代码实际上没有必要
因此,最终的解决方案是:
public class myGraphics
{
// public Graphics g is no longer necessary
public void initialize(int W, int H ) { //sets some values}
public void draw() { // code to draw on myGraphics.bmp }
public void markpoints(Graphics graph)
{
if (draw_points) {
graph.SmoothingMode = SmoothingMode.AntiAlias;
graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
graph.PixelOffsetMode = PixelOffsetMode.HighQuality;
foreach (objecto ob in solidos) {
for (int p = 0; p < ob.viewpoints.Count; p++)
{
// determine position of text (x, y)
SolidBrush drawBrush = new SolidBrush(Color.Black);
g.DrawString(p.ToString(), new Font("Arial", 10), drawBrush, x, y);
}
}
}
}
}
// Connect to picture box
myGraphics mg = new myGraphics()
Picturebox.Image = mg.bmp;
PictureBox.Invalidate(); // forces update of the control using paint event
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
mg.markpoints(e.Graphics);
}
公共类myGraphics
{
//不再需要公共图形g
公共void初始化(intw,inth){//设置一些值}
public void draw(){//在myGraphics.bmp上绘制的代码}
公共空心标记点(图形)
{
如果(绘制点){
graph.SmoothingMode=SmoothingMode.AntiAlias;
graph.InterpolationMode=InterpolationMode.HighQualityBicubic;
graph.PixelOffsetMode=PixelOffsetMode.HighQuality;
foreach(以solidos表示的对象对象){
for(int p=0;p
您正在修改位图,但PictureBox无法知道这一点。Image类没有事件。因此它不知道需要重新绘制图像。这取决于您是否调用PictureBox“Invalidate()方法,现在它知道了。这不是问题所在,但它让我明白了,所以谢谢。这是一个愚蠢的错误,我仍然会用PictureBox.CreateGraphics()编写一个答案足以解决问题不,很可能这还不够,因为结果不会持续..要么绘制到图像中,要么使用绘画事件中的e.Graphics对象..@TaW我无法分配e.Graphics()=myGraphics.g
,因为e.Graphics
是只读的…这是否意味着我必须放置标记点()
paint事件中的代码?是。或者您可以将e.Graphics
对象传递给使用它进行绘图的函数,例如markpoints(e.Graphics)
。请注意,必须从Paint
事件调用此函数,不允许存储或缓存它,否则它将无效!谢谢,它工作正常,性能也更好。我是否应该更新我的答案?我是新来的,所以。。。