C# 位图绘制不会渲染到屏幕上

发布于 2024-12-02 19:22:03 字数 2899 浏览 2 评论 0原文

我正在尝试编写一个与平板电脑一起使用的绘图程序。为此,我需要在压力下使用衰减和透明度。所以我使用 C# 中的位图系统来构建图像。

我目前似乎无法让我的绘图代码显示任何内容。它正在被渲染到图片框。我知道有一些内容被输入到位图中,因为当我保存位图时它会显示出来。

我浏览过几乎所有 C# 绘图问题都涉及使用线条图或椭圆图而不是位图

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace paint1
{
    public partial class Form2 : Form
    {
        public Bitmap m_bitmap;
        public bool m_penDown;
        public int m_lastX;
        public int m_lastY;
        public int m_currentX;
        public int m_currentY;

        public Form2()
        {
            InitializeComponent();

            // Create the bitmap area
            m_bitmap = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            m_penDown = false;

            Graphics m_graphics = Graphics.FromImage(m_bitmap);
            m_lastX = System.Windows.Forms.Cursor.Position.X;
            m_lastY = System.Windows.Forms.Cursor.Position.Y;
            m_currentX = System.Windows.Forms.Cursor.Position.X;
            m_currentY = System.Windows.Forms.Cursor.Position.Y;
        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }

        private void Form2_Paint(object sender, PaintEventArgs e)
        {
            Graphics objGraphics;
            //You can't modify e.Graphics directly.
            objGraphics = e.Graphics;
            // Draw the contents of the bitmap on the form.
            objGraphics.DrawImage(m_bitmap, 0, 0,
              m_bitmap.Width,
              m_bitmap.Height);
            objGraphics.Dispose();
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            m_penDown = true;
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            m_penDown = false;
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            m_lastX = m_currentX;
            m_lastY = m_currentY;

            m_currentX = System.Windows.Forms.Cursor.Position.X;
            m_currentY = System.Windows.Forms.Cursor.Position.Y;

            if(m_penDown)
                m_bitmap.SetPixel(m_currentX, m_currentY, Color.Gray);
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {

            Form2_Paint(sender, e);
            this.pictureBox1.Image = m_bitmap;
        }

        private void Form2_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space)
            {
                m_bitmap.Save(@"C:\Users\rpettefar\Documents\My Dropbox\Programming\paint1\preview.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
            }
        }
    }
}

我对 C# 有点陌生,所以我对任何其他问题或可能出现的问题持开放态度也注意。

I am trying to write a drawing program for use with a tablet. For this I need fall-off and transparency for use with pressures. So I am using the bitmap system in C# for image construction.

I cannot seem to get my drawing code at the moment to display anything. It is being rendered to a picture box. I know there is some stuff being input to the bitmap as it shows up when I do a bitmap save.

