تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
مقال - استخلاص الصور من صورة متحركة gif
#1
كاتب الموضوع : silverlight

بسم الله الرحمن الرحيم


السلام عليكم ورحمة الله وبركاته

مقدمـــــة:

من المؤكد أن قارئ هذا المقال فد سمع عن أو استخدم كلمة GIF وهي كلمة أو إمتداد يستخدم لملفات الصور المتحركة............... وبالتأكيد جميعنا قد استخدم مثل هذا النوع من الصور في برامحه بشكل ما. وفي بعض المقالات التي كتبتها سابقا كنت قد استعرضت بعض الأفكار للتعامل مع الصور المتحركة وذلك باستحدام الجرافكس +GDI وتستطيع عزيزي القارئ أن تقرأ هذا المقالات في اللينك التالي:

الصور المتحركة في الدوت نت Animation

الصور المتحركة في الدوت نت Animation الجزء الثاني

الصور المتحركة في الدوت نت Animation الجزء الثالث

الصور المتحركة في الدوت نت Animation الجزء الرابع

كيف نتأكد أن الصورة متحركة:

لنتأكد أن الصورة متحركة علينا إتباع الخطوات التالية:

1- نقوم بتعريف متغير يعبر عن أي صورة متحركة حيث هنا الصورة المتحركة موجودة في Resouces الخاصة بالمشروع ومن ثم يكون لدينا الكود بالشكل الأتي:


كود :
Dim gifImage As Image = My.Resources.sweet_gifs_003
2- نقوم بتعريف متغير عبارة عن FrameDimension ثم نمرر له متغير عبارة عن GUID وهذا المتغير هو عبارة عن صفة Property تمتلكها الصورة وهو FrameDimensionsList وبالتالي نحصل علي الكود بالشكل الأتي:


كود :
Dim fDimensions As FrameDimension = New FrameDimension(gifImage.FrameDimensionsList(0))
ولمزيد من المعلومات عن الكلاس FrameDimension يمكنك عزيزي القارئ مراجعة اللينك التالي

FrameDimension Class On MSDN

3- ثم نقوم بتعريف متغير يعبر عن عدد Frames الموجودة في الصورة وهو عبارة عن متغير رقمي وهذا المتغير نحصل علي قيمتة عن طريق دالة موجودة بالكلاس Image واسم هذه الدالة هو GetFrameCount حيث يتم تمرير المتغير الذي تم تعريفه بالخطوة السابقة الي هذه الدالة ومن ثم نحصل علي الكود بالشكل الأتي:


كود :
Dim frames As Integer = gifImage.GetFrameCount(fDimensions)
4- الأن نستخدم جملة IF الشرطية حيث أن لو كان عدد Frames التي نحصل عليها من الخطوة 3 أكبر من 1 فهذا يعني أن الصورة متحركة أما لو كان الناتج اقل من أو يساوي 1 فهذا يعني أن الصورة غير متحركة ثم بناء علي تحقق هذه الشروط نضع الكود الذي نراة مناسبا وهنا علي سبيل المثال ستظهر رسالة تحدد إذا كانت الصورة متحركة أم لا والكود الأتي يوضح الأمر


كود :
If frames > 1 Then
MessageBox.Show("Image is an animated GIF" + " and the number of frames are" + " " + frames.ToString + " frames")
Else
MessageBox.Show("Image is not an animated GIF.")
End If
وبالنهاية يكون الكود الإجمالي للخطوات السابقة بالشكل الأتي


كود :
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim gifImage As Image = My.Resources.sweet_gifs_003
Dim fDimensions As FrameDimension = New FrameDimension(gifImage.FrameDimensionsList(0))
Dim frames As Integer = gifImage.GetFrameCount(fDimensions)
If frames > 1 Then
MessageBox.Show("Image is an animated GIF" + " and the number of frames are" + " " + frames.ToString + " frames")
Else
MessageBox.Show("Image is not an animated GIF.")
End If
End Sub
حاول عزيزي القارئ في الخطوة رقم 1 أن تستخدم صورة عادية غير متحركة بدلا من صورة متحركة لتري الفارق بنفسك

وبعد أن أوضحت لكم كيف نتأكد أن الصورة متحركة أم لا عن طريق الكود نحتاج هنا لبناء دالة نسترجع منها نفس النتائج التي حصلنا عليها بالخطوات السابقة ولكن مع تعديل بسيط في الكود حيث أن الدالة التي سنقوم بكتابة الكود الخاص بها سنسترجع منها قيمة لمتغير عبارة عن Boolean والشكل النهائي للدالة سيكون كالأتي


كود :
''' <summary>
''' Check if the imag is Animated or not
''' </summary>
''' <param name="img"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Function IsGifImage(ByVal img As Image) As Boolean
If (img Is Nothing) Then
Throw New ArgumentNullException("img")
End If
Dim fDimensions As FrameDimension = New FrameDimension(img.FrameDimensionsList(0))
Dim frames As Integer = img.GetFrameCount(fDimensions)
Dim isGif As Boolean = False
If frames > 1 Then
isGif = True
End If
Return isGif
End Function
الأن لنعطي مثالا عن كيفية استخدام الدالة أعلاه


كود :
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim gifImage As Image = My.Resources.sweet_gifs_003
If IsGifImage(gifImage) Then
MessageBox.Show("Image is an animated GIF")
Else
MessageBox.Show("Image is not an animated GIF.")
End If
End Sub
ستلاحظون هنا أن الدالة ساعدتنا علي تقليل حجم الكود المستخدم ومن هنا تأتي أهمية بناء الدوال Functions وهذا بشكل عام

أيضا الدالة الثانية توضح كيفية الحصول علي عدد Frames الموجودة في الصورة المتحركة


كود :
''' <summary>
''' Get Gif Image Frame
''' </summary>
''' <param name="img"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Function GetImageFrames(ByVal img As Image) As Integer
If IsGifImage(img) Then
Dim fDimensions As FrameDimension = New FrameDimension(img.FrameDimensionsList(0))
Dim frames As Integer = img.GetFrameCount(fDimensions)
Return frames
End If
Return 0
End Function
كيف نسترجعه الصور الموجودة في صورة متحركة


بالتأكيد هذا السؤال يجول في خاطر القارئ ولكي نفعل ذلك سوف نستحدم الدوال التي كتبناها سابقا لنسترجع الصور الموجودة في الصورة المتحرك ونبني كلاسا نستخدمه في استرجاع الصور المتحركة ومن الممكن أن نضيف للكلاس بعض الدوال أو Properties أو اي شئ أخر نراه مناسبا لهدفنا من هذا الكلاس. ولسوف أطلق علي هذا الكلاس إسم GifImageFrames


كود :
Public Class GifImageFrames

End Class
لنضيف بعض المتغيرات للكلاس كالتالي
1- متغير يعبر عن الصورة
2- متغير يعبر عن عدد Frames الموجودة بالصورة وهو عبارة عن متغير رقمي


كود :
Public Class GifImageFrames

#Region " Fields "

Private _frames As Integer
Private _image As Bitmap

#End Region
ثم نضيف Constructor أو أكثر لهذا الكلاس


كود :
Public Class GifImageFrames

#Region " Fields "

Private _frames As Integer
Private _image As Bitmap

#End Region

#Region " Constructor "

Public Sub New()
Me._image = Nothing
Me._frames = 0
End Sub

#End Region

End Class
ثم نضيف بعض الدوال التي كتبناها سابقا لهذا الكلاس بالطبع نحتاج للتعديل بها قليلا لتتناسب مع الكلاس

ستلاحظون من الكود أدناه أنني أضفت دالة جديدة نسترجع منها الصور الموجود في الصورة المتحركة وهي الدالة GetImages

وأخيرا لنضيف بعض Properties وايضا المزيد من Constructor لهذا الكلاس ومن ثم يكون الشكل النهائي لهذا الكلاس كالتالي وهو كلاس بسيط جدا جدا


كود :
Imports System.Drawing.Imaging

Public Class GifImageFrames

#Region " Fields "

Private _frames As Integer
Private _image As Bitmap

#End Region

#Region " Constructor "

Public Sub New()
Me._image = Nothing
Me._frames = 0
End Sub

Public Sub New(ByVal frames As Integer, ByVal image As Bitmap)
Me._image = image
Me._frames = frames
End Sub

#End Region

#Region " Properties "

Public ReadOnly Property IsGif As Boolean
Get
If Me._image IsNot Nothing Then
Return Me.IsGifImage(Me._image)
End If
Return Nothing
End Get
End Property

Public ReadOnly Property Image As Bitmap
Get
Return Me._image
End Get
End Property

