تعلم كيف تنشئ برنامج لتعديل مقاسات الصور بنفسك

تعلم كيف تنشئ برنامج لتعديل مقاسات الصور بنفسك

السلام عليكم

مقدمة

  1. مرحلة التخطيط

كما نعلم ان المبرمج يهدف دوماً ببرامجه لتسهيل حياة الناس الذين يقتنون أجهزة الحاسوب .. كنت أواجه صعوبة ما في تعديل مقاس مجموعة كبيرة من الصور فأضطر لفتح برنامج تحرير الصورة وتعديل المقاس واحدة والأخرى وهذا كما نعلم يأخذ منا وقت كبير ونظراً لكثرة تلك الصور قمت بعد توفيق الله بعمل برنامج صغير لتغيير مقاس الصور دفعة واحدة وفي هذه التدوينة سنتحدث عن كود تغيير مقاس الصورة وسنركز فيه كما ستجد في آخرها رابط لصفحة مشروع أبعاد الذي هو خلاصة هذا الكود

البدأ بالعمل

  1. مرحلة التصميم

سنبني تطبيق من نوع ويندوز أبليكيشن مع العلم انه من السهل تغييره ليكون ويب ابليكيشن لكننا نريد السهولة والسرعة ,نبدأ ببسم الله مع مشروع جديد و نفتح شاشة جديدة (Form) ونصممها بشكل سهل وبسيط لعمل كمايلي :

صورة توضح واجهة البرنامج

كل البرنامج تقريبا عبارة عن هذه الشاشة

أولا ً: سنظيف زرين Buttons  الأول لاختيار الصور وسنضعه في أول الشاشة والثانية لحفظ الصور وسنضعه في آخر الشاشة

ثانيا : الزر الأول سنحتاج استخدام مربع حوار (فتح) لفتح الصور وسنضيف في المشروع أداة ( OpenDialog ) نسميها OpenImg و الزر الثاني سنحدد به (المجلد) الذي سنحفظ فيه الصور لذلك سنضيف أداة FolderBrowserDialog  ونسميها FolderSave

رابعا ً : سيكون لنا طريقتين في تصغير الصور وسنبدل بين الطريقتين بأزرار إختيار من نوع Radio Button  الأول اسمه RadioButSize لتغيير الصورة بحجم محدد والثاني  RadioButPersent لتغيير الصورة بالنسبة

 الطريقة الأولى التغيير بمقاس محدد مع إمكانية الحفاظ على التناسب بين الابعاد ( المقصود بالتناسب بين الابعاد الحفاظ على الصورة الطويلة بتناسب معين كماهي والصغيرة كماهي فمثلا لو كان طول الصور 120 وعرضها 40 فيعني ان التانسب هنا العرض هو ثلث الطول )

سنجعل تلك الطريقة في مجموعة واحدة اسمها GroSize فيها أداة إدخال أرقام فقط NumericUpDown الأولى للطول ونسميها NumHeight  والثانية للعرض ونسميها NumWidth ومربع خيار صغير CheckBox  لتفعيل / عدم تفعيل خاصية الحفاظ على التناسب بين الطول والعرض (الحفاظ على تناسب الأبعاد ) ونسميه CheckBRatio

وفي المجموعة الثانية GrPers

سنضيف أداة NumericUpDown لوضع نسبة تغيير الحجم فيها فيها ونسميها NumPers

أيضاً بالجهة المقابلة نظيف أداة FolwLayoutPanel لنضع فيها مصغرات بسيطة للصور التي اخترناها ونسميها FLP

ملاحظة : قمت بتجاهل إضافة Labels لان المستخدم سيعرفها من شكل الشاشة .

  1. مرحلة البرمجة

