گرافیک در سی شارپ

saalek110

Well-Known Member
گرافیک در سی شارپ

در این تاپیک منظور ما استفاده از کلاسهای System.Drawing است.
پس using های ما در این تاپیک همواره شامل System.Drawing باید باشد(که فکر کنم با ساخت یک پروژه ویندوزی خودبخود این using اضافه می شود):

کد:
using System.Drawing;

همچنین در این تاپیک رویدادهایی را بررسی می کنیم. مثل رویداد paint .
 
آخرین ویرایش:

saalek110

Well-Known Member
اولا من خودم به بازی و گرافیک خیلی علاقه دارم.
ولی دوما منظور من از این تاپیک این است که کلاسهای دات نت را ملموس تر بیاموزیم.
مثلا بفهمیم که چگونه شی ئی از یک کلاس با شی دیگری از کلاس دیگر ارتباط برقرار می کند.

چون در گرافیک شکلها هستند که موضوعات کار ما را تشکیل می دهند و خیلی ملموس تر میشه ارتباطات کلاسها را فهمید تا مثلا در کلاسهای دیتابیس.

پس من سعی می کنم در این تاپیک تمرینات بیشتری داشته باشیم و هدف باطنی من تسلط بر کلاسهای دات نت است و در درجه بعد کمی تفریح و سرگرمی با بازی با گرافیک.
 

saalek110

Well-Known Member
لوازم کار ما یک پروژه سی شارپ ویندوزی و using کردن همان System.Drawing و کدهایی است که در ادامه بحث می کنیم.

من اکثرا عادت دارم کدها را داخل رویداد کلیک یک باتون(دکمه) قرار می دهم. پس اگر در تاپیک ذکر نشد یعنی من در همین رویداد کدم را ریخته ام.
 

saalek110

Well-Known Member
شروع: یک پروژه ویندوزی سی شارپ بسازید. و در رویداد کلیک یک باتون(که به فرم خود باتون را قبلا افزوده اید) کد زیر را بیافزایید:

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            my_graph.DrawRectangle(System.Drawing.Pens.Blue, 80, 20, 40, 40);
            my_graph.Dispose();


a1.gif


شرح برنامه :
شی ئی از کلاس Graphics ایجاد شده.
بعد این شی یک مستطیل(در اینجا اضلاع را برابر داده این و مربع شده) رسم کرده.
و بعد شی را Dispose کرده ایم.

نامهای دلخواه را من در این تاپیک مثل my_graph می سازم.
یعنی کلمه my و بعد نوع شی.


اعدادی هم که می بینید یا x و y شکل ما هستند یا طول و عرض.
من در طول تاپیک شرح نمی دهم. کمی تغییرشان بدهید می فهمید چه هستند.
 
آخرین ویرایش:

saalek110

Well-Known Member
بحث فنی تر برنامه پست قبل:

به آبجکت بروسر بروید و کلاس Graphics را نگاه کنید . چرا سازنده ( متدی همنام کلاس) نیست؟
چرا شی را این طور خلق نکرده ایم؟
کد:
System.Drawing.Graphics my_graph = new Graphics();

چرا متدی از فرم ( this ) یعنی CreateGraphics عامل خلق این شی بوده؟
آیا می شود به جای کشیدن مربع خود بر فرم بیاییم مربع خود را بر روی باتون بکشیم؟

در پستهای بعدی به این سئوالات به تدریج جواب می دهیم.
 

saalek110

Well-Known Member
برای پاسخ به آخرین سئوال پست قبل من برنامه زیر را ساختم:

کد:
            System.Drawing.Graphics my_graph = this.button1.CreateGraphics();
            my_graph.DrawRectangle(System.Drawing.Pens.Blue, 80, 20, 40, 40);
            my_graph.Dispose();



a4.gif


دو شکل گذاشتم تا متوجه این قضیه باشیم که مختصات نسبت به دکمه است نه فرم.


a2.gif


تصویر بالا موقعی تهیه شده که ماوس هنوز روی دکمه بوده. چرا وقتی ماوس را از روی دکمه کنار می بریم تصویر محو می شود؟
 
آخرین ویرایش:

saalek110

Well-Known Member
برای پاسخ به سئوال پست قبل به جای کلیک با ماوس بر باتون با زدن اینتر باعث رسم مربع شوید. و سپس پنجره فرم را آنقدر از صفحه مونیتور خارج کنید که نیمی از مربع آبی رنگ رسم شده توسط کد ما خارج شود.
بعد با برگرداندن فرم به وسط صفحه قسمتی که خارچ شده بود از صفحه دیگر وجود ندارد.



