تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
مقدمة إلي ضغط الصور ..... Zip Bitmap
#1
مقدمة:
الموضوع هذا محاولة بسيطة لتوضيح كيفية ضغط الصور بدون أن تفقد الصورة شيئا من دقتها او من ألوانها الأصلية
الفكرة ممكن تطبيقها علي البرامج التي تحتاج الي أن نحفظ الصورة في ملف مثل ملفات الدات بيز

الخطوات التالية توضح كيفية ضغط الصورة:

1- تعريف متغير يعبر عن الصورة و هنا سأفترض أن الصورة موجودة في Resources المشروع
PHP كود :
Dim bmp As Bitmap My.Resources.rm 

2- تحويل بيانات الصورة إلي مصفوفات بايت
أولا : تحويل العرض Width الي مصفوفة بايت
PHP كود :
       ' Convet bitmap width to byte array
        Dim widthBytes As Byte() = BitConverter.GetBytes(CUInt(bmp.Width)) 
ثانيا : تحويل الطول Height الي مصفوفة بايت 
كود :
       ' Convet bitmap height to byte array
       Dim heightBytes As Byte() = BitConverter.GetBytes(CUInt(bmp.Height))
ثالثا : تحويل PixelFormat الخاصة بالصورة إلي مصفوفة بايت
يتم استخدام الدالة التالية
كود :
   Private Function ConvertFromPixelFormat(bmp As Bitmap) As Byte()
       Dim imgFormat As Long = CType(Convert.ChangeType(bmp.PixelFormat, GetType(Imaging.PixelFormat)), Long)
       Return BitConverter.GetBytes(imgFormat)
   End Function
ونحصل علي مصفوفة البايت كالتالي:
كود :
       ' Convet bitmap pixelformaat to byte array
       Dim imgFormatBytes As Byte() = Me.ConvertFromPixelFormat(bmp)
رابعا : الحصول علي مصفوفة الألوان الخاصة بالصورة علي هيئة مصفوفة بايت
كود :
       ' Convet bitmap to byte array
       Dim data As Imaging.BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat)
       Dim bitmapBytes As Byte() = New Byte(data.Stride * data.Height - 1) {}
       Runtime.InteropServices.Marshal.Copy(data.Scan0, bitmapBytes, 0, bitmapBytes.Length)
       bmp.UnlockBits(data)

3- ندمج مصفوفات البايت معا في مصفوفة واحدة
بخيث تكون ترتيب المصفوفات كالتال
مصفوفة PixelFormat
مصفوفة Width
مصفوفة Height
مصفوفة الألوان
وبهذا الترتيب نحن ها نبيني ما يمطن أن نطلق عليه Bytes layout
والهدف من هذا الترتيب هو سهولة استرداد بيانات الصورة كاملة لاحقا ومن ثم نستطيع استرجاع الصورة الأصلية دون أن نفقد شيئا من دقة الصورة
كود :
       ' Build up byte arrays layout by .....
       ' Concatenate imageformat, width, height, bmp byte arrays in a single byte array
       Dim imgArray As Byte() = New Byte(imgFormatBytes.Length + widthBytes.Length + heightBytes.Length + bitmapBytes.Length - 1) {}
       Array.Copy(imgFormatBytes, 0, imgArray, 0, imgFormatBytes.Length)
       Array.Copy(widthBytes, 0, imgArray, imgFormatBytes.Length, widthBytes.Length)
       Array.Copy(heightBytes, 0, imgArray, imgFormatBytes.Length + widthBytes.Length, heightBytes.Length)
       Array.Copy(bitmapBytes, 0, imgArray, imgFormatBytes.Length + widthBytes.Length + heightBytes.Length, bitmapBytes.Length)

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

4- نقوم بضغط الصورة باستخدام 
ويمكن استخدام الدلة التالية لضغط المصفوفة والدالة تقوم بالتشفيير و الضغط معا
كود :
   Public Function Compress(bytes As Byte()) As Byte()
       Dim result As Byte() = Nothing
       Using ms As IO.MemoryStream = New IO.MemoryStream()
           Using g As GZipStream = New GZipStream(ms, CompressionMode.Compress, True)
               g.Write(bytes, 0, bytes.Length)
           End Using
           result = ms.ToArray()
       End Using
       Return result
   End Function

ااستخدام الدالة:

كود :
Dim result As Byte() = Me.Compress(imgarray)

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

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

كود :
   Private Function BuildBytes(bmp As Bitmap) As Byte()
       ' Convet bitmap width to byte array
       Dim widthBytes As Byte() = BitConverter.GetBytes(CUInt(bmp.Width))

       ' Convet bitmap height to byte array
       Dim heightBytes As Byte() = BitConverter.GetBytes(CUInt(bmp.Height))

       ' Convet bitmap pixelformaat to byte array
       Dim imgFormatBytes As Byte() = Me.ConvertFromPixelFormat(bmp)

       ' Convet bitmap to byte array
       Dim data As Imaging.BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat)
       Dim bitmapBytes As Byte() = New Byte(data.Stride * data.Height - 1) {}
       Runtime.InteropServices.Marshal.Copy(data.Scan0, bitmapBytes, 0, bitmapBytes.Length)
       bmp.UnlockBits(data)

       ' Build up byte arrays layout by .....
       ' Concatenate imageformat, width, height, bmp byte arrays in a single byte array
       Dim imgArray As Byte() = New Byte(imgFormatBytes.Length + widthBytes.Length + heightBytes.Length + bitmapBytes.Length - 1) {}
       Array.Copy(imgFormatBytes, 0, imgArray, 0, imgFormatBytes.Length)
       Array.Copy(widthBytes, 0, imgArray, imgFormatBytes.Length, widthBytes.Length)
       Array.Copy(heightBytes, 0, imgArray, imgFormatBytes.Length + widthBytes.Length, heightBytes.Length)
       Array.Copy(bitmapBytes, 0, imgArray, imgFormatBytes.Length + widthBytes.Length + heightBytes.Length, bitmapBytes.Length)

       Return imgArray
   End Function
كود :
   Private Function ConvertFromPixelFormat(bmp As Bitmap) As Byte()
       Dim imgFormat As Long = CType(Convert.ChangeType(bmp.PixelFormat, GetType(Imaging.PixelFormat)), Long)
       Return BitConverter.GetBytes(imgFormat)
   End Function
كود :
   Public Function Compress(bytes As Byte()) As Byte()
       Dim result As Byte() = Nothing
       Using ms As IO.MemoryStream = New IO.MemoryStream()
           Using g As GZipStream = New GZipStream(ms, CompressionMode.Compress, True)
               g.Write(bytes, 0, bytes.Length)
           End Using
           result = ms.ToArray()
       End Using
       Return result
   End Function

ويتم الاستخدام كالتالي
كود :
       ' compress
       Dim imgarray As Byte() = Me.BuildBytes(bmp)
       Dim result As Byte() = Me.Compress(imgarray)
Retired
الرد }}}


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  مقدمة الي تشفير الحروف الأبجدية العربية silverlight 3 9,508 17-05-22, 02:23 AM
آخر رد: flawer69
Video [درس فيديو] تقارير الكريستال ريبورت وتغيير مسار الصور أثناء التشغيل رمضان272 0 1,621 28-03-22, 03:18 AM
آخر رد: رمضان272
  شرح خوارزميات معالجة الصور (من دروس الاستاذ فوزي برزنجي) ناديه الشجيري 19 34,382 20-02-22, 02:13 PM
آخر رد: رضوان الجماعي
  التعامل مع الصور Images في بيئة الدوت نت باستخدام +GDI - مقدمة RaggiTech 3 5,873 30-07-21, 05:14 PM
آخر رد: kebboud
  Compare Images المقارنة بين الصور Abu Ehab 0 3,276 31-10-18, 04:27 PM
آخر رد: Abu Ehab
  Convert Bitmap To ByteArray & ViceVersa silverlight 1 2,093 22-09-17, 03:37 PM
آخر رد: Amir_Alzubidy
  مشروع لجلب الصور من الماسحة الضوئية (Scanner) m.sami.ak 14 12,107 22-01-17, 10:41 AM
آخر رد: amko
  مقدمة إلي إخفاء المعلومات - الجزء الأول silverlight 5 4,158 07-01-17, 10:44 PM
آخر رد: Basil Abdallah
  مقدمة إلي إخفاء المعلومات - الجزء الثاني silverlight 1 3,028 06-01-17, 11:52 AM
آخر رد: silverlight
  Convert Bitmap To Integer & Viceversa silverlight 5 3,557 28-05-16, 02:17 PM
آخر رد: CLARO

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


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