2010-10-10 6 views
1

Я новичок в C++ и немного расстроен. Ниже, в pixVector, я сохраняю значение пикселя RGB каждого пикселя в пикселе и хочу сбросить все значения в массив байтов с пикселемArray, чтобы я мог выводить в файл изображения. HEIGHT и WIDTH относятся к размерам изображения. Код ниже работает отлично, но мне нужно указать размеры пикселейArray во время выполнения, потому что это может быть не всегда изображение 500x500.C++ Использование трехмерных динамических массивов и векторов

// WIDTH and HEIGHT specified at run-time 
vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT)); 

... 

unsigned char pixelsArray[500][500][3]; 

for (int i = 0; i < 500; i++) 
{ 
    for (int j = 0; j < 500; j++) 
    { 
     // Returns RGB components 
     vector<float> pixelColors = pixelArray[i][j].getColor(); 

     for (int k = 0; k < 3; k++) 
     { 
      pixels[i][j][k] = pixelColors.at(k); 
     } 
    } 
} 

// write to image file 
fwrite(pixelsArray, 1, 500*500*3, file); 

Если я установил HEIGHT и WIDTH вместо 500 и 500 выше, я получаю сообщение об ошибке, так как они не являются постоянными значениями. Теперь использование 3D-вектора действительно работает, но fwrite не примет вектор для его первого аргумента. Я попытался использовать массив с тремя указателями, но он вообще не работает - возможно, я использовал его неправильно. Здесь он использует 3D-вектор для пикселей:

vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT)); 

... 

vector< vector< vector<unsigned char> > > pixelsArray; 

for (int i = 0; i < HEIGHT; i++) 
{ 
    pixels.push_back(vector< vector<unsigned char> >()); 

    for (int j = 0; j < WIDTH; j++) 
    { 
     pixels[i].push_back(vector<unsigned char>()); 

     vector<float> pixelColors; 
     pixelColors = pixelArray[i][j].getColor(); 

     for (int k = 0; k < 3; k++) 
     { 
      pixels[i][j][k] = pixelColors.at(k); 
     } 
    } 
} 

// Error 
fwrite(pixelsArray, 1, 500*500*3, file); 

Предложения?

ответ

1

Вы можете использовать Boost.MultiArray внутри векторов векторов, что позволяет получить доступ к его базовой памяти с помощью метода .data().

Похоже, вы пытаетесь манипулировать изображениями, поэтому вам может потребоваться использовать Boost.Gil.

+0

ли библиотека подталкивание встроенный в C++? – Steve

+0

@John: Нет, но это примерно как кросс-платформа, которую может получить библиотека. –

1

Из последнего фрагмента кода:

vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT)); 

Использование заглавных имена переменных вы рискуете коллизии имен с макросами. В C++ все имена верхнего регистра обычно зарезервированы для макросов.

... 

vector< vector< vector<unsigned char> > > pixelsArray; 

Предположительно этот вектор такой же, как называется pixels ниже?

Если это так, то стандартным советом является то, что он помогает отправлять реальный код.

В любом случае, чтобы вывести эти байты в одну эффективную операцию, вам понадобятся байты, которые должны быть смежно сохранены в памяти. Таким образом, вектор векторов векторов отсутствует. Используйте один вектор (C++ гарантирует непрерывное хранение для буфера std::vector).

for (int i = 0; i < HEIGHT; i++) 
{ 
    pixels.push_back(vector< vector<unsigned char> >()); 

    for (int j = 0; j < WIDTH; j++) 
    { 
     pixels[i].push_back(vector<unsigned char>()); 

На данный момент у вас есть внутренний вектор, но он пуст, размер 0.

 vector<float> pixelColors; 
     pixelColors = pixelArray[i][j].getColor(); 

Предположительно pixelArray это вы определили экземпляр класса?

 for (int k = 0; k < 3; k++) 
     { 
      pixels[i][j][k] = pixelColors.at(k); 
     } 

Здесь вы пытаетесь назначить несуществующие элементы пустого самого внутреннего вектора. Вы можете либо правильно настроить его заранее, либо использовать метод push_back для каждого значения.

Кроме того, вы уверены, что значения float являются целыми числами в диапазоне от 0 до 255 (или, как правило, от 0 до UCHAR_MAX), а не, скажем, в диапазоне от 0 до 1?

Возможно, вам необходимо масштабировать эти значения.

} 
} 

// Error 
fwrite(pixelsArray, 1, 500*500*3, file); 

ЕслиpixelsArray был (непустой) вектор байтов, то вы могли бы использовать &pixelsArray[0] чтобы получить указатель на первый байт.

Теперь, я знаю, вышеизложенное раскрывает только некоторые из причин, и прямо не говорит вам, что правильно. :-)

Но потребуется дополнительная информация, чтобы привести пример кода для этого, например: (1) каковы ваши значения float и (2) что вы хотите в своем файле?

Во всяком случае, надеюсь, что это помогает,

- Alf

Смежные вопросы