Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Самый быстрый способ прочитать 3 байта по заданному адресу указателя?

Автор вопроса: Robin RodricksОтветов: 2

В настоящее время я читаю пиксельные данные растрового изображения, используя BitmapData, доступный после блокировки растрового изображения. Метод, который я использую, читает каждый байт цвета отдельно и будет медленнее, чем чтение 4-байтового int непосредственно по заданному указателю. Но, к сожалению, мой битовый массив составляет 24 бит на пиксель, что означает, что на пиксель приходится 3 байта, а не 4. Так есть ли способ быстро прочитать всего 3 байта и преобразовать их в int по заданному адресу указателя?

// read pixel color
byte* Pix = (byte*)bmpScan0 + (y * bmpStride) + (x * 3);
byte R = *(Pix + 2);
byte G = *(Pix + 1);
byte B = *(Pix);
int RGB = ((int)R << 16) | ((int)G << 8) | (int)B;
  • @MitchWheat А, очень хорошее замечание; форматы пикселей растрового изображения повсюду, черт возьми, от конечности ... JerKimball 26.02.2013
  • Ваш пример кода не совпадает с тем, что вы просите - он показывает чтение 3 байтов в отдельные переменные вместо int с маскировкой 8 старших бит ... Также рассмотрите возможность показать немного больше кода - тот, который у вас есть, похоже, делает много математических для получения следующего байта. Alexei Levenkov 26.02.2013
  • @AlexeiLevenkov - Я обновил свой код, чтобы показать, чего мне нужно достичь. Robin Rodricks 26.02.2013
  • Для меня не похоже на C #: P Corey 26.02.2013

performancebitmapint

Ответы

Ответ 1 · рейтинг 2 · Corey

Вместо нескольких операций - чтения, маскирования и т. Д. - вы можете прочитать полное int по адресу пикселя и замаскировать лишний байт.

int Pix = *(int*)((byte*)bmpScan0 + (y * bmpStride) + (x * 3)) & 0x00FFFFFF;

В зависимости от вашего порядка байтов вам может потребоваться сдвиг вниз вместо маскирования, и ваши цветовые компоненты могут быть перевернуты - BGR вместо RGB.

Да, и у вас, вероятно, будут проблемы со скоростью из-за чтения из памяти, которая не выровнена по 4-байтовой границе. Их можно обойти, но решения часто хуже, чем исходная проблема.

Ответ 2 · рейтинг -1 · JerKimball

Вы имеете в виду что-то вроде:

int foo = *(some pixel address in memory);
byte R = (byte)(foo & 0xff0000 >> 16);
byte G = (byte)(foo & 0x00ff00 >> 8);
byte B = (byte)(foo & 0xff);

Изменить: должен оставить этот ответ неотредактированным, чтобы сохранить преемственность в других комментариях, но больше не применим на основе изменений самого вопроса. :)

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы