PDA

View Full Version : آموزش: آموزش تولید Mini Photoshop



bitaroos
جمعه 15 مرداد 1389, 16:35 عصر
سلام

اگه دوست دارید یه برنامه شبیه Photoshop بنویسید ( البته اگه خدا حال و حوصله بده) توچند قسمت می خوام اینکارو براتون بکنم

در اینجا یه قسمت از toolbox برنامه ی Photoshop رو یاد دادم البته اکسرش ترجمه ی کتاب زیره

Graphics Programming with GDI+

http://forum.majidonline.com/attachment.php?attachmentid=46293&stc=1&d=1173447104



البته برای فهم این آموزشی که دادم باید یکمی GDI+ بلد باشید



قسمت های بعدی color piker & filters & color box & cropping & resizing & typing on image & image rotation & zooming & flipping & ….

پس منتظر باشید البته اگه خدا حال و حوصله بده





بعد از باز کردن c# و ایجاد پروژه از نوع Windows Forms Application روی فورم ایجاد شده دابل کلیک کنید تا وارد رویداد load این فورم بشیم
FFFFFFFFFFFFFFFFFFFF
private void Form1_Load(object sender, EventArgs e)
{
XXXXXXXXXXXXXXX
}


حال قبل از وارد کردن کد های این رویداد، کد های زیر را در بالایprivate void Form1… یعنی بجای FFFFFFFFFFFFFFFFFFFFوارد میکنیم

این کد ها متغیر هایی هستند که در طول برنامه ازشون استفاده میشه




private Bitmap bitmap = null;
private Bitmap curBitmap = null;
private bool dragMode = false;
private int drawIndex = 1;
private int curX, curY, x, y;
private int diffX, diffY;
private Graphics curGraphics;
private Pen curPen;
private SolidBrush curBrush;
private Size fullSize;
private Color curcolor = Color.Black;
<div align="right">
حال کد های رویداد load را بین { } بجای XXXXXXXXXXXXXXX وارد میکنیم



private void Form1_Load(object sender, EventArgs e)
{

// Get the full size of the form
fullSize = SystemInformation.PrimaryMonitorMaximizedWindowSiz e;
// Create a bitmap using full size
bitmap = new Bitmap(fullSize.Width,fullSize.Height);
// Create a Graphics object from Bitmap
curGraphics = Graphics.FromImage(bitmap);
// Set background color as form's color
curGraphics.Clear(this.BackColor);
// Create a new pen and brush as
// default pen and brush
curPen = new Pen(curcolor);
curBrush = new SolidBrush(curcolor);

}



کد زیر اندازه ی پنجره را در متغیر fullSize ذخیره می کند
fullSize = SystemInformation.PrimaryMonitorMaximizedWindowSiz e;


کد زیر یک bitmap به ابعاد پنجره پروژه (با استفاده از fullSize) میسازد
bitmap = new Bitmap(fullSize.Width,fullSize.Height);


کد زیر از bitmap یک شئ Graphic جهت ترسیم شکل های گرافیکی میسازد
curGraphics = Graphics.FromImage(bitmap);


کد زیر رنگ شئ Graphic ایجاد شده در مرحله قبل رو به رنگ پس زمینه فورم تغییر میده
curGraphics.Clear(this.BackColor);


در اینجا یک Pen و یک Brush ، برای نقاشی روی شئ Graphic میسازیم
curPen = new Pen(curcolor);
curBrush = new SolidBrush(curcolor);


حال به تب [design] رفته و از toolbox یک toolstrip روی فورم ایجاد می کنیم. و سه button مطابق شکل روی آن ایجاد میکنیم. و پنجره properties نام آنها را به btn_Elips و btn_line و btn_rect تغییر می دهیم

بر روی هر یک از button ها دابل کلیک میکنیم و کد رویداد Click را برای هر کدام به ترتیب
drawIndex = 1;وdrawIndex = 2;و

drawIndex = 3;
می گذاریم پس داریم


private void btn_Elips_Click(object sender, EventArgs e)
{
drawIndex = 1;
}

private void btn_line_Click(object sender, EventArgs e)
{
drawIndex = 2;
}

