Область рисования (C#)
От: thespian Украина  
Дата: 01.06.04 10:18
Оценка:
Как получить размеры области рисования на форме. Form.Size — даёт размеры всего окна, а мне нужно только клиентской области.

Заранее спасибо.
... << RSDN@Home 1.1.3 stable >>
Re: Область рисования (C#)
От: BLR Беларусь  
Дата: 01.06.04 10:24
Оценка:
Здравствуйте, thespian, Вы писали:

T>Как получить размеры области рисования на форме. Form.Size — даёт размеры всего окна, а мне нужно только клиентской области.


T>Заранее спасибо


для размера клиентской области ClientRectangle.
Re[2]: Область рисования (C#)
От: thespian Украина  
Дата: 01.06.04 19:56
Оценка:
Здравствуйте, BLR, Вы писали:

BLR>Здравствуйте, thespian, Вы писали:


T>>Как получить размеры области рисования на форме. Form.Size — даёт размеры всего окна, а мне нужно только клиентской области.


T>>Заранее спасибо


BLR> для размера клиентской области ClientRectangle.


Как можно в памяти создать канву (много квадратиков), и отобразить её на форму?
... << RSDN@Home 1.1.3 stable >>
Re[3]: Область рисования (C#)
От: viknet Казахстан  
Дата: 02.06.04 04:33
Оценка:
Здравствуйте, thespian, Вы писали:

T>Здравствуйте, BLR, Вы писали:


BLR>>Здравствуйте, thespian, Вы писали:


T>>>Как получить размеры области рисования на форме. Form.Size — даёт размеры всего окна, а мне нужно только клиентской области.


T>>>Заранее спасибо


BLR>> для размера клиентской области ClientRectangle.


T>Как можно в памяти создать канву (много квадратиков), и отобразить её на форму?

Отрисовать на bitmap и потом выводи хоть на принтер хоть на экран.
Re[4]: Область рисования (C#)
От: thespian Украина  
Дата: 02.06.04 18:59
Оценка:
Здравствуйте, viknet, Вы писали:

V>Отрисовать на bitmap и потом выводи хоть на принтер хоть на экран.


Это я понимаю и уже второй день мучаюсь. Можно небольшой примерчик рисования на битмапе в C#?
... << RSDN@Home 1.1.3 stable >>
Re[5]: Область рисования (C#)
От: Ael США  
Дата: 02.06.04 20:13
Оценка:
Здравствуйте, thespian, Вы писали:

T>Здравствуйте, viknet, Вы писали:


V>>Отрисовать на bitmap и потом выводи хоть на принтер хоть на экран.


T>Это я понимаю и уже второй день мучаюсь. Можно небольшой примерчик рисования на битмапе в C#?


Вот кусок:


_hBitmap=new Bitmap(_iWidth,_iHeight);
            using(Graphics gr=Graphics.FromImage(_hBitmap))
            {
                using (GraphicsPath gPath=new GraphicsPath())
                 {
                    gPath.AddEllipse(0,0,_iWidth,_iHeight);
                    using (PathGradientBrush pgBrush=new PathGradientBrush(gPath))
                     {
                        pgBrush.CenterColor=Color.FromArgb(0,255,255,255);
                        pgBrush.SurroundColors=new Color[]{Color.Red,Color.Blue};
                        gr.Clear(Color.FromArgb(0,255,255,255));
                        gr.FillEllipse(pgBrush,0,0,_iWidth,_iHeight);
                    }
                }
            }
Re[6]: Область рисования (C#)
От: thespian Украина  
Дата: 03.06.04 16:30
Оценка:
Здравствуйте, Ael.

Спасибо за пример. Очень содержательный.
Я его попробовал, но всё-таки не добился цели. Как в дотнете быстро выводить графику на канву? (уж сильно мерцает).
... << RSDN@Home 1.1.3 stable >>
Re[7]: Область рисования (C#)
От: Ael США  
Дата: 03.06.04 19:53
Оценка:
Здравствуйте, thespian, Вы писали:

T>Здравствуйте, Ael.


T>Спасибо за пример. Очень содержательный.

T>Я его попробовал, но всё-таки не добился цели. Как в дотнете быстро выводить графику на канву? (уж сильно мерцает).

А какая задача, почему надо рисовать именно на битмапе, и какой код мерцает?
Re[8]: Область рисования (C#)
От: thespian Украина  
Дата: 03.06.04 21:03
Оценка:
Здравствуйте, Ael, Вы писали:

Ael>А какая задача, почему надо рисовать именно на битмапе, и какой код мерцает?


Я просто пробовал рисовать анимацию на C# .Net, при анимировании 20 эллипсов — началось мерцание. Я решил разрисововать это в памяти, а потом всё выводить на экран — не помогло. Каким образом это всё можно сгладить?

П.С.: вопрос по примеру, почему компилятор на GraphicsPath выдаёт ошибку? Что надо прописать в using?
... << RSDN@Home 1.1.3 stable >>
Re[9]: Область рисования (C#)
От: Ael США  
Дата: 04.06.04 04:32
Оценка:
Здравствуйте, thespian, Вы писали:

T>Здравствуйте, Ael, Вы писали:


Ael>>А какая задача, почему надо рисовать именно на битмапе, и какой код мерцает?


T>Я просто пробовал рисовать анимацию на C# .Net, при анимировании 20 эллипсов — началось мерцание. Я решил разрисововать это в памяти, а потом всё выводить на экран — не помогло. Каким образом это всё можно сгладить?



Посмотрите вот такой пример:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;

    public class Form1 : System.Windows.Forms.Form
    {
        private Bitmap _hBitmap;
        private volatile Boolean _bFinish;
       const Int32 iNumber=30;
                     public Form1()
        {
            Int32 _iWidth=this.Width/iNumber;
            Int32 _iHeight=this.Height/iNumber;
        
             _hBitmap=new Bitmap(_iWidth,_iHeight);
            using(Graphics gr=Graphics.FromImage(_hBitmap))
            {
                
                    using (SolidBrush sBrush=new SolidBrush(Color.Green))
                    {
                        gr.Clear(Color.FromArgb(0,255,255,255));
                        gr.FillEllipse(sBrush,0,0,_iWidth,_iHeight);
                    }
                }            
            Thread t=new Thread(new ThreadStart(this.Animation));
            t.IsBackground=true;
            t.Start();
            this.Closing+=new CancelEventHandler(Form1_Closing);
        }
       
        private void Animation()
        {
            Thread.Sleep(100);
            Random rand=new Random(DateTime.Now.Millisecond);
            Int32 cX=0,cY=0;
            while (!_bFinish)
            {
                using (Graphics g=this.CreateGraphics())
                 {
                    using (Brush brushErase=new SolidBrush(this.BackColor))
                           {
                        for(cX=0;cX<this.Width;cX+=iNumber)
                            for (cY=0;cY<this.Height&&!_bFinish;cY+=iNumber)
                            {
                                if(rand.Next()%2==0)
                                    g.DrawImage(this._hBitmap,cX,cY,iNumber,iNumber);
                                else
                                    g.FillRectangle(brushErase,cX,cY,iNumber,iNumber);
                        
                                    }
                                        Thread.Sleep(100);
                            }
                    }
            }
        }


        
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void Form1_Closing(object sender, CancelEventArgs e)
        {
            this._bFinish=true;
        }
    }

Хотя по правилам нужно рисовать только в OnPaint. Можно переписать пример, чтобы он использовал делегат и вызывал OnPaint для выполнения в основном потоке. Это будет медленнее (появится мерцание), так что мне нравится больше
пример выше.
using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

public delegate void PaintCallback(Rectangle rectClip);
    public class Form1 : System.Windows.Forms.Form
    {
        private Bitmap _hBitmap;
        private volatile Boolean _bDraw,_bFinish;
        const Int32 iNumber=30;
        private PaintCallback _pc;
        public Form1()
        {
            Int32 _iWidth=this.Width/iNumber;
            Int32 _iHeight=this.Height/iNumber;
        
            _hBitmap=new Bitmap(_iWidth,_iHeight);
            using(Graphics gr=Graphics.FromImage(_hBitmap))
            {
                
                using (SolidBrush sBrush=new SolidBrush(Color.Green))
                {
                    gr.Clear(Color.FromArgb(0,255,255,255));
                    gr.FillEllipse(sBrush,0,0,_iWidth,_iHeight);
                }
            }            
            this._pc=new PaintCallback(this.InvalidateUpdate);
            Thread t=new Thread(new ThreadStart(this.Animation));
            t.IsBackground=true;
            t.Start();
            this.Closing+=new CancelEventHandler(Form1_Closing);
        }
       
        private void InvalidateUpdate(Rectangle rectClip)
        {
            if(!this._bFinish)
            {
                this.Invalidate(rectClip);
                this.Update();
                _bDraw=false;    
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            if (_bDraw)
                e.Graphics.DrawImage(_hBitmap,e.ClipRectangle);
            base.OnPaint (e);
        }

        private void Animation()
        {
            Thread.Sleep(100);
            Random rand=new Random(DateTime.Now.Millisecond);
            Int32 cX=0,cY=0;
            while (!_bFinish)
            {
                using (Graphics g=this.CreateGraphics())
                {
                    using (Brush brushErase=new SolidBrush(this.BackColor))
                    {
                        for(cX=0;cX<this.Width;cX+=iNumber)
                            for (cY=0;cY<this.Height&&!_bFinish;cY+=iNumber)
                            {
                                if(rand.Next()%2==0)
                                    this._bDraw=true;
                                    this.BeginInvoke(this._pc,new Object[]{new Rectangle(cX,cY,iNumber,iNumber)});
                                                    
                            }
                        Thread.Sleep(100);
                    }
                }
            }
        }


        
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void Form1_Closing(object sender, CancelEventArgs e)
        {
            this._bFinish=true;
        }
    }

Кстати, если в битмапе обычный кружок, или там кружок и линии, то быстрее будет не рисовать это в битмап, а потом выводить битмап, а рисовать фигуры заново.С битмапом выигрываешь, если в битмапе — картинка.

T>П.С.: вопрос по примеру, почему компилятор на GraphicsPath выдаёт ошибку? Что надо прописать в using?

using System.Drawing.Drawing2D;
Re[10]: Область рисования (C#)
От: thespian Украина  
Дата: 04.06.04 09:50
Оценка:
Здравствуйте, Ael.

Пример просто супер. Спасибо.
А теоретически какие-либо методы рисования плоской анимации (игр) есть на дотнете. Например, как BitBlt в Win32?
... << RSDN@Home 1.1.3 stable >>
Re[11]: Область рисования (C#)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.06.04 11:26
Оценка:
Здравствуйте, thespian, Вы писали:

T> А теоретически какие-либо методы рисования плоской анимации (игр) есть на дотнете. Например, как BitBlt в Win32?


Есть, DirectX 9 SDK
... << Rsdn@Home 1.1.4 beta 2 >>
AVK Blog
Re[11]: Область рисования (C#)
От: mihailik Украина  
Дата: 04.06.04 13:38
Оценка:
T> А теоретически какие-либо методы рисования плоской анимации (игр) есть на дотнете.

Игрушки типа пасьянса и тетриса нормально будут работать на System.Drawing. Гонки и Postal 2, конечно, так не получится. Кстати, скоро в RSDN Magazine будет моя статья с игрушкой как раз вроде тетриса.

Всё работает достаточно быстро, если аккуратно реализовать. Одна из основных мыслей — рисовать только в OnPaint и только ту область, которая должна быть перерисована. А для события перерисовки использовать Invalidate. Тогда никогда не будет проблем с мельканием.

Ну и, конечно, кешировать всё по максимуму. Битмапы тех же самых карт, кисти, фонты.


T>Например, как BitBlt в Win32?


Graphics.DrawImage отлично работает. Одна беда — нельзя нарисовать картинку саму в себя. Это действительно неудобно.


P.S. В следующей версии .NET V2 кроме GDI+ будет поддерживаться и старый GDI. Теоретически он должен работать немного быстрее.
... << Rsdn@Home 1.1.4 beta 1 >>
Re[12]: Область рисования (C#)
От: Ael США  
Дата: 04.06.04 21:06
Оценка: 9 (1)
Здравствуйте, mihailik, Вы писали:

[skipped]

M>Всё работает достаточно быстро, если аккуратно реализовать. Одна из основных мыслей — рисовать только в OnPaint и только ту область, которая должна быть перерисована. А для события перерисовки использовать Invalidate. Тогда никогда не будет проблем с мельканием.


[skipped]

Знаю, это уже обсуждалось, но хотелось бы прояснить. Согласен, что лучше всегда рисовать только в OnPaint и для перерисовки вызывать Invalidate. Но — посмотрите вот эти два простых примера — сравненияздесь
Автор: Ael
Дата: 04.06.04

Вопрос — согласны ли с тем, что в случае, когда, как в этом, перерисовка постоянно и незначительных деталей в разных местах контрола — более производительно как раз рисовать не в OnPaint-е?
Re[13]: Область рисования (C#)
От: mihailik Украина  
Дата: 07.06.04 08:09
Оценка:
Ael>Вопрос — согласны ли с тем, что в случае, когда, как в этом, перерисовка постоянно и незначительных деталей в разных местах контрола — более производительно как раз рисовать не в OnPaint-е?

Да, конечно.

К сожалению, OnPaint получает ClipRectangle, а не ClipRegion.
... << Rsdn@Home 1.1.4 beta 1 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.