Public ReadOnly Property Frames As Integer
Get
If Me._image IsNot Nothing Then
Return Me.GetImageFrames(Me._image)
End If
Return 0
End Get
End Property

Public ReadOnly Property Images As List(Of Bitmap)
Get
Return GetImages()
End Get
End Property

#End Region

#Region " Methods "

Private Function GetImageFrames(ByVal img As Image) As Integer
If IsGifImage(img) Then
Dim fDimensions As FrameDimension = New FrameDimension(img.FrameDimensionsList(0))
Dim frames As Integer = img.GetFrameCount(fDimensions)
Return frames
End If
Return 0
End Function

Private Function IsGifImage(ByVal img As Image) As Boolean
If (img Is Nothing) Then
Throw New ArgumentNullException("img")
End If
Dim fDimensions As FrameDimension = New FrameDimension(img.FrameDimensionsList(0))
Dim frames As Integer = img.GetFrameCount(fDimensions)
Dim isGif As Boolean = False
If frames > 1 Then
isGif = True
End If
Return isGif
End Function

Private Function GetImages() As List(Of Bitmap)
If Me._image IsNot Nothing Then
Dim images As New List(Of Bitmap)
Dim gifImage As Image = Me._image
Dim frames As GifImageFrames() = New GifImageFrames() {}
Dim fd As New FrameDimension(gifImage.FrameDimensionsList(0))
Dim frameCount As Integer = gifImage.GetFrameCount(fd)
If frameCount > 1 Then
frames = New GifImageFrames(frameCount - 1) {}
Dim times As Byte() = gifImage.GetPropertyItem(&H5100).Value
For i As Integer = 0 To frameCount - 1
gifImage.SelectActiveFrame(fd, i)
Dim length As Integer = BitConverter.ToInt32(times, 4 * i) * 10
frames(i) = New GifImageFrames(length, New Bitmap(gifImage))
Next
End If

For Each frm As GifImageFrames In frames
images.Add(frm.Image)
Next

Return images
End If
Return Nothing
End Function

#End Region

End Class ' GifImageFrames

كيف نستحدم الكلاس

1- نقوم بتعريف صورة متحركة
2- نقوم بتعريف متغير يعبر عن هذا الكلاس الذي كتبناه ومن ثم نمرر له الصور المتحركة
3- بعد ذلك ومن الصفة Images Property يكون لدينا الصور الموجودة في الصورة المتحركة حيث نستخدمها كيفما شئنا بعد ذلك

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


كود :
Public Class Form1

Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Dim gifImage As Image = My.Resources.sweet_gifs_003
Dim frames As GifImageFrames = New GifImageFrames(gifImage)

For Each img As Bitmap In frames.Images
For x = 0 To frames.Frames - 1
e.Graphics.DrawImage(img, CInt(gifImage.Width * x / frames.Frames), 0, CInt(img.Width / frames.Frames), CInt(img.Height / frames.Frames))
Next
Next
End Sub

End Class
أعتقد أن الحصول علي الصور الموجودة بصورة متحركه هو أمر بسيطا جدا ولكنه هام جدا للمهتمين بالتعامل مع الصور بشكل عام

أتمني أن يكون الموضوع الذي ناقشناه مفيدا لكم بشكل ما

بالمرفقات ستجدون نسخة من الكلاس وكيفية استخدامة بنسخة الفيجوال استوديو 2010
ولمن لا يملك نسخة 2010 يستطيع أن يعيد كتابة الكود مرة أخري ليتناسب مع نسخة الفيجوال استوديو الذي لديه

وبالتوفيق لكم جميعا

أخوكم عمر


الملفات المرفقة
.rar   IsGifImage_scr.rar (الحجم : 484.77 ك ب / التحميلات : 96)
}}}
تم الشكر بواسطة: kebboud
#2
في الموضوع أعلاه الكلاس به جزء لم يكتمل وتحديدا في Constructor الخاص بالكلاس ولذلك هذا هو الشكل النهائي للكلاس كالأتي

أيضا من الممكن أن نقوم باستخدام IDisposable Interface مع هذا الكلاس


كود :
Imports System.Drawing.Imaging

Public Class GifImageFrames

#Region " Fields "

Private _frames As Integer
Private _image As Bitmap

#End Region

#Region " Constructor "

Public Sub New()
Me._image = Nothing
Me._frames = 0
End Sub

Public Sub New(ByVal image As Image)
Me._frames = 0
Me._image = image
End Sub

Public Sub New(ByVal frames As Integer, ByVal image As Bitmap)
Me._image = image
Me._frames = frames
End Sub

#End Region

#Region " Properties "

Public ReadOnly Property IsGif As Boolean
Get
If Me._image IsNot Nothing Then
Return Me.IsGifImage(Me._image)
End If
Return Nothing
End Get
End Property

Public ReadOnly Property Image As Bitmap
Get
Return Me._image
End Get
End Property

Public ReadOnly Property Frames As Integer
Get
If Me._image IsNot Nothing Then
Return Me.GetImageFrames(Me._image)
End If
Return 0
End Get
End Property

Public ReadOnly Property Images As List(Of Bitmap)
Get
Return GetImages()
End Get
End Property

#End Region

#Region " Methods "

Private Function GetImageFrames(ByVal img As Image) As Integer
If IsGifImage(img) Then
Dim fDimensions As FrameDimension = New FrameDimension(img.FrameDimensionsList(0))
Dim frames As Integer = img.GetFrameCount(fDimensions)
Return frames
End If
Return 0
End Function

Private Function IsGifImage(ByVal img As Image) As Boolean
If (img Is Nothing) Then
Throw New ArgumentNullException("img")
End If
Dim fDimensions As FrameDimension = New FrameDimension(img.FrameDimensionsList(0))
Dim frames As Integer = img.GetFrameCount(fDimensions)
Dim isGif As Boolean = False
If frames > 1 Then
isGif = True
End If
Return isGif
End Function

Private Function GetImages() As List(Of Bitmap)
If Me._image IsNot Nothing Then
Dim images As New List(Of Bitmap)
Dim gifImage As Image = Me._image
Dim frames As GifImageFrames() = New GifImageFrames() {}
Dim fd As New FrameDimension(gifImage.FrameDimensionsList(0))
Dim frameCount As Integer = gifImage.GetFrameCount(fd)
If frameCount > 1 Then
frames = New GifImageFrames(frameCount - 1) {}
Dim times As Byte() = gifImage.GetPropertyItem(&H5100).Value
For i As Integer = 0 To frameCount - 1
gifImage.SelectActiveFrame(fd, i)
Dim length As Integer = BitConverter.ToInt32(times, 4 * i) * 10
frames(i) = New GifImageFrames(length, New Bitmap(gifImage))
Next
End If

For Each frm As GifImageFrames In frames
images.Add(frm.Image)
Next

Return images
End If
Return Nothing
End Function

#End Region

End Class ' GifImageFrames
}}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  معلومة :: تعلم كيف تحفظ صورة في My.Settings بدون الإحتياج إلى مسارها! أسامة أحمد 13 6,230 أمس, 01:13 AM
آخر رد: أبو جودة
Video [درس فيديو] تقارير الكريستال ريبورت وتغيير مسار الصور أثناء التشغيل رمضان272 0 1,607 28-03-22, 03:18 AM
آخر رد: رمضان272
  شرح خوارزميات معالجة الصور (من دروس الاستاذ فوزي برزنجي) ناديه الشجيري 19 34,362 20-02-22, 02:13 PM
آخر رد: رضوان الجماعي
  التعامل مع الصور Images في بيئة الدوت نت باستخدام +GDI - مقدمة RaggiTech 3 5,865 30-07-21, 05:14 PM
آخر رد: kebboud
  مقال: الكومبو بوكس ComboBox كيف تضيف أيقونات Blue Sky 1 3,161 30-06-19, 10:41 AM
آخر رد: invocker
  Compare Images المقارنة بين الصور Abu Ehab 0 3,272 31-10-18, 04:27 PM
آخر رد: Abu Ehab
  مقدمة إلي ضغط الصور ..... Zip Bitmap silverlight 0 2,392 10-05-18, 04:35 AM
آخر رد: silverlight
  إخفاء تكست في صورة silverlight 0 2,496 02-07-17, 09:31 AM
آخر رد: silverlight
  مشروع لجلب الصور من الماسحة الضوئية (Scanner) m.sami.ak 14 12,094 22-01-17, 10:41 AM
آخر رد: amko
  [VB.NET] تشغيل Twain الخاص بسحب الصور من السكنر في حالة net framework4 ahmed saleh 4 4,385 25-10-15, 07:20 PM
آخر رد: عدنان الشمري

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم