【问题标题】:C# bitmap drawing doesn't render to the screenC# 位图绘制不渲染到屏幕上
【发布时间】:2011-09-02 14:26:03
【问题描述】:

我正在尝试编写一个用于平板电脑的绘图程序。为此,我需要衰减和透明度以用于压力。所以我在 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# 有点陌生,所以我对任何其他可能引起您注意的问题或事情都持开放态度。

【问题讨论】:

    标签: c# graphics bitmap drawing paint


    【解决方案1】:

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

    myPictureBox.Image = m_bitmap;
    

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

    myPictureBox.Invalidate();
    

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

    【讨论】:

    • 谢谢。无效的图片框似乎画得很好:D
    【解决方案2】:

    看起来至少有两种方法可以让图像显示在屏幕上;不能立即说出出了什么问题,但我会说肯定要摆脱 objGraphics.Dispose(); 行 - 你没有创建 Graphics(你通过了它),所以你不应该 Dispose 它。

    【讨论】:

    • 是的,这是我有点沮丧的结果。一种方法行不通,所以我换了另一种方法,看看是否有帮助。我还想我必须摆脱在那里创建的图形对象。那么让它超出范围也可以吗?
    • @Pyro 但它不是在那里创建的,它是在PaintEventArgs 中给你的。 您创建IDisposable对象中的Dispose绝对正确,但那些。
    【解决方案3】:

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

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

      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();
          }
        }  
      }
    

    【讨论】:

    • 非常感谢。点数和失效的使用效果很好。虽然我对“使用 (Graphics g = Graphics.FromImage(m_bitmap))”有点迷惑,但我想我应该阅读更多关于 c# 的内容,呵呵。
    • 实现 IDisposable 接口的对象需要被释放,而 using(){} 语句会为您完成。
    【解决方案4】:

    其他发帖人在很大程度上回答了这个问题,但根据我的经验,我要补充一点,使用这种方法你可能会得到一些闪烁。如果你这样做了,你可以做的一件事就是对你的渲染目标进行子类化并启用双缓冲。对于图片框,它看起来像这样:

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

    【讨论】:

    • 哇,我不知道你可以双缓冲一个 c# 组件。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 2013-12-31
    相关资源
    最近更新 更多