ما هي الاختلافات بين الصورة النقطية لـ Windows وDIBSection؟

StackOverflow https://stackoverflow.com/questions/8352240

  •  27-10-2019
  •  | 
  •  

سؤال

أقوم بتحميل DIBSection من ملف يتضمن ما يلي:

HBITMAP bmpIn = (HBITMAP) LoadImage(NULL, _T("c:\\Temp\\Temp.bmp"), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);

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

  • يتم ترتيب الأسطر في الذاكرة من أعلى إلى أسفل بدلاً من من أسفل إلى أعلى.لقد تحققت من أن الملف .bmp نفسه مرتب من الأسفل إلى الأعلى.
  • تكون حشوة الصف بمضاعفات 2 بايت بدلاً من 4.

لقد اكتشفت أيضًا فرقًا موثقًا عند الاستخدام CreateDIBSection لإنشاء DIBSection من البداية.

  • تم إرجاع القيمتين DIBSECTION.dsHandle وBITMAP.bmBits بواسطة GetObject سيكون فارغا.

أين الوثائق الخاصة بالاختلافين الأولين، وهل أفتقد أي شيء؟هذا مع نظام التشغيل Windows 7 ولكن لا يمكنني أن أتخيل أن الأمر سيكون مختلفًا بالنسبة للإصدارات الأخرى من Windows.

يحرر: بعض التفاصيل الإضافية.وهنا تفريغ عرافة من temp.bmp;إنها صورة مقاس 7×7 مع شريط أبيض أسفل الجانب الأيمن وقيم زرقاء تتزايد على طول الجانب الأيسر (0x10,0x20، وما إلى ذلك).يمكنك أن ترى أن النتيجة النهائية (00،00،70) هي الأولى وأن هناك 3 بايت من المساحة المتروكة.

00: 42 4d de 00 00 00 00 00 00 00 36 00 00 00 28 00
10: 00 00 07 00 00 00 07 00 00 00 01 00 18 00 00 00
20: 00 00 a8 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 00 00 70 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 60 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: ff ff ff 00 00 00 50 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 40 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: ff ff ff 00 00 00 30 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 20 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: ff ff ff 00 00 00 10 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 ff ff ff 00 00 00

إليك نموذج برنامج لقراءة ملف .bmp وكتابة محتوياته.لقد قمت بإزالة التحقق من الأخطاء للإيجاز.

int _tmain(int argc, _TCHAR* argv[])
{
   HBITMAP bmpIn = (HBITMAP) LoadImage(NULL, argv[1], IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
   FILE * out = _tfopen(argv[2], _T("wb"));
   DIBSECTION obj = {0};
   GetObject(bmpIn, sizeof(obj), &obj);
   cout << "dsBm.bmHeight = " << obj.dsBm.bmHeight << endl;
   cout << "dsBmih.biHeight = " << obj.dsBmih.biHeight << endl;
   cout << "sizeof(DIBSECTION) = " << sizeof(DIBSECTION) << endl;
   fwrite(&obj, sizeof(DIBSECTION), 1, out);
   int stride = (((obj.dsBmih.biWidth * obj.dsBmih.biBitCount) + 15) / 16) * 2;
   int bytecount = abs(obj.dsBmih.biHeight) * stride;
   vector<BYTE> bits(bytecount);
   GetBitmapBits(bmpIn, bytecount, &bits[0]);
   fwrite(&bits[0], 1, bytecount, out);
   fclose(out);
   return 0;
}

وإليك إخراج البرنامج أعلاه بالإضافة إلى تفريغ سداسي عشري للملف الذي تم إنتاجه:

dsBm.bmHeight = 7
dsBmih.biHeight = 7
sizeof(DIBSECTION) = 84
00: 00 00 00 00 07 00 00 00 07 00 00 00 18 00 00 00
10: 01 00 18 00 00 00 11 00 28 00 00 00 07 00 00 00
20: 07 00 00 00 01 00 18 00 00 00 00 00 a8 00 00 00
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 ff ff ff 00 20 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff 00
80: 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 ff ff ff 00 40 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 ff ff ff 00 50 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff
c0: ff 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 ff ff ff 00 70 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 ff ff ff 00
هل كانت مفيدة؟

المحلول

اتصل بـ GetDIBits بدلاً من GetBitmapBits.مستندات GetBitmapBits (هنا) تشير إلى أن هذا يؤدي إلى إرجاع بيانات لصورة نقطية تعتمد على الجهاز، بينما لديك صورة نقطية مستقلة عن الجهاز.وتشير أيضًا إلى أنه لا ينبغي استخدام هذه المكالمة وأنها موجودة فقط للتوافق مع 16 بت.لذلك، فإن استخدام GetDIBits يجب أن يفي بالغرض.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top