a3.gif

چه کار کنیم که چنین اتفاقی رخ ندهد؟
 

saalek110

Well-Known Member
در پستهای قبلی مدام از رویداد کلیک دکمه استفاده شده بود ولی حالا کد زیر را امتحان کنید:

کد:
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            System.Drawing.Graphics my_graph = this.button1.CreateGraphics();
            my_graph.DrawRectangle(System.Drawing.Pens.Blue, 80, 20, 40, 40);
            my_graph.Dispose();  
        }

یعنی در رویداد paint فرم کدمان را قرار دادیم.
حالا فرم را از صفحه خارج کنید. موقع باز گرداندن فرم به داخل صفحه می بینید که مربع آبی روی دکمه رسم می شود.
همچنین در موقع کلیک دکمه یک لحظه مربع دیده می شود یا موقع ورود و خروج ماوس از روی دکمه. یعنی در این زمانها رویداد paint ااحضار می شود.

بهتر است کد زیر را امتحان کنید:
کد:
            System.Drawing.Graphics my_graph = this.button1.CreateGraphics();
            my_graph.DrawRectangle(System.Drawing.Pens.Blue, 80, 20, 40, 40);
            for (int i = 1; i < 100000000; i++) ;
            my_graph.Dispose();

یعنی یک حلقه هم اضافه کردیم تا رویت مربع راحت تر باشد.
با این کار می بینید که وقتی داریم فرم را به صفحه مونیتور برمی گردانیم انگار فرم گیر دارد. ولی موقع حرکت داخل صفحه مونیتور هیچ گیری وجود ندارد . و این به خاطر این است که رویداد paint مسئول رسم موقع به نمایش درآمدن فرم است. موقع شروع برنامه بالا هم مکثی که مشاهده می شود مربوط به این حلقه است.
 

saalek110

Well-Known Member
شرح کد زیر:
کد:
my_graph.DrawRectangle(System.Drawing.Pens.Blue, 80, 20, 40, 40);



a5.gif


کلاس Pens دارای اعضایی static است. یعنی بی ساخت شی از این کلاس می توانیم از اعضایش استفاده کنیم.

کار ما را راحت کرده این کلاس در اینجا ولی اگر می خواستیم خودمان pen بسازیم باید مراحلش را طی می کردیم.
 

saalek110

Well-Known Member
و در کد زیر :

کد:
        private void button1_Click(object sender, EventArgs e)
        {
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Pen my_Pen = new Pen(Color.Chocolate);
            my_graph.DrawRectangle(my_Pen, 80, 20, 40, 40);
            my_graph.Dispose();
        }



a6.gif


در اینجا ما شی pen را خودمان ساخته ایم. و بعد به عنوان یکی از ورودی های متد DrawRectangle شی my_graph استفاده کرده ایم.
کار این متد رسم مستطیل است و منطقی است اگر قلم خود را نوعش را سئوال کند.
این متد 3 نوع ورودی می گیرد و هر 3 قلم را مطالبه می کند. شکل زیر:



a7.gif


پس به این علت ما از این کلاس شی ساخته ایم. کد زیر:

کد:
System.Drawing.Pen my_Pen = new System.Drawing.Pen(Color.Chocolate);

در زیر می بینید که سازنده کلاس Pen چهار نوع می شود به آن ورودی داد و ما نوع چهارمی را به کار برده ایم.



a8.gif


و در زیر باز استفاده از یک عضو استاتیک یک کلاس را می بینیم.



b1.gif


در پست قبلی این عضو استاتیک یک Pen بود و در اینجا این عضو استاتیک یک Color می باشد.
 
آخرین ویرایش:

saalek110

Well-Known Member
در پستهای قبلی با فرمول زیر مستطیل خود را کشیدیم:

کد:
my_graph.DrawRectangle(System.Drawing.Pens.Blue, 80, 20, 40, 40);

حالا نگاهی به متد DrawRectangle از کلاس Graphics می اندازیم:



b2.gif


در شکل بالا می بینید که یکی از ورودی های این متد همواره قلم است و ورودی دوم می تواند 4 عدد باشد یا یک :
System.Drawing.Rectangle
پس می توانیم به جای کد بالا که 4 عدد دادیم بیاییم شی ئی از کلاس(در حقیقت استراکت است نه کلاس. شرح در پست بعدی) System.Drawing.Rectangle بسازیم.

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Rectangle my_rec1 = new Rectangle(40, 20, 40, 40); // khalghe rec1
            my_graph.DrawRectangle(System.Drawing.Pens.Red, my_rec1);   // rasme rec1
            my_graph.Dispose();

کد بالا را در رویداد کلیک باتون قرار بدهید.


b3.gif

 
آخرین ویرایش:

saalek110

Well-Known Member

b4.gif


طبق شکل بالا با کلیک بر روی متد مربوطه در کادر پایین مفصل تر پارامترهای متد را می بینیم.
همان طور که می بینید System.Drawing.Rectangle یک استراکت است نه کلاس. ولی فرقی برای ما فعلا ندارد. از آن یک نمونه ساختیم در پست قبل.
 

saalek110

Well-Known Member
اساس کار همین ها بود که گفتیم.
حالا در پستهای بعدی فقط با اشیای ساخته شده بازی می کنیم.
شی ئی از کلاس Brush می سازیم. یا از Point نمونه می سازیم. یا متنی را چاپ می کنیم.
کد:
Brush bb = Brushes.Black;
Point pp1 = new System.Drawing.Point(320, 20); 
my_graph.DrawString("hello", this.Font, bb, 240, 40);

فرق قلم و براش را یاد می گیریم.
یاد می گیریم چطور عکسها را نمایش دهیم. ( البته نه داخل پیکچر باکس بلکه مثل همین کارهای قبلی با کلاسهای System.Drawing . )
کد زیر:
کد:
            // ----------------------------------------------------------------ax1
                Bitmap myBitmap = new Bitmap(@".\\55.bmp");
                //Graphics g = Graphics.FromImage(myBitmap);
                my_graph.DrawImage(myBitmap, 10, 90);
           // ------------------------------------------------------------------ax2
                Image image = Image.FromFile(@".\\33.jpg");
                my_graph.DrawImage(image, 110, 90);

یا صفات اشیای خود را تغییر می دهیم:

کد:
                Pen my_pen = new Pen(Color.Chocolate);
                my_pen.Width = 1;
                my_pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

یا چرخش را کار می کنیم:

کد:
my_graph.RotateTransform(-12);
 
آخرین ویرایش:

saalek110

Well-Known Member
در این پست به دکمه ای وظیفه پاک کردن فرم را می دهیم.
کدی هم برای رسم یک مربع می گذاریم برای تست.

این بار برخلاف گذشته کل کد فرم را پست می زنم.
کد:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
[COLOR="Red"]using System.Drawing;[/COLOR]
using System.Text;
using System.Windows.Forms;

namespace g1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
[COLOR="Blue"]
        private void button2_Click(object sender, EventArgs e)
        {
            [COLOR="DarkOrange"]System.Drawing.Graphics my_graph = this.CreateGraphics(); // khalghe sheie
            my_graph.Clear(System.Drawing.SystemColors.Control);     // clear form
            my_graph.Dispose();[/COLOR]
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Rectangle my_rec1 = new Rectangle(40, 20, 40, 40); // khalghe rec1
            my_graph.DrawRectangle(System.Drawing.Pens.Red, my_rec1);   // rasme rec1
            my_graph.Dispose();
        }
  [/COLOR]  }
}



b5.gif

 
آخرین ویرایش:

saalek110

Well-Known Member
برنامه زیر برای نوشتن کلمه ای بر روی فرم است که ابتدا یک براش ساخته ایم و بعد از متد DrawString استفاده کرده ایم.

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Brush my_Brush = Brushes.Black;
            my_graph.DrawString("hello", this.Font, my_Brush, 100, 80);
            my_graph.Dispose();



b6.gif


البته کمی در ساخت براش و فونت صرفه جویی شده در کد بالا. این دو خود کلاسهای با شخصیتی هستند. ما در اینجا از فونت خود فرم استفاده کرده ایم و براش هم همان طور که می بینید.
 

saalek110

Well-Known Member
برنامه این پست رسم خط است.
کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Point my_point_one = new System.Drawing.Point(80, 20);
            Point my_point_two = new System.Drawing.Point(200, 150);
            my_graph.DrawLine(System.Drawing.Pens.Red, my_point_one, my_point_two);
            my_graph.Dispose();



b7.gif


دو نقطه ابتدا ساخته ایم و بعد با استفاده از متد DrawLine آن را رسم کرده ایم.
باز در ساخت قلم صرفه جویی شده.
دقت کنید که line را با قلم کشیدیم نه براش. و در پست قبل نوشته خود را با براش نوشتیم.
 
آخرین ویرایش:

saalek110

Well-Known Member

b8.gif


شرحی راجع به برنامه پست قبل:
با فلش ها نشان داده شده که کدهای پست قبل بر چه اساسی تنظیم شده.

باز هم نقطه استراکت است نه کلاس.
و سعی کنید بدون ساخت point از روشهای دیگر این متد که در عکس بالا مشخص است خط را بکشید. یعنی این طوری:

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            //Point my_point_one = new System.Drawing.Point(80, 20);
            //Point my_point_two = new System.Drawing.Point(200, 150);
            my_graph.DrawLine(System.Drawing.Pens.Red , 80, 20 ,200, 150);
            my_graph.Dispose();
 
آخرین ویرایش:

saalek110

Well-Known Member
رسم دایره:

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Rectangle my_rec = new Rectangle(100, 20, 80, 80);       // khalghe rec
            my_graph.DrawEllipse(System.Drawing.Pens.Blue, my_rec);  // rasme dayereh
            my_graph.Dispose();



b9.gif


توجه کنید که دایره ما داخل یک مستطیل کشیده می شود.
و می تواند یک بیضی باشد:

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Rectangle my_rec = new Rectangle(60, 20, 160, 80);       // khalghe rec
            my_graph.DrawEllipse(System.Drawing.Pens.Blue, my_rec);  // rasme Ellipse
            my_graph.Dispose();



c1.gif

 
آخرین ویرایش:

saalek110

Well-Known Member
پر کردن داخل Rectangle :

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Rectangle my_rec = new Rectangle(80, 20, 120, 120);               // khalghe rec
            Brush my_brush = Brushes.Red; 
            my_graph.DrawRectangle(System.Drawing.Pens.Black, my_rec);        // rasme rec
            my_graph.FillRectangle(my_brush, my_rec);                        // fille rec
            my_graph.Dispose();



c2.gif


می بینید که پر کردن هم با براش است.
قبلا هم با براش یک hello نوشتیم.
ولی رسم خط و دایره و ... با قلم بود.

و در زیر باز الگوهای دیگر این متد را می بینیم.



c3.gif


پس بدون رسم مستطیل هم می شد جایی را پر کرد:
کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            //Rectangle my_rec = new Rectangle(80, 20, 120, 120);               // khalghe rec
            Brush my_brush = Brushes.Blue; 
            //my_graph.DrawRectangle(System.Drawing.Pens.Red, my_rec);        // rasme rec
            my_graph.FillRectangle(my_brush, 80,20,120,120);                        // fille rec
            my_graph.Dispose();



c4.gif

 
آخرین ویرایش:

saalek110

Well-Known Member
نمایش عکس(بدون پیکچر باکس):

کد:
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            Bitmap my_Bitmap = new Bitmap(@".\\ice.bmp");
            my_graph.DrawImage(my_Bitmap, 80, 15);
            my_graph.Dispose();



c5.gif


عکس زیر :
http://saalek110c.250free.com/gifs/gifs2/a2/ice.bmp
را در مسیر :
F:\your_project\bin\Debug\ice.bmp
قرار دهید.

===============
طرح زیر :
کد:
                Image my_image = Image.FromFile(@".\\ice.jpg");
                my_graph.DrawImage(my_image, 110, 90);
هم وجود دارد که من فرقهایش را نمی دانم و به خودتان واگذار می کنم تا سریعتر برویم مباحث بعدی.

================

برنامه زیر هم نیاز به عکس مورد نظر دارد که باید کنار فایل اگزه در پوشه bin-debug باشد. یا ریلیز اگر تنظیمات کامپایلر شما چنین باشد.

ice.bmp


کد:
        private void button1_Click(object sender, EventArgs e)
        {
            System.Drawing.Graphics my_graph = this.CreateGraphics();
            FontFamily my_FontFamily = new FontFamily("tahoma");
            Font my_Font = new Font(my_FontFamily, 150, FontStyle.Bold);

            //Image my_image = Image.FromFile(@".\\ice.jpg");
            Bitmap my_Bitmap = new Bitmap(@".\\ice.bmp");
            System.Drawing.TextureBrush my_TextureBrush = new TextureBrush(my_Bitmap);

            my_graph.DrawString("HI", my_Font, my_TextureBrush, 20, 20, StringFormat.GenericDefault);        // print hello
            my_graph.Dispose();
        }

b4.gif
 
آخرین ویرایش:

جدیدترین ارسال ها

بالا