Почему & ldquo; шагать & rdquo; в конструкторе System.Drawing.Bitmap быть кратным 4?

    public static List<string> _Split(this string input,string[] splt)
    {
        List<string> _Result=new List<string>();
        foreach(string _splt in splt)
        {
            if (splt.Count() == 1)
            { 
                _Result.AddRange(Regex.Split(input, _splt, RegexOptions.IgnoreCase).ToList());
            }
            else 
            {
                List<string> NewStr = Regex.Split(input, _splt, RegexOptions.IgnoreCase).ToList();
                foreach(string _NewStr in NewStr)
                {
                    List<string> NewSplt = splt.ToList();
                    NewSplt.Remove(_splt);
                    return _Split(_NewStr, NewSplt.ToArray());
                }
            } 
        }
        return _Result;
    } 

, затем используйте эту функцию ниже

public frmThematicConversation()
{
    InitializeComponent();
    string str = "a b c d e f g h a b c f a d c b f";
    string[] splt = { "a", "b" };
    List<string> _result = str._Split(splt);
}
21
задан Gorchestopher H 2 February 2010 в 16:56
поделиться

4 ответа

Это восходит к ранним разработкам ЦП. Самый быстрый способ прорезать биты растрового изображения - это читать их по 32 бита за раз, начиная с начала строки сканирования. Это работает лучше всего, когда первый байт строки сканирования выровнен по границе 32-битного адреса. Другими словами, адрес, кратный 4. На ранних процессорах наличие первого байта, выровненного неправильно, стоило бы дополнительных циклов ЦП, чтобы прочитать два 32-разрядных слова из ОЗУ и перемешать байты для создания 32-разрядного значения. Обеспечение того, чтобы каждая строка сканирования начиналась с выровненного адреса (автоматически, если шаг кратен 4), позволяет избежать этого.

На современных процессорах это больше не беспокоит, теперь выравнивание по границе строки кэша гораздо важнее. Тем не менее, требование по кратности 4 для шага по компромиссу не изменилось.

Кстати, вы можете легко рассчитать шаг по формату и ширине с помощью этого:

        int bitsPerPixel = ((int)format & 0xff00) >> 8;
        int bytesPerPixel = (bitsPerPixel + 7) / 8;
        int stride = 4 * ((width * bytesPerPixel + 3) / 4);
60
ответ дан Community 2 February 2010 в 16:56
поделиться

Помните, что stride отличается от width. У вас может быть изображение с 111 (8-битными) пикселями на строку, но каждая строка сохраняется в памяти 112 байтов.

Это сделано для эффективного использования памяти и, как сказал @Ian, хранит данные в int32.

2
ответ дан Matt Warren 2 February 2010 в 16:56
поделиться

Потому что он использует int32 для хранения каждого пикселя.

Sizeof(int32) = 4

Но не волнуйтесь, когда изображение сохраняется из памяти в файл, оно будет использовать наиболее эффективное использование памяти. Внутренне он использует 24 бита на пиксель (8 бит красного, 8 зеленого и 8 синего) и оставляет последние 8 бит избыточными.

1
ответ дан Dead account 2 February 2010 в 16:56
поделиться

Как было указано ранее Джейком, вы рассчитываете шаг, найдя байты на пиксель (2 на 16 бит, 4 для 32 бит) а затем умножить его по ширине. Поэтому, если у вас есть ширина 111 и 32-битное изображение, у вас будет 444, что является кратным 4.

Однако, скажем на минуту, что у вас есть 24-битное изображение. 24 бита равен 3 байтам, поэтому с шириной 111 пикселей у вас будет 333 в качестве вашего шага. Это, очевидно, не кратное 4. Итак, вы хотели бы раунд до 336 (следующий самый высокий показатель 4). Несмотря на то, что у вас есть немного дополнительного, это неиспользуемое пространство недостаточно значимо, чтобы действительно иметь большую разницу в большинстве применений.

К сожалению, вокруг этого ограничения нет (если вы всегда не используете 32 бит или 64 бит, которые всегда есть кратные 4.

2
ответ дан 29 November 2019 в 03:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: