مع وجود العديد من الأدوات الجاهزة و المكتبات اللتي توفر الكثير على المبرمج, قد ينظر البعض بغرابة الي عندما أقول انني اريد تحميل ملف bmp يدويا بدون استخدام اي من تلك الأدوات! و بالتالي قد لا يعير احدا هذا الموضوع اهتماما, و و لكن لا تستهينوا بالموضوع, فهناك عدة فوائد لتعلم تحميل ملفات من هذا النوع. فهذا يعطيك نموذج عن كيفية اختيار صيغة معينة لتخزين المعلومات في الملفات, و كيفية استخدام هذه الصيغة لتخزين و تحميل المعلومات من الملفات, و هذا مفيد جدا في برمجة الألعاب. ألم تفكر يوما كيف تقوم بتخزين المراحل في ملفات و من ثم تحميلها؟ لعلك كنت تتصور دائما ان هذه مهمة مستحيلة او صعبة جدا على شخص مثلك و أنها للعباقرة فقط! لا تقلق أبدا, فالعملية ليست صعبة لتلك الدرجة, و الإنسان عدو ما جهل, فما دمت لم تر مثالا من قبل عن تخزين و استرجاع المعلومات من الملفات, فسيصعب عليك تخيل كيف يمكنك ان تقوم بهذه الأشياء, و لكن عندما ترى مثالا حيا, و تقوم بنفسك بكتابة الكود اللازم لقراءة المعلومات من الملف, سيختلف الوضع كثيرا! من المفيد دائما للمبرمج ان يطلع على ما يجري خلف الكواليس, فهو أمر يوسع المدارك و يجعل الشخص يشعر بأنه يعرف شيئا مهما!! ههههه, و يستطيع من خلالها ان يتفلسف على الناس هذا الموضوع للمناقشة, لا تتوقعوا مني القيام بإلقاء محاضرات عن الموضوع! ما اريد القيام به هو اعطاء دفعات بسيطة لكي نناقش الموضوع, كل من له دلو فليدلي به دون أي خجل! أكرر دون أي خجل! طبعا لازم اول شي نعرف ما اللذي نحن بصدده! و هنا الؤال هو, ما هي ملفات bmp و لماذا نريد تحميلها؟ طبعا اذا لم تكن تعرف ما هي ملفات bmp فلا أدري ما أقول لك!! سوى أنك في المكان الخطأ! هو طبعا ملف لخزن الصور, يحتوي على صورة واحدة, غير مضغوطة (من الممكن ان تكون الصورة مضغوطة, و لكن خلونا ناخذهة حبة حبة.. سنركز فقط على الصور الغير مضغوطة). كيف يضع الصورة داخل الملف؟ الاجابة باختصار هي عن طريق وضع لون كل النقاط في الصورة pixels بشكل متسلسل في الملف, و يقوم ايضا بوضع معلومات عن الصورة, مثل الطول و العرض و بعض التفاصيل الأخرى. يمكن البحث في جووجل عن bmp file format من أجل الحصول على المزيد من التفاصيل. و هذه بعض الوصلات اللتي تتحدث عن تفاصيل محتويات الملف, او صيغة الملف, يمكن الضغط على اي منها و قرائتها, فهي ليست سلسلة, بل كلها تقليد لبعض! http://pages.cpsc.ucalgary.ca/~walpole/325...E_INFO/BMP.html http://pages.cpsc.ucalgary.ca/~walpole/325...pfileformat.htm http://pages.cpsc.ucalgary.ca/~walpole/325...O/bmpffrmt.html مع ملاحظة انها كلها من موقع احد اساتذتي كما قلت, نريد ان يكون هذا الموضوع نقاشا, و ليس مجرد محاضرات او دروس, فكل من له دلو فليدلي به! نريد الخروج من المناقشة و كلنا قد فهمنا طريقة تخزين و تحميل ملفات الـ bmp, إن شاء الله يمكن الملاحظة من خلال الروابط السابقة او من خلال البحث في جووجل, ان ملفات bmp في نظام وندوز مقسمة الى ثلاثة أقسام: اول قسمين هما بمثابة مقدمة عن الملف, و القسم الثالث هو سسلسلة النقاط في الصورة نفسها. مع وجود قسم اختياري و هو الـ palette, فإذا كان كل بكسل في الصورة عبارة عن 8 بت, فسيكون هناك palette, و هي مثل الـ indexed mode في الـ photoshop لمن لا يعرف. يرجى ملاحظة ان هذا ليس درس, بل مجرد محاولة لتحريك النقاش .. كيف يكون درس و انا لم اكتب كود تحميل ملفات bmp الا اليوم!!! و لأول مرة!! مش ناقص غير اني اعطي فيها درس!! اعتقد انه يمكننا اعتبار الملف مقسم الى قسمين, المقدمة و الصورة. المقدمة بالنسبة لنا هي عبارة عن سلسلة من الـ bytes, نقوم بقرائتها بالتسلسل لكي نحصل على المعلومات المطلوبة عن هذه الصورة! أول بايت هو دائما 'B' و ثاني بايت هو دائما 'M', يلي ذلك اربعة بايتات (تمثل int) تعطينا حجم الملف بالبايتات .. يليها سلسلة أخرى من المعلومات, يمكن النظر اليها في الجداول الموجودة في بعض الروابط اللتي وضعتها أعلاه. اريد منكم الان قرائة الجداول و من ثم كتابة كود جزئي, يقوم بفتح ملف bmp و استخراج المعلومات اللتي تراها مهمة فقط. و اريد من كل شخص مناقشة الصعوبات اللتي واجهته او تواجهه في كتابة مثل هذا الكود. ارجو من الجميع استخدام عقولهم و عدم البحث في الانترنت عن أكواد جاهزة!! في الحقيقة احد الروابط يقدم كود جاهز .. ارجو محاولة عدم استخدامه, فنحن نريد تشغيل عقولنا هنا قليلا. طبعا هنالك عدة طريق لقرائة المقدمة الموجودة في ملفات الـ bmp, و هي مسألة مثل كل مسائل البرمجة, لا يوجد لها حل صحيح واحد, بل يوجد لها عدة حلول, و لا احد يخجل ان يضع حله!! انا شخصيا حلي قد يكون من أسوأ الحلول .. و لكني لن اضعه هنا قبل ان يقوم شخصان على الأقل بوضع محاولاتهما .. لا أريد ان أكون واقفا هنا مثل الأهبل .. أكلم نفسي!! عموما هذا كود مكتوب في الأصل بالسي .. يقوم بفتح ملف و اخذ المعلومات منه, مع افتراض ان الصورة تستخدم indexed color
typedef unsigned int uint;typedef unsigned char byte;typedef struct{ byte red; byte green; byte blue;} PalleteEntry;typedef struct { char * fileName; byte * imageData; uint fileSizeInBytes; uint imageWidth; uint imageHeight; uint imageDataOffset; uint numberOfColours; PalleteEntry * palleteTableArray;} BmpInfo;BmpInfo * loadImage( char * fileName ){ int i = 0; int rasterSize; int currentPosition; byte readBuffer[128]; int skip; //dummy used to read unused data; FILE * file = fopen( fileName, "rb" ); //read binary? BmpInfo * bmp = new BmpInfo; bmp->fileName = fileName; fread( readBuffer, 1, 2, file); //read the first two bytes, should be 'BM' if( readBuffer[0] != 'B' && readBuffer[1] != 'M' ) { printf("wrong bmp signature"); return 0; } fread( &(bmp->fileSizeInBytes), 4, 1, file ); //read file size in bytes and store it in the bmp structure fread( &skip, 4, 1, file ); //skip next 4 bytes (they are unused) fread( &(bmp->imageDataOffset), 4, 1, file ); //the next 4 bytes in the file are the 4-byte-integer value for the offset fread( &skip, 4, 1, file ); //this should read 40 into skip, indicating the size of the BITMAPINFOHEADER block if( skip != 40 ) { printf(" BITMAPINFOHEADER size wrong "); return 0; } fread( &(bmp->imageWidth), 4, 1, file ); //next 4 bytes indicate the width of the bitmap fread( &(bmp->imageHeight), 4, 1, file ); //next 4 bytes indicate the height of the bitmap skip = 0; fread( &skip, 2, 1, file ); //next two bytes indicate number of planes, should be 1 always if( skip != 1 ) { printf(" wrong number of planes " ); return 0; } skip = 0; fread( &skip, 2, 1, file ); //next two bytes indicate color mode, this code assumes it must be 8 if( skip != 8 ) { printf("This is not a palettized bmp .... no can do!!"); return 0; } fread( &skip, 4, 1, file ); //next 4 bytes are an integer indicating type of compression, for the purpose of this code, it must be 0 for no compression if( skip != 0 ) { printf("Can't open compressed bmp"); return 0; } fread( &skip, 4, 1, file ); //next 4 bytes indicate size of compressed image, seems unimportant to me!! // from one of the docs: (compressed) Size of Image. It is valid to set this =0 if Compression = 0 fread( &skip, 4, 1, file ); // horizontal resolution, i.e. pixels per meter, seems unimportant to me! fread( &skip, 4, 1, file ); //vertical resolution, see above line. fread( &skip, 4, 1, file ); //next 4 bytes indicate the number of colors used, I don't think that we need this for the palllete, because the pallete size is always 256 fread( &skip, 4, 1, file ); // number of important colors, I'm thinking this is not important for our purposes //create pallete table bmp->palleteTableArray = new PalleteEntry[256]; //read the pallete for( i = 0; i < 256; i++ ) { //is it stored as r,g,b or b,g,r? it seems to work only if I read it as b,g,r??! fread( &(bmp->palleteTableArray[i].blue), 1, 1, file ); //read B byte fread( &(bmp->palleteTableArray[i].green), 1, 1, file ); //read G byte fread( &(bmp->palleteTableArray[i].red), 1, 1, file ); //read R byte fread( &skip, 1, 1, file ); //ignore 4th byte } currentPosition = fgetc( file ); //create a buffer for image data rasterSize = bmp->imageHeight * bmp->imageWidth; bmp->imageData = new byte[rasterSize]; //read the raster data fread( bmp->imageData, rasterSize, 1, file ); return bmp;}