كيفية قياس عرض البيكسل من رقم في خط / حجم معين (C #)

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

سؤال

أحاول حساب عرض البكسل لأعمدة Excel، كما هو موضح في هذا المشنور, باستخدام الصيغة الرسمية من مواصفات OpenXML. ومع ذلك، من أجل تطبيق هذه الصيغة، أحتاج إلى معرفة عرض أرقام الحد الأقصى التابع طبيعي الخط، وهو عرض البكسل لأوسع رقم أرقام. تعطي مواصفات OpenXML هذا المثال كإظهار:

باستخدام الخط Calibri كمثال، فإن الحد الأقصى لعرض الرقم 11 نقطة حجم هو 7 بكسل (في 96 نقطة في البوصة).

لقد راجعت أن هذا صحيح من خلال فحص بصريا رقم Calibri 11 نقطة وهو بالفعل 7 بكسل واسعة. لذلك، أحاول إنشاء طريقة ستعيد الحد الأقصى لعرض الرقم لأي خط / بحجم.

لقد اتبعت التوصيات المقدمة في هذا السؤال, ، لكنها لا تنتج النتائج التي أتوقعها.

إليك رمز الاختبار الخاص بي:

var font = new Font("Calibri", 11.0f, FontStyle.Regular);

for (var i = 0; i < 10; i++)
{
    Debug.WriteLine(TextRenderer.MeasureText(i.ToString(), font));
}

هذه التقارير تفيد بأن جميع الأرقام لها عرض 15.

أي اقتراحات من فضلك؟

شكرا، تيم

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

المحلول

أولا اسمحوا لي أن أقول إن الكود الذي يجب أن أظهر عليه يبدو وكأنه اختراق فظيع وأنا لا أقدمه كحل. بدلا من ذلك، آمل أن يكشف عن سلوك القياس الذي قد يؤدي إليك إلى حلك النهائي.

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

var font = new Font("Calibri", 11.0f, FontStyle.Regular);
int underscoreWidth = TextRenderer.MeasureText("__", font).Width; 
for (var i = 0; i < 10; i++)
   {
      int charWidth = TextRenderer.MeasureText(String.Concat("_", i.ToString(), "_"), font).Width - underscoreWidth;
      Debug.WriteLine(charWidth);
   }

نصائح أخرى

Texstrender ليس دقيقا دائما الطريقة التي تتوقعها:

من MSDN: http://msdn.microsoft.com/en-us/library/8wafk2kt.aspx.

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

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

إلقاء نظرة على http://msdn.microsoft.com/en-us/library/6xe5hazb(vs.80).aspx.

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

        float size = 5;
        for (int ix = 0; ix < 10; ++ix) {
            var font = new Font("Calibri", size, FontStyle.Regular);
            string txt = new string('0', 100);
            SizeF sz1 = TextRenderer.MeasureText("00", font) - TextRenderer.MeasureText("0", font);
            Console.WriteLine("{0} {1:N3}", size, sz1.Width);
            size += 2;
        }

انتاج:

5 4.000
7 5.000
9 6.000
11 7.000
13 9.000
15 10.000
17 12.000
19 13.000
21 14.000
23 16.000

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

يمكن أن يكون قياس عرض النص هو nighmare .. أنا لا أعرف لماذا جعلوا الأمر مربكا للغاية ..

هيريس الطريقة الأكثر دقة حصلت على قياس طول النص:

    protected int _MeasureDisplayStringWidth ( Graphics graphics, string text, Font font )
    {
        if ( text == "" )
            return 0;

        StringFormat format = new StringFormat ( StringFormat.GenericDefault );
        RectangleF rect = new RectangleF ( 0, 0, 1000, 1000 );
        CharacterRange[] ranges = { new CharacterRange ( 0, text.Length ) };
        Region[] regions = new Region[1];

        format.SetMeasurableCharacterRanges ( ranges );
        format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

        regions = graphics.MeasureCharacterRanges ( text, font, rect, format );
        rect = regions[0].GetBounds ( graphics );

        return (int)( rect.Right );
    }

أنا لست متأكدا بنسبة 100٪، ما تحتاجه بالضبط.

ولكن قد ترغب في إلقاء نظرة على صفحة Microsoft هذه:

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