I have had a look around an pretty much all C# drawing questions refer to using the line drawing or ellipse drawing stuff as opposed to bitmaps

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace paint1
{
    public partial class Form2 : Form
    {
        public Bitmap m_bitmap;
        public bool m_penDown;
        public int m_lastX;
        public int m_lastY;
        public int m_currentX;
        public int m_currentY;

        public Form2()
        {
            InitializeComponent();

            // Create the bitmap area
            m_bitmap = new Bitmap(this.Width, this.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            m_penDown = false;

            Graphics m_graphics = Graphics.FromImage(m_bitmap);
            m_lastX = System.Windows.Forms.Cursor.Position.X;
            m_lastY = System.Windows.Forms.Cursor.Position.Y;
            m_currentX = System.Windows.Forms.Cursor.Position.X;
            m_currentY = System.Windows.Forms.Cursor.Position.Y;
        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }

        private void Form2_Paint(object sender, PaintEventArgs e)
        {
            Graphics objGraphics;
            //You can't modify e.Graphics directly.
            objGraphics = e.Graphics;
            // Draw the contents of the bitmap on the form.
            objGraphics.DrawImage(m_bitmap, 0, 0,
              m_bitmap.Width,
              m_bitmap.Height);
            objGraphics.Dispose();
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            m_penDown = true;
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            m_penDown = false;
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            m_lastX = m_currentX;
            m_lastY = m_currentY;

            m_currentX = System.Windows.Forms.Cursor.Position.X;
            m_currentY = System.Windows.Forms.Cursor.Position.Y;

            if(m_penDown)
                m_bitmap.SetPixel(m_currentX, m_currentY, Color.Gray);
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {

            Form2_Paint(sender, e);
            this.pictureBox1.Image = m_bitmap;
        }

        private void Form2_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space)
            {
                m_bitmap.Save(@"C:\Users\rpettefar\Documents\My Dropbox\Programming\paint1\preview.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
            }
        }
    }
}

I am a bit new to c# so I am very open to any other issues or things that may come to your attention too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

榆西 2024-12-09 19:22:03

您必须将位图分配给图片框。

myPictureBox.Image = m_bitmap;

您可以在更改位图后执行此操作,或分配一次位图,然后使 PictureBox 无效。

myPictureBox.Invalidate();

这告诉您的表单刷新屏幕上的图片。无需重写 OnPaint。使用您在表单构造函数中创建的 Graphics 对象绘制位图(如果您想要制作比仅绘制单个像素更复杂的事情)。 PictureBox 将完成剩下的工作。

You will have to assign your bitmap to the picture box.

myPictureBox.Image = m_bitmap;

You can do that after you changed the bitmap or assign it once and then invalidate your PictureBox.

myPictureBox.Invalidate();

This tells your form to refresh the picture on the screen. There is no need to override OnPaint. Draw to the bitmap using the Graphics object you created in the constructor of the form (if you want to make more complicated things than just drawing single pixels). The PictureBox will do the rest.

小姐丶请自重 2024-12-09 19:22:03

看起来至少有两种方法可以让图像显示在屏幕上:不能立即说出问题所在,但我想说绝对要摆脱 objGraphics.Dispose(); 行 - 你没有创建 Graphics (你被传递了它),所以你不应该Dispose它。

It looks like there's at least two ways you're trying to get the image on screen; can't say immediately what's wrong, but I would say definitely get rid of that objGraphics.Dispose(); line - you didn't create the Graphics (you were passed it), so you shouldn't Dispose it.

微暖i 2024-12-09 19:22:03

我稍微清理了一下你的代码。您可能不应该为此使用图片框。

这是一个只有一个面板的表单:

  public partial class Form1 : Form
  {
    public Bitmap m_bitmap;
    public Point m_lastPoint = Point.Empty;

    public Form1()
    {
      InitializeComponent();   
      m_bitmap = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
      using (Graphics g = Graphics.FromImage(m_bitmap))
        g.Clear(SystemColors.Window);
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
      e.Graphics.DrawImage(m_bitmap, new Point(0, 0));
    }

    private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
      m_lastPoint = e.Location;
    }

    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Left)
      {
        using (Graphics g = Graphics.FromImage(m_bitmap))
          g.DrawLine(Pens.Black, m_lastPoint, e.Location);

        m_lastPoint = e.Location;    
        panel1.Invalidate();
      }
    }  
  }

I cleaned up your code a bit. You probably shouldn't use a picturebox for this.

Here is a form with just a panel:

  public partial class Form1 : Form
  {
    public Bitmap m_bitmap;
    public Point m_lastPoint = Point.Empty;

    public Form1()
    {
      InitializeComponent();   
      m_bitmap = new Bitmap(panel1.ClientSize.Width, panel1.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
      using (Graphics g = Graphics.FromImage(m_bitmap))
        g.Clear(SystemColors.Window);
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
      e.Graphics.DrawImage(m_bitmap, new Point(0, 0));
    }

    private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
      m_lastPoint = e.Location;
    }

    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Left)
      {
        using (Graphics g = Graphics.FromImage(m_bitmap))
          g.DrawLine(Pens.Black, m_lastPoint, e.Location);

        m_lastPoint = e.Location;    
        panel1.Invalidate();
      }
    }  
  }
回眸一遍 2024-12-09 19:22:03

其他海报基本上回答了这个问题,但根据我的经验,我想补充一点,使用这种方法可能会出现一些闪烁。如果这样做,您可以做的一件事就是对渲染目标进行子类化并启用双缓冲。对于图片框,它看起来像这样:

public class DoubleBufferedPictureBox : PictureBox
{
    /// <summary>
    /// Creates an instance of the DoubleBufferedPictureBox.
    /// </summary>
    public DoubleBufferedPictureBox() : base()
    {
        this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
    }
}

The other posters have largely answered the question, but in my experience, I'd add that you'll likely get some flicker with this method. If you do, one thing you can do to help with this is sub-class your rendering target and enable double buffering. For a picture box, it would look something like this:

public class DoubleBufferedPictureBox : PictureBox
{
    /// <summary>
    /// Creates an instance of the DoubleBufferedPictureBox.
    /// </summary>
    public DoubleBufferedPictureBox() : base()
    {
        this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文