• 0
MiCcSoft

تعلم طريقة وضع صورة ونص في نفس الملف

سؤال

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

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

مثل برنامج Acrobat Reader يقوم بفتح ملفات PDF التحي تحتوي

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

الخطوة الأولى : كيف نقوم بتنظيم البيانات للكتابة

- يجب علينا أن نقوم بصنع جدوال (Structures)للتنظيمم والجدول التي ستلزمنا

الجدوال الأول

	Structure ImageType
Dim img As Byte()
Dim AnyText() As String
End Structure

وهو لحفظ مجموعة صورة مع نص خاص بكل واحدة لكن أنتبه !

المتغير img هو المسؤول عن تخزين الصور لكنه ليس من النوع image

بل من النوع Byte !!! لماذا ؟

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

إلى byte قبل

الجدول الثاني

	Structure TextType
Dim Text As String
End Structure

هذا الجدول مسؤول عن حفظ النصوص

الجدول TypeToWrite

	Structure TypeToWrite
Dim Images() As ImageType
Dim Texts() As TextType
End Structure

كما تلاحظ هو عبارة عن مصفوفات من الجدولين ImageType و TextType

وهو يتم تجهيزه في الاخر للكتابة

الأن أنتهينا من الجداول والأن عبارة عن دالة لكتابة الجدول TypeToWrite إلى ملف

	Public Sub WrtieToFile(ByVal FileName As String, ByVal Data As TypeToWrite)
Dim i As Integer = FreeFile()
Try
FileOpen(i, FileName, OpenMode.Binary)
FilePut(i, Data)
FileClose(i)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub

------------------------------- الكتابة -------------------------------

والأن سنبدأ في طريقة تجهيز الجداول للكتابة :

الدالة : CreateMyFile

	Public Sub CreateMyFile(ByVal im As Image, ByVal Strings As String, ByVal FileName As String)
Try
Dim MemoStream As New IO.MemoryStream
im.Save(MemoStream, System.Drawing.Imaging.ImageFormat.Jpeg)
Dim Arr() As Byte = MemoStream.ToArray
Dim img As New ImageType
img.img = Arr
img.AnyText = "Your Tag"
Dim T As New TextType
T.Text = Strings
Dim AllData As New TypeToWrite
Dim ImgTypes() As ImageType = {img}
Dim St() As TextType = {T}
AllData.Images = ImgTypes
AllData.Texts = St
WrtieToFile(FileName, AllData)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical)
End Try
End Sub

هذا الدالة تستقبل ثلاثة بارمترات وهي :

im - وهو الصورة المراد وضعها في الملف

strings - وهو النصوص المراد وضعها في الملف

FileName - وهو أسم الملف المراد الكتابة إليه

طريقة العمل :

أولا - كما ذكرنا سابقا فإن الجدول ImageType لا يقبل الصور إلى بعد تحويلها إلى Bytes وطريقة تحويلها

عن طريقة IO.MemoryStream

ثانيا شرح الدالة :في السطر الأول قمنا بتعريف متغير من النوع IO.MemoryStream لتحويل الصورة الممررة إلى Byte()

السطر الثاني لحفظ الصورة داخل ل MemoStream الأن أصبحت الصورة داخل MemoStream على شكل Byte() وهو المطلوب

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

السطر الرابع نقوم ببدأ استعمال الجداول التي قمنا بعملها ونبدأ مع ImageType ونعرف متغير أسمه img

في السطر الخامس والسادس نقوم يتهيئة المتغيرات الخاصة بالمتغير img

في السطر السابع نقوم ببدء أستعمال الجدول TextType وفي الثامن نقوم بتهيئة متغيراته

في السطر التاسع نقوم بإستخدام الجدول TypeToWrite

طبعا هنا لم نسمح إلا بوضع صورة واحدة في الملف ويمكن تعديلها

الأن السطرالعاشر والحادي عشر نقوم بتعريف مصفوفات من الجداول imageType و TextType لأن

الجدوال TypeTowrite لا يقبل إلا مصفوفات لكي يتسنى وضع أكثر من جدوال

في السطرين 13 و 14 نقوم بتهيئة المتغير AllData

وفي السطر السادس عشر نكون قد جهزنا بيانات الملف ونستخدم الدالة WriteToFile التي قمنا بصنعها لكتابة

البيانات إليه

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

------------------------------- القراءة -------------------------------

الكود هو :

		Dim ImgType() As ImageType - 1
Dim TextTyp() As TextType - 2
Dim AllDat As New TypeToWrite - 3
Dim i As Integer = FreeFile() -4
Dim Fi As String - 5
Dim a As New OpenFileDialog -6
a.Filter = "MiCcSoft Test Files (*.tst)|*.tst" - 7
If a.ShowDialog = Windows.Forms.DialogResult.OK Then -8
Fi = a.FileName -9
Else -10
MsgBox("لم تقم بتحديد ملف", MsgBoxStyle.Critical) -11
Exit Sub - 12
End If - 13
FileOpen(i, Fi, OpenMode.Binary)-14
FileGet(i, AllDat) - 15
FileClose(i) - 16
ImgType = AllDat.Images - 17
TextTyp = AllDat.Texts - 18
Dim MemoStr As New IO.MemoryStream - 19
Dim Bi As New IO.BinaryWriter(MemoStr) - 20
Bi.Write(ImgType(0).img, 0, ImgType(0).img.Length) - 21
Bi.Flush() -22
pic.Image = Image.FromStream(MemoStr - 23
24 -textD.Text = TextTyp(0).Text

الشرح :الأسطر الأول و الثاني و الثالث نقوم بتعريف الجداول لتعبأتها عند فتح الملف الهدف

الأسطر من 4 حتى 13 خي للأستعراض عن ملف

السطر 14 نقوم بفتح الملف الهدف

السطر 15 نقوم بملئ المتغير AllData الذي قمنا بتعريفه في السطر الثالث وهو من النوع TypeToWrite أي جدول

السطر 16 نقوم بإغلاق الملف بعد قراءته

السطرين 17 و 18 نقوم بملئ المتغيرين ImgType و TextTyp الذين قمنا بتعريفهما في السطرين الأول والثاني

الأن كما تذكر سابقا حولنا من image إلى Byte() عن طريق IO.MemoryStream ولعكس التحويل أي من Byte()

إلى image يجب أستخدام IO.MemoryStream

في السطر 19 قمنا بتعريف متغير من النوع IO.MemoryStream

الأن كيف سنقوم بكتابة ل Byte() إلى المتغير MemoStr

عن طريق IO.BinaryWriter

في السطر 20 قمنا يتعريف متغير من النوع IO.BinaryWriter وجعلنا البرامتر الخاص به هو MemoStr

السطر 21 نقوم بكتابة Byte() إلى MemoStr

السطر 22 نقوم بإنهاء ل الكتابة

وباقي الأسطر لإظهار النتائج

وهنا نكون قد أنتهينا وقد قمت بإرفاق مثال على هذا الدرس

تم بعون الله

Your_File_Exp.zip

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

9 إجابة على هذا السؤال .

  • 0

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

برافو .. أحسنت بدون هيك مقالات و دروس ..

لا يكون لدينا منتدى جيد .. ;)

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

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

جزاك الله خيراً الدرس رائع جداً..

وكذلك درسك الآخر "درس لتعليم كيفية دمج الملفات في ملف حاضن"..

لكن عندي سؤال أرجو أن تعينني على حل مشكلته..

خاصة في موضوع دمج عدة ملفات في ملف حاضن، والاثنين على نفس الطريقة..

المشكلة هي:

أنت تقوم بتحميل الملف الذي سيتم تخزينه إلى الذاكرة، وهذا يرهق الذاكرة ويسبب فشل العملية لو كان حجم الملف كبير مقارنة بحجم الذاكرة!

فمثلاً لو أردنا حفظ ملف بحجم 500 ميجا والذاكرة 512 ميجا فسيموت الجهاز حتى تغلق البرنامج..

مع العلم أنك لو صبرت عليه فسيقوم بحفظ الملف بشكل ناجح.

فإن قيل فلم تضع ملف بحجم 500 ميجا؟!

أقول لا ليست هذه هي القصة فقط، بل أيضاً عند القراءة نفس المشكلة!

فلو وضعت 500 صورة كل صورة حجمها فقط 1 ميجا، عند القراءة سيقوم البرنامج بتحميل مصفوفة alldata وهي محجوزة في الذاكرة سيقوم بتعبئة كل البايتات عليها، يعني 500 ميجا لأن مجموع حجم الصور في مثالنا 500 ميجا.

وهكذا تعود المشكلة من جديد!

FileOpen(i, Fi, OpenMode.Binary)-14

FileGet(i, AllDat) - 15

FileClose(i) - 16

هذه السطور التي أقصدها وهي من كود القراءة في هذا المثال..

المهم: الحل هو إيجاد طريقة لتحميل بايتات الملف بشكل متقطع إلى الذاكرة ثم حفظهم ثم تحميل الباقي وهكذا..

وفي القراءة لا بد أن يوجد حل لقراءة Info معلومات الصورة من غير قراءة الصورة وبعد ذلك عندما يختار المستخدم صورة معينة من خلال الinfo الذي أمامه يقوم البرنامج باستخراج الملف المطلوب فقط.

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

لو حلت هذه المشاكل لأصبح WinArab حقاً..

شكراً لك على كل حال..

وأنا سأبذل جهداً إن شاء الله للتفكير بحل لهذه المشكلة.

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

تم تعديل بواسطه أبو اليسر
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

بإذن الله سأقوم بحل هذه المشاكل

-1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

موضوع جميل و فكرة جميلة

لكن يمكنك ان تطور الفكرة اكثر لتنتج ملفات خاصة بك

ماذا لو اني حملت الملف عبر الشبكة الانترنت و انقطع الاتصال

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

لذا يمكن ان تضيف تروسية للملف تحوي حجم الصورة و حجم النص

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

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

يمكنك ان تمنع ذلك باضافة حقل تخزن فيه نتيجة تطبيق احدى خوارزميات الـ Hash مثل

SHA256 على بيانات الصورة و بالتالي لن يتمكن اي شخص من تعديل الصورة لان برنامجك

يتحقق من تطابق نتيجة تطبيق الخوارمية على البيانات الموجودة مع القيمة المخزنة في الملف

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

عندها تحصل على ملفات خاصة بك تخزن بيانات ضخمة (يمكن ان تستفيد من ذلك لصنع كتاب الكتروني و قارئ له)

حاول ان تطور الشيفرة المستخدمة هناك مقاطع تغييرها يساعد بشكل كبير على انشاء الملف بسرعة (ستتلاحظ ذلك مع الملفات الضخمة)

عملك جميل و تابع به لكن هذه مجرد نصائح للتطوير

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
يمكن ان تستفيد من ذلك لصنع كتاب الكتروني و قارئ له

فكرة معقولة وليست مستحيلة وأنا جاهز

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

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

Your_File_Exp2.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

قبل ان تقوم بأي شيء ضع تصميما لملفك هذا سيسهل عليك البرمجة و يسهل حل المشاكل

إضافة لتغييرك اساليب التعامل مع البيانات كالقراءة و الحفظ

قم باستخدام OOP و استغل ميزاتها هذا سيمسهل عليك عمليات انشاء و فتح الملفات و يمكنك من اجراء

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

فكرة معقولة وليست مستحيلة وأنا جاهز

اذا احببت ان تقوم بذلك حاول و اذا واجهتك اي مشاكل سأساعك

يمكن ان تخزين صور و نصوص في ملفات XML

الملف المرفق هو تجربة قديمة لي لتخزين و استخراج صورة من ملف XML

كما انه يتضمن فكرة عن تشفير الصورة بخوارزمية TripleDES

قد تفضل استخدام ملفات XML لأنها تسهل التعامل مع البيانات إضافة للدعم الكبير لها من ميكروسوفت

في معظم منتجاتها

WindowsApplication12.zip

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم..

ماذا عن المشاكل التي كلمتك عنها، هل غيرت منها شيئاً؟

أرجو التوضيح..

وشكراً على المثال الثاني..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

هذا الكود توصلت إليه يقوم بقراءة الملف بشكل متقطع إلى الذاكرة (1000 بايت كل مرة) أو حسب تحديدك والافتراضي من مايكروسفت 100بايت..

المهم ثم يقوم بكتابة هذه الكتلة من البايتات إلى الملف الوجهة أيضاً بشكل متقطع فهو يضيف 1000 بايت كل مرة على نفس الملف حتى تنتهي عملية الكتابة..

وبالتالي فلا مشكلة على الذاكرة مهما كان حجم الملف..

وسرعته ممتازة..

Dim w As Date = Now

'Create a file stream from an existing file.

Dim fi As New IO.FileInfo("c:\1.nrg")

Dim fi2 As New IO.FileInfo("C:\Output.nrg")

Dim fs As IO.FileStream = fi.OpenRead

Dim fd As IO.FileStream = fi2.OpenWrite

Dim startIndex As Long = 0

Dim retval As Long

'Read 1000 bytes into an array from the specified file.

Dim nBytes As Integer = 1000

Dim ByteArray(nBytes) As Byte

startIndex = 0

retval = fs.Read(ByteArray, 0, nBytes)

Do While retval = nBytes

fd.Write(ByteArray, 0, nBytes)

' Reposition start index to end of the last buffer and fill buffer.

startIndex += nBytes

retval = fs.Read(ByteArray, 0, nBytes)

Loop

fd.Write(ByteArray, 0, retval)

ByteArray = Nothing

fs.Close()

fd.Close()

Dim ww As Integer = DateAndTime.DateDiff(DateInterval.Second, w, Now)

MsgBox(ww, , "ثانية")

الآن فقط يجب دمج هذا الكود مع برنامجك في عمليتي القراءة والكتابة حتى تنتهي مشكلة تحميل كل الملفات إلى الذاكرة..

والسلام عليكم

تم تعديل بواسطه أبو اليسر
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .