سؤال

أود أن أكون قادرًا على إنشاء صورة نقطية كبيرة (على سبيل المثال 20.000 × 20.000) بكسل في تطبيق C++ MFC، باستخدام فئة مشتقة من CDC للكتابة على الصورة النقطية.لقد حاولت استخدام وحدات تحكم المجال DC للذاكرة كما هو موضح في مستندات MSDN، ولكن يبدو أنها مقيدة بالأحجام المتوافقة مع برنامج تشغيل العرض الحالي.

أستخدم حاليًا برنامج تشغيل طباعة الصورة النقطية للقيام بهذه المهمة، ولكنه بطيء للغاية ويستخدم كميات كبيرة جدًا من مساحة التخزين الوسيطة بسبب التخزين المؤقت لمعلومات GDI.

الحل الذي أبحث عنه يجب ألا يتضمن ملفات تعريف أو تخزين مؤقت، حيث أن النموذج الذي أرسمه يتطلب عدة ملايين من استدعاءات GDI لعرضه.

يمكنني استخدام نهج فرق تسد عبر وحدات تحكم المجال DC ذات الذاكرة المتعددة، ولكن يبدو أنها تقنية مرهقة وغير أنيقة إلى حد ما.

أي أفكار؟

هل كانت مفيدة؟

المحلول

يبدو أن CDC وCBitmap يدعمان فقط الصور النقطية المعتمدة على الجهاز، وقد يكون حظك أكبر في إنشاء الصورة النقطية باستخدامها :: إنشاء قسم DIBS, ، ثم قم بإرفاق CBitmap لذلك.واجهات GDI الخام قديمة بعض الشيء، لسوء الحظ.

ربما لن يكون لديك الكثير من الحظ مع 20000 × 20000 بمعدل 32 بت لكل نقطة، على الأقل في تطبيق 32 بت، حيث يأتي ذلك بحوالي 1.5 جيجابايت من الذاكرة، لكنني حصلت على HBITMAP صالح مرة أخرى مع 16 بت لكل ثانية:

BITMAPINFOHEADER bmi = { sizeof(bmi) };
bmi.biWidth = 20000;
bmi.biHeight = 20000;
bmi.biPlanes = 1;
bmi.biBitCount = 16;
HDC hdc = CreateCompatibleDC(NULL);
BYTE* pbData = 0;
HBITMAP hbm = CreateDIBSection(hdc, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&pbData, NULL, 0);
DeleteObject(SelectObject(hdc, hbm));

نصائح أخرى

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

وبالنظر إلى دقة الصورة الكبيرة هذه، لا يمكنك إنشاء الصورة باستخدام صور نقطية متوافقة.

مثال:

عمق البكسل = 32 بت = 4 بايت لكل بكسل

عدد البكسل = 20.000 * 20.000 = 400.000.000

إجمالي البايتات = عدد البكسل * 4 = 1.600.000.000 بايت = 1.562.500 كيلو بايت ~= 1525 ميجابايت ~= 1.5 جيجابايت

أنا أتكهن بشأن النوايا النهائية، ولكن لنفترض أنك تريد إنشاء خريطة هائلة والسماح للمستخدمين باستكشافها باستخدام تكبيرات تفصيلية للغاية.يجب عليك إنشاء تنسيق ملف صورة مخصص؛يمكنك وضع داخل هذا الملف طبقات مختلفة تحتوي على شبكات من الصور النقطية، على سبيل المثال، لتسريع العرض.يمكن أن تستخدم عملية التجسيد GDI DIBs أو GDI+ لإنشاء صور جزئية ثم عرضها معًا.بالطبع يحتاج هذا إلى بعض التجارب/التحسين للوصول إلى الشعور المثالي للمستخدم.

حظ سعيد

للحفاظ على استخدام الذاكرة الخاصة بك ضمن الحدود المقبولة، سيتعين عليك استخدام استراتيجية "فرق تسد".إنها ليست عملية اختراق، إذا تم تنفيذها بشكل صحيح فهي في الواقع طريقة أنيقة جدًا للتعامل مع الصور النقطية ذات الحجم غير المحدود.إذا قمت بتصميمها بشكل صحيح، فيمكنك دمج طرق "عرض/إظهار جزء الصورة فقط"، و"عرض الصورة بأكملها بدقة منخفضة للعرض على الشاشة" و"عرض كل شيء إلى صورة نقطية على القرص" في محرك واحد ويحمي مستخدمي الكود الخاص بك (على الأرجح أنت خلال أسبوعين؛)) ) من الأجزاء الداخلية.أعمل على منتج به نفس المشكلات:يتم عرض الخرائط (التي قد تكون كبيرة) إما على الشاشة أو على ملفات .bmp.

إذا كانت الصورة يجب أن تكون بهذه الدقة - على سبيل المثال، مسح عالي الدقة للأشعة السينية - فقد ترغب في النظر في كتابة إجراءات تخزين مؤقت مخصصة لها - 1.5 جيجابايت مكلفة للغاية - حتى بالنسبة لأجهزة الكمبيوتر المكتبية الحديثة.

إذا كان يعتمد على المتجهات، فيمكنك النظر إلى SVG لأنه يدعم منافذ العرض ومعظمها يسمح لك بالعرض إلى تنسيقات أخرى.أستخدم SVG إلى JPG عبر Batik (java) لذلك من الممكن القيام بذلك.

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