private void btn_rect_Click(object sender, EventArgs e)
{
drawIndex = 3;
}
این کار رو کردیم تا موقع ترسیم، با توجه به عدد drawIndex ، برنامه بفهمه کدوم شکل ( خط، بیضی یا مستطیل) رو ترسیم کنه.

خوب برای ترسیم علاوه بر مشخص بودن drawIndex باید مختصات نقاط آغاز و پایان روهم از موقعیت و وضعیت موس بدست بیاریم پس می ریم سراغ 3 تا از رویداد های فورم که عبارتند از :

MouseDown - MouseMove – MouseUp

با انتخاب فورم در تب design و رفتن به پنجره properties و انتخاب events بر روی هر یک از این رویداد ها دابل کلیک کرده و کد های زیر را وارد میکنیم



private void Form1_MouseDown(object sender, MouseEventArgs e)
{
curX = e.X;
curY = e.Y;
dragMode = true;
}
</div>
تا اینجا با فشردن کلید موس مختصات آغاز را بدست آوردیم


private void Form1_MouseMove(object sender, MouseEventArgs e)
{
x = e.X;
y = e.Y;
diffX = e.X - curX;
diffY = e.Y - curY;

if (dragMode)
{
this.Refresh();
}
}
</div>
در اینجا با drag موس در هر لحظه مختصات پایانی را بدست آوردیم و از تفریق مختصات پایانی و آغازی ، طول و عرض مستطیلی را بدست می آوریم که برای رسم مستطیل و بیضی به آن احتیاج داریم. این کار را انجام می دهیم چون مل خواهیم هنگام drag پیش نمایشی از شکل داشته باشیم، برای درک بهتر- بعد از اتمام برنامه- یک بار این کد ها را به صورت کامنت در بیاورید وبرنامه را اجرا کنید، تفاوب را خواهید فهمید.

از dragMode = true; برای این استفاده کردیم تا فقط و فقط وقتی کلیک کرده ایم وهمزمان drag می کنیم، پیش نمایشی از شکل داشته باشیم.

تا اینجا وقتی کلیک کرده ایم وهمزمان drag می کنیم، شکل ایجاد شده با حرکت موس مدام تغییر می کنه(البته ترسیم در این جا با کمک رویداد paint صورت می گیرد که در ادامه بررسی می شود). حالا باید کاری کنیم که با بالا آمدن کلیک موس، شکل ایجاد شده ثابت بماند.


private void Form1_MouseUp(object sender, MouseEventArgs e)
{
diffX = x - curX;
diffY = y - curY;
switch (drawIndex)
{
case 1:
{
// Draw an ellipse
curGraphics.DrawEllipse(curPen, curX, curY, diffX, diffY);
break;
}

case 2:
{
// Draw a line
curGraphics.DrawLine(curPen, curX, curY, x, y);
break;
}

case 3:
{
// Draw a rectangle
curGraphics.FillRectangle(curBrush, curX, curY, diffX, diffY);
break;
}
}
// Refresh
RefreshFormBackground();
// Set drag mode to false
dragMode = false;

}

در رویداد MouseUP فورم، با استفاده از مختصات و drawIndex، مکان و نوع شکل ترسیمی مشخص می شود و با استفاده از قلم curPen و دستور ِDrawEllipse شکل تو خالی ایجاد می کنیم و با استفاده از قلموی curBrash و دستور ِFillRectangle مستطیل تو پر رسم می کنیم.

متد RefreshFormBackground(); که در زیر امده باعث می شود کشیدن شکل جدید باعث پاک شدن شکل قبلی نشود در واقع این کد تصویر جاری روbackground فورم قرار میده.


private void RefreshFormBackground()
{
curBitmap = bitmap.Clone(new Rectangle(0, 0, this.Width, this.Height), bitmap.PixelFormat);
this.BackgroundImage = curBitmap;
}

اینم از رویداد paint که دیگه فکر نکنم توضیح بخواد.


private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
// If dragMode is true, draw the selected
// graphics shape
if (dragMode)
{
switch (drawIndex)
{
case 1:
{
g.DrawEllipse(curPen, curX, curY, diffX, diffY);
break;
}

case 2:
{
g.DrawLine(curPen, curX, curY, x, y);
break;
}

case 3:
{
g.FillRectangle(curBrush, curX, curY, diffX, diffY);
break;
}

}
}

}