2011-09-02 4 views
4

타블렛과 함께 사용할 드로잉 프로그램을 작성하려고합니다. 이를 위해 나는 압력과 함께 사용하기 위해 전도와 투명성이 필요합니다. 그래서 C#에서 비트 맵 시스템을 사용하여 이미지를 구성했습니다.C# 비트 맵 드로잉이 화면에 렌더링되지 않습니다.

지금은 내 그림 코드를 표시 할 수없는 것처럼 보입니다. 그림 상자로 렌더링됩니다. 비트 맵에 저장할 때 비트 맵에 입력되는 내용이 있다는 것을 알고 있습니다.

내가 주위를 살펴 있었다 거의 모든 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); 
      } 
     } 
    } 
} 

을 비트 맵 반대로 물건을 그리기 타원 당신의 관심을 끌지도 모르는 다른 이슈 나 일들에 대해서도 마찬가지입니다.

답변

2

그림 상자에 비트 맵을 지정해야합니다.

myPictureBox.Image = m_bitmap; 

비트 맵을 변경하거나 한 번 할당 한 다음 PictureBox를 무효화하면 가능합니다.

myPictureBox.Invalidate(); 

이렇게하면 양식에서 화면의 그림을 새로 고침합니다. OnPaint를 재정의 할 필요가 없습니다. 양식의 생성자에서 만든 Graphics 객체를 사용하여 비트 맵에 그리십시오 (단일 픽셀을 그리는 것보다 복잡한 작업을 수행하려는 경우). PictureBox는 나머지 작업을 수행합니다.

+0

고마워요. 무효화 된 그림 상자는 멋지게 그려집니다. D – Pyro

2

화면에 이미지를 가져 오는 중 적어도 두 가지 방법이있는 것처럼 보입니다. 무엇이 잘못 되었는 지 바로 말할 수는 없지만 확실히 objGraphics.Dispose(); 라인을 없애면 - Graphics을 만들지 않으므로 Dispose이 아닙니다.

+0

그래, 내 부분에 약간의 좌절감이 생겼습니다. 한 가지 방법이 효과가 없었기 때문에 다른 방법으로 던져 도움이되는지 확인했습니다. 또한 거기에 만들어진 그래픽 객체를 제거해야한다고 생각했습니다. 범위를 벗어나는 것도 괜찮습니까? – Pyro

+0

@Pyro하지만 거기에는 생성되지 않았으므로, 그것은 PaintEventArgs에서 당신에게 주어졌습니다. *를 만드는 'IDisposable' 객체 *를'Dispose '하는 것은 절대적으로 옳습니다. – AakashM

1

코드를 약간 정리했습니다. 아마도 이것을 위해 그림 상자를 사용해서는 안됩니다. 여기

그냥 패널 형태이다 : 다른 포스터는 크게 질문에 대답 한

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

고마워요. 포인트와 무효화의 사용은 훌륭하게 작동합니다. "(Graphics g = Graphics.FromImage (m_bitmap))를 사용하여 다소 신비 스럽지만" 나는 C#, heh heh에 대해 더 많이 읽어야한다고 생각합니다. – Pyro

+2

IDisposable 인터페이스를 구현하는 객체는 처리해야하며 using() {} 문이 처리합니다. – LarsTech

1

,하지만 내 경험에, 나는 당신이 가능성이 방법에 약간의 깜박임을 얻을 것이다 것을 추가 할 것입니다. 그렇게 할 수있는 한 가지 방법은 렌더링 대상의 하위 클래스이며 이중 버퍼링을 사용하는 것입니다. 그림 상자의 경우 다음과 같이 표시됩니다.

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

와우, 나는 당신이 C# 컴포넌트를 두 번 버퍼링 할 수 있다는 것을 몰랐다. 감사! – Pyro

관련 문제