(سأكتب الكود هنا واشرحه بالفيجول بيسك ثم سأكتب لكم نسخة كاملة ب C# )

نبدأ بجلب المكتبات الثلاث الرسم والرسم ثانئ البعد ومكتبة الإدخال والإخراج كما يلي:

 

Imports System.Drawing

Imports System.Drawing.Drawing2D

Imports System.IO

 

ثم لنضع المتغيرات التالية كمتغيرات عامة لكل الفئة

 

 الأول ImgOneOpenLocation لنرسم فيه الصورة (وسنتعامل معه عند تحديد صورة واحدة فقط )

 والثاني ImgListOpenLocation  مجموعة صورة لنرسم فيها الصور المختارة ( وسنتعامل معه عند تحديد أكثر من صورة )

والثالث ImgSaveLocation لتحديد مجلد الحفظ

الرابع ImgNameOneOpenLocation  مسار الصورة (وسنتعامل معه عند تحديد صورة واحدة فقط )

الخامس ImgNamesListOpenLocation  لمجموعة مسارات الصور ( وسنتعامل معه عند تحديد أكثر من صورة )

والسادس NewImagesList قائمة صور لنقوم بإضافة الصور بعد تعديل حجمها فيها

 

Public ImgOneOpenLocation As Image

    Public ImgListOpenLocation As New List(Of Image)

    Public ImgSaveLocation As String

    Public ImgNameOneOpenLocation As String

    Public ImgNamesListOpenLocation As New List(Of String)

    Public NewImagesList As New List(Of Image)

 

 

 

وحتى لايظل برنامجنا يعمل في خلفية الجهاز بعد النقر على زر الإغلاق نظيف في الحدث Close  للشاشة الرئيسية الفعل End

   

Private Sub FrmMain_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed

        End

    End Sub

 

 

في زر الفتح ( تحديد الصور ) سنكتب الكود التالي

Try

            FLP.Controls.Clear()

            ImgListOpenLocation.Clear()

            ImgNameOneOpenLocation = ""

            ImgNamesListOpenLocation.Clear()

            OpenImg.Filter = "All Image files|*.bmp;*.gif;*.jpg;*.ico;*.emf,*.wmf|Bitmap Files(*.bmp;*.gif;*.jpg;*.ico)|*.bmp;*.gif;*.jpg;*.ico|Meta Files(*.emf;*.wmf)|*.emf;*.wmf"

            Dim filter As String = OpenImg.Filter

            OpenImg.InitialDirectory = Environment.CurrentDirectory

            OpenImg.Title = "اختيار صورة"

            OpenImg.ShowHelp = False

            OpenImg.Multiselect = True

            If OpenImg.ShowDialog() = DialogResult.OK Then

                If OpenImg.FileNames.Length > 1 Then

                    For i As Integer = 0 To OpenImg.FileNames.Length - 1

                        Dim IPictureBox As New PictureBox

                        ImgListOpenLocation.Add(Image.FromFile(OpenImg.FileNames(i)))

                        ImgNamesListOpenLocation.Add(OpenImg.FileNames(i))

                        IPictureBox.Width = 50

                        IPictureBox.Height = 50

                        IPictureBox.Image = ImgListOpenLocation.Item(i)

                        IPictureBox.SizeMode = PictureBoxSizeMode.StretchImage

                        IPictureBox.Visible = True

                        FLP.Controls.Add(IPictureBox)

                    Next

                ElseIf OpenImg.FileNames.Length = 1 Then

                    Dim IPictureBox As New PictureBox

                    ImgOneOpenLocation = Image.FromFile(OpenImg.FileName)

                    ImgNameOneOpenLocation = OpenImg.FileName

                    IPictureBox.Width = 50

                    IPictureBox.Height = 50

                    IPictureBox.Image = ImgOneOpenLocation

                    IPictureBox.Visible = True

                    IPictureBox.SizeMode = PictureBoxSizeMode.StretchImage

                    FLP.Controls.Add(IPictureBox)

                Else

                    MessageBox.Show("فضلا قم باختيار صورة أو عدة صور")

                End If

            End If

        Catch ex As Exception

            MessageBox.Show(ex.Message, "خطأ", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading)

        End Try

    End Sub

 

وشرحه كما يلي :

 

نقوم أولا بتغريغ كافة المتغيرات السابقة تمهيداً لبدأ عملية جديدة

FLP.Controls.Clear()

            ImgListOpenLocation.Clear()

            ImgNameOneOpenLocation = ""

            ImgNamesListOpenLocation.Clear()

 

 

 

نحدد الملفات التي سنقبل ان نفتحها وقد اخترت أغلب الأنواع المشهورة

OpenImg.Filter = "All Image files|*.bmp;*.gif;*.jpg;*.ico;*.emf,*.wmf|Bitmap Files(*.bmp;*.gif;*.jpg;*.ico)|*.bmp;*.gif;*.jpg;*.ico|Meta Files(*.emf;*.wmf)|*.emf;*.wmf"

كما نحدد بقية الخواص لمربع الفتح

OpenImg.InitialDirectory = Environment.CurrentDirectory

            OpenImg.Title = "اختيار صورة"

            OpenImg.ShowHelp = False

           

فنحدد المسار وعنوان الشاشة ونقوم بإلغاء زر المساعدة

وأهم من ذلك أن نفعل خاصية اختيار أكثر من ملف

OpenImg.Multiselect = True

ثم نشغل الشاشة وننتظر أن تعود لنا بالقيمة OK  بمعنى اننى لن نقوم بأي إجراء في حال قام المستخدم بالنقر على زر Cancel

If OpenImg.ShowDialog() = DialogResult.OK Then

الآن سننظر هل قام المستخدم باختيار ملف صورة واحدة ام عدة صور

If OpenImg.FileNames.Length > 1 Then

إذا اختار أكثر من صورة فإننا سنقوم بعمل دائرة تكرار (For Next ) تبدأ من صفر وتنتهي بإجمالي عدد الملفات ناقص واحد

For i As Integer = 0 To OpenImg.FileNames.Length – 1

نضيف اسم كل صورة لقائمة أسماء الصور ImgNamesListOpenLocation ونظيف الصورة نفسها أيضا لقائمة الصور ImgListOpenLocation

                        ImgListOpenLocation.Add(Image.FromFile(OpenImg.FileNames(i)))

                        ImgNamesListOpenLocation.Add(OpenImg.FileNames(i))

 

 

 

نقوم بإنشاء مربع صورة لكل صورة ( للصورة المصغرة التي ستضهر في الأداة FLP ) ونحدد طولها وعرضها ب50 بكسل مع تمكين خاصية تمدد الصورة داخل الأدة وخاصية إظهار الصورة

Dim IPictureBox As New PictureBox

                        IPictureBox.Width = 50

                        IPictureBox.Height = 50

                        IPictureBox.Image = ImgListOpenLocation.Item(i)

                        IPictureBox.SizeMode = PictureBoxSizeMode.StretchImage

                        IPictureBox.Visible = True

 

 

 

ثم نقوم أخيراً بإضافة مربع الصورة في الأداة FLP

 

                        FLP.Controls.Add(IPictureBox)

 

نفس ماقمنا به أعلاه سنكرره لكن في حال اختيار صورة واحدة

Dim IPictureBox As New PictureBox

                    ImgOneOpenLocation = Image.FromFile(OpenImg.FileName)

                    ImgNameOneOpenLocation = OpenImg.FileName

                    IPictureBox.Width = 50

                    IPictureBox.Height = 50

                    IPictureBox.Image = ImgOneOpenLocation

                    IPictureBox.Visible = True

                    IPictureBox.SizeMode = PictureBoxSizeMode.StretchImage

                    FLP.Controls.Add(IPictureBox)

 

يجب أن نجعل المستخدم يختار فقط إحدى الطريقتين وسنقوم في زر اختيار التصغير باستخدام مقاس محدد بإضافة الكود التالي عند الحدث CheckedChanged

 

  

 Private Sub RadioButSize_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButSize.CheckedChanged

        If RadioButSize.Checked = True Then

            GroSize.Enabled = True

            GrPers.Enabled = False

        Else

            GroSize.Enabled = False

            GrPers.Enabled = True

        End If

    End Sub

 

وملخص الكود هو أنه اذا حدد المستخدم زر التعديل بمقاس محدد فعل مجموعة الأزرار لتتغيير بطول وعرض محدد وعند تفعيل الزر الأخر قم بتفعيل مجموعة التغيير بالنسبة وإلي التفعيل للمجوعة الأولى

دعونا قبل ان نتحدث عن زر الحفظ ان نقوم بإضافة وظيفتي تغيير الحجم الأولى ستأخذ الصورة image  مع المقاس الجديد size بالإضافة لخاصية التناسب بين الطول والعرض وتأخذ بشكل أساسي قيمة نعم preserveAspectRatio  وتعيد لنا بعد ذلك الصورة معدلة

Public Shared Function ResizeImg(ByVal image As Image, _

  ByVal size As Size, Optional ByVal preserveAspectRatio As Boolean = True) As Image

 

في حال اختار المستخد خاصية التناسب بين الطول والعرض فسنحدد مغيرات إضافية الأولى للطول والعرض بعد تعديل التناسب والثانية لتحديد النسبة بين الطول والعرض مع أخذ أكبرهما كأساس للتناسب

 

       

Dim newWidth As Integer

        Dim newHeight As Integer

        If preserveAspectRatio Then

            Dim OrgWidth As Integer = image.Width

            Dim OrgHeight As Integer = image.Height

            Dim percentWidth As Single = CSng(size.Width) / CSng(OrgWidth)

            Dim percentHeight As Single = CSng(size.Height) / CSng(OrgHeight)

            Dim percent As Single = If(percentHeight < percentWidth,

                    percentHeight, percentWidth)

            newWidth = CDbl(OrgWidth * percent)

            newHeight = CDbl(OrgHeight * percent)

 

في حال لم يختار المستخدم خاصية التناسب سنسد قيمة الطول والعرض من المقاس المرسل لمتغييرين أساسيين

Else

            newWidth = size.Width

            newHeight = size.Height

        End If

 

الان نقوم بإعادة رسم الصورة باستخدام الدالة DrawImage  من جديد  بطول وعرض محددين ثم نعيد الصورة الجديدة كالتالي:

 

Dim newImage As Image = New Bitmap(newWidth, newHeight)

        Using graphicsHandle As Graphics = Graphics.FromImage(newImage)

            graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic

            graphicsHandle.DrawImage(image, 0, 0, newWidth, newHeight)

        End Using

        Return newImage

 

وهذ الفكرة الأساسية

 

في الوظيفة الثانية سنقوم بنفس العمل تقريباً وستأخذ الوظيفة متغييرين فقط أولهما الصورة القديمة والثانية هي النسبة المئوية والفرق عن الوظيفة السابقة هنا أننا نعيد حساب الطول الجديد  والعرض بتقسيمها على 100 لنأخذ قيمة 1% ثم نضربها في النسبة التي أراد المستخدم التغيير إليها فلو كان الطول 10000 واختار التغيير بنسبة 50% سيكون الطول الجديد 5000

وباقي الوظيفة هو نفس الوظيفة السابقة بإعادة رسم الصورة

 

Public Shared Function ResizePercentImg(ByVal image As Image, _

  ByVal percent As Integer) As Image

        Dim newWidth As Integer

        Dim newHeight As Integer

        Dim OrgWidth As Integer = image.Width

        Dim OrgHeight As Integer = image.Height

        newWidth = (CDbl(OrgWidth / 100) * percent)

        newHeight = (CDbl(OrgHeight / 100) * percent)

        Dim newImage As Image = New Bitmap(newWidth, newHeight)

        Using graphicsHandle As Graphics = Graphics.FromImage(newImage)

            graphicsHandle.InterpolationMode = InterpolationMode.HighQualityBicubic

            graphicsHandle.DrawImage(image, 0, 0, newWidth, newHeight)

        End Using

        Return newImage

    End Function

 

أخيرا زر الحفظ وملخص أدائه كالتالي

أولا : نتأكد ان المستخدم اختار صورة او عدة صور

If ImgNameOneOpenLocation = "" And ImgNamesListOpenLocation.Count = 0 Then

                MessageBox.Show("قم باختيار صورة او عدة صور أولا", "خطأ", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading)

                Exit Sub

            End If

 

ثانيا نجعل المستخدم يحدد مجلد الحفظ بعرض مربع الحوار FolderSave

 

If FolderSave.ShowDialog = Windows.Forms.DialogResult.OK Then

 

نخزن المسار في متغير من نوع DirectoryInfo اسمه Dirc

 

Dim Dirc As New IO.DirectoryInfo(FolderSave.SelectedPath)

طبعا نمسح قائمة الصور الجديدة

 

ثم ننظر هل قام المستخدم باختيار الطريقة الأولى ام الثانية

إذا اختار الطريقة الأولى ( التغيير بحجم ثابت )

ننظر هل قام المستخدم باختيار صورة واحدة ام عدة صور ثم نرسل بعد ذلك الصورة او الصور للوظيفة الأولى

If RadioButSize.Checked = True Then

                    If ImgNamesListOpenLocation.Count > 0 Then

                        For i As Integer = 0 To ImgListOpenLocation.Count - 1

                            NewImagesList.Add(ResizeImg(ImgListOpenLocation(i), New Size(NumWidth.Value, NumHeight.Value), CheckBRatio.Checked))

                        Next

                    ElseIf ImgNameOneOpenLocation <> "" Then

                        ImgNamesListOpenLocation.Add(ImgNameOneOpenLocation)

                        NewImagesList.Add(ResizeImg(ImgOneOpenLocation, New Size(NumWidth.Value, NumHeight.Value), CheckBRatio.Checked))

                    End If

                Else

 

في حال ان المستخدم اختار الطريقة الثانية (التغيير بنسبة )

 

سننظر هل قام باختيار صورة واحدة ام عدة صور ونرسلهم بعد ذلك للوظيفة الثانية

If NumPers.Value = 0 Then

                        MessageBox.Show("لقد اخترت تغيير حجم الصورة بنسبة 0 % " & vbNewLine & "وهذا يعني انه لن يتم تغيير الحجم فضلا قم بتغيير القيمة المؤية لتكون اكبر من صفر", "خطأ", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading)

                        Exit Sub

                    End If

                    If ImgNamesListOpenLocation.Count > 0 Then

                        For i As Integer = 0 To ImgListOpenLocation.Count - 1

                            NewImagesList.Add(ResizePercentImg(ImgListOpenLocation(i), NumPers.Value))

                        Next

                    ElseIf ImgNameOneOpenLocation <> "" Then

                        ImgNamesListOpenLocation.Add(ImgNameOneOpenLocation)

                        NewImagesList.Add(ResizePercentImg(ImgOneOpenLocation, NumPers.Value))

                    End If

 

الان حتى لانقع في مشاكل تكرار اسم الصورة سنظيف لكل صورة حرف A ورقم كعداد ويتم البحث عن نفس الأسم إذا كان موجود مسبقا يتم إضافة حرف A  والعدد

 

For ImgNo As Integer = 0 To NewImagesList.Count - 1

                    Dim img As Image = NewImagesList(ImgNo)

                    Dim OldName As New FileInfo(ImgNamesListOpenLocation(ImgNo))

                    Dim counter As Integer = 1

                    Dim NewName As String

                    Dim IsNewName = True

                    Do

                        NewName = (OldName.Name.Split(".")(0) & "A" & counter.ToString & "." & OldName.Name.Split(".")(1))

                        IsNewName = False

                        For Each FilStr As String In Directory.GetFiles(FolderSave.SelectedPath)

                            Dim Fil As New FileInfo(FilStr)

                            If Fil.Name = NewName Then

                            counter = counter + 1

                            IsNewName = True

                            Exit For

                            End If

                        Next

                    Loop Until IsNewName = False

                    img.Save(FolderSave.SelectedPath & "\" & NewName)

                Next

 

يبقى عليك أخي القارئ إضافة بعض التحسينات والشكليات الجمالية على البرنامج مثل الأيقونات وشعار للبرنامج وخلافه فيما يلي رابط صفحة المشروع باستخدام Visual Studio 2012  بلغة Vb.net  مع نسخة من المشروع بتنسيق exe. جاهزة للتثبيت على جهازكم الرابط موجود في أسفل الصفحة باسم Download

 

http://tecnyt.com/Project.aspx?id=9#.UqcC8Zbo8wA.twitter

الردود

آراء أعضاء الموقع وتعليقاتهم

هل أنت مشترك بموقع تقنيات ؟ بادر بالإشتراك الآن


يجب عليك التسجيل لتستطيع كتابة تعليق