#c #pointers
#c #указатели
Вопрос:
У меня есть указатель, возвращенный из функции
rs2::video_frame frame = frames.get_color_frame();
const void* data = frame.get_data();
Я знаю, что этот указатель представляет собой массив значений RGB (т.Е. 3 char
с) размера frame.get_data_size()
.
Как я могу изменить определенные цвета пикселей, учитывая, что
int bpp = frame.get_bytes_per_pixel();
int width = frame.get_width();
int height = frame.get_height();
int offset = (y * width * bpp) (x * bpp);
int r = offset;
int g = offset 1;
int b = offset 2;
// ?data[r] = newRed;
// ?data[g] = newGreen;
// ?data[b] = newBlue;
Комментарии:
1. Приведите его к указателю типа pixel, затем используйте смещения.
void*
это не то, чем вы можете управлять напрямую.2. Вам нужно указать регистр
data
char*
, чтобы разыменовать его.3. @tadman Я знаю о приведении и все такое. Я программировал на C / C немного, много лет назад, но вопрос в том, как .
4. Если вы вернулись к программированию на C , то пришло время освежить основы. C и C имеют здесь совершенно разные подходы, поэтому не путайте их с C / C , что не имеет значения. Используйте
static_cast
для C .5. @tadman чтобы дать вам представление, в последний раз, когда я касался компилятора, был на 386, используя TurboC 3.5. Некоторое время назад.
Ответ №1:
Вам было бы проще, если бы у вас был объектно-ориентированный подход:
struct Pixel {
short red;
short green;
short blue;
};
Пусть ваш фрейм работает с std::vector<Pixel> pixels
; который возвращается по ссылке. std::vector<Pixel>amp; get_data();
pixels[y * width x].red = newRed;
pixels[y * width x].green = newGreen;
pixels[y * width x].blue = newBlue;
Если вам действительно нужно работать void*
, попробуйте это
char* data = static_cast<char*>(const_cast<void*>(dataframe.get_data()));
// Since you also const cast it becomes more and more dangerous. You really need know what you are doing.
size_t bpp = frame.get_bytes_per_pixel();
size_t width = frame.get_width();
size_t height = frame.get_height();
size_t offset = (y * width * bpp) (x * bpp);
size_t r = offset;
size_t g = offset 1;
size_t b = offset 2;
*(data r) = newRed;
*(data g) = newGreen;
*(data b) = newBlue;
Для массовых обновлений вы можете использовать memset
.
См. https://godbolt.org/z/xvc1xs за подробностями.
Комментарии:
1. вам также нужно отбросить константу, чтобы написать
2. FWIW
memset
сработал!memset((void *)data r, (char) newRed, (size_t) 1);
3. Вы правы, указатель должен быть не
const
таким, как у меня в моем примере godbolt. Я исправляю это в ответе. Вашиmemset
работы, потомуconst
что вы отбрасываете