لماذا bitmapsource.create رمي engumentException؟
-
22-09-2019 - |
سؤال
أحاول الحصول على صورة نقطية من البيانات الأولية لإظهارها في WPF ، باستخدام صورة و Nitmapsource:
Int32[] data = new Int32[RenderHeight * RenderWidth];
for (Int32 i = 0; i < RenderHeight; i++)
{
for (Int32 j = 0; j < RenderWidth; j++)
{
Int32 index = j + (i * RenderHeight);
if (i + j % 2 == 0)
data[index] = 0xFF0000;
else
data[index] = 0x00FF00;
}
}
BitmapSource source = BitmapSource.Create(RenderWidth, RenderHeight, 96.0, 96.0, PixelFormats.Bgr32, null, data, 0);
RenderImage.Source = source;
ومع ذلك ، فإن الدعوة إلى bitmapsource.create ترمي engumentException ، قائلاً "لا تندرج القيمة ضمن النطاق المتوقع". أليس هذه هي الطريقة للقيام بذلك؟ هل أنا لا أجري هذه المكالمة بشكل صحيح؟
المحلول
خطوتك غير صحيحة. Stride هو عدد البايتات المخصصة لخط مسح واحد من صورة نقطية. وبالتالي ، استخدم ما يلي:
int stride = ((RenderWidth * 32 + 31) & ~31) / 8;
واستبدل المعلمة الأخيرة (حاليًا 0
) مع stride
على النحو المحدد أعلاه.
فيما يلي تفسير لصيغة الخطوة الغامضة:
حقيقة: يجب محاذاة خطوط المسح على حدود 32 بت (المرجعي).
ستكون الصيغة الساذجة لعدد البايتات لكل سطرح:
(width * bpp) / 8
ولكن هذا قد لا يعطينا صورة نقطية محاذاة على حدود 32 بت و (العرض * BPP) قد لا يكون قابلاً للقسمة على 8.
لذا ، ما نفعله هو أننا نجبر نقطتنا على الحصول على 32 بت على الأقل (نفترض ذلك width > 0
):
width * bpp + 31
ثم نقول أننا لا نهتم ببتات الترتيب المنخفضة (بت 0--4) لأننا نحاول التوافق مع حدود 32 بت:
(width * bpp + 31) & ~31
ثم اقسم على 8 للعودة إلى البايتات:
((width * bpp + 31) & ~31) / 8
يمكن حساب الحشو بواسطة
int padding = stride - (((width * bpp) + 7) / 8)
ستكون الصيغة الساذجة
stride - ((width * bpp) / 8)
لكن width * bpp
قد لا تتماشى على حدود البايت ، وعندما لا تكون هذه الصيغة ستحسب الحشوة بواسطة بايت. (فكر في صورة نقطية واسعة 1 بكسل باستخدام 1 BPP. الخطوة هي 4 وستقول الصيغة الساذجة أن الحشو هو 4 ولكن في الواقع هو 3.) لذلك نضيف قليلاً لتغطية الحالة width * bpp
ليست حدود بايت ومن ثم نحصل على الصيغة الصحيحة المذكورة أعلاه.