2017-01-29 4 views
0

Я работаю над основным графическим редактором с использованием векторов, и я пытаюсь получить матрицу, подобную той, что показана ниже, 4 на 4, но с каждым слотом, содержащим 3 значения (значения RGB)Редактор изображений и размеры вектора C++

0 0 0 100 0 0  0 0 0 255 0 255 
0 0 0 0 255 175  0 0 0  0 0 0 
0 0 0 0 0 0  0 15 175 0 0 0 
255 0 255 0 0 0  0 0 0 255 255 255 

до сих пор я был в состоянии получить матрицу поставить в этот код (я думаю ..)

int rows; 
int columns; 
fin >> rows; 
fin >> columns; 
vector<vector<int> > image_dimensions(rows); 
for (int i = 0; i < rows; i++) 
    image_dimensions[i].resize(columns); 

Это только создать матрицу, полную 0s. Как я могу сделать каждый слот, содержащий три значения RGB, как показано на примере? Наконец, какой сложный цикл я должен использовать, чтобы иметь возможность изменять отдельные значения в каждом слоте, например, поворачивать 0 0 0 на 155 0 255?

+1

Замените int на rgb (где rgb: 'struct rgb {std :: uint8_t r, g, b;}') и прочитайте в каждом компоненте для каждого элемента rgb. (Вы можете уйти с 8 бит, потому что afaict ваш диапазон 0-255) – Borgleader

+0

Подождите. Я смущен. Что я могу заменить, чтобы получить значения RGB ??? – Caladin00

+0

Вы не можете использовать OpenCV? Это должно многое помочь. – cpatricio

ответ

1

В данный момент вы используете примитивный целочисленный тип. Рассмотрим хранить больше некоторый комплекс как класс RGB:

class RGB { 
private: 
    std::unit8_t r, g, b; 
public: 
    RGB() {} 
    RGB(int r, int g, int b) : r(r), g(g), b(b){ } 
} 

Вы можете простые объекты конструкции с:

rgb = RGB(255,255,255); 

После этого вы можете хранить объекты в векторе.

int rows; 
int columns; 
fin >> rows; 
fin >> columns; 
vector<vector<RGB> > image_dimensions(rows); 
for (int i = 0; i < rows; i++) 
    image_dimensions[i].resize(columns); 

Разница в вашем примере заключается в том, что вектор может хранить объекты из класса RGB. Если вы хотите, вы можете теперь перебирать вектор:

for (int i = 0; i < columns; i++) 
    for (int i = 0; i < rows; i++) 
     image_dimensions[i][j] = RGB(0,0,0); 

редактировать: на основе комментария, это, вероятно, лучше не тратить пространство и использовать тип такой Uint8. Поэтому больше нет необходимости в проверке. И вы можете использовать плоский вектор и вычислить 2d-индекс. Если вы работаете с большими матрицами, это будет генерировать более эффективное решение.

edit2: Второе возможное решение без создания нового класса является использование класса станд кортеж:

std::tuple<std::unit8_t, std::unit8_t, std::unit8_t > rgb(0,0,0); 

В этом случае ваш вектор должны хранить этот вид кортежа. Дополнительная информация о кортежах: klick

К слову: создание небольшого класса или структуры не должно вас беспокоить. ;-)

+1

Предоставление по умолчанию ctor, и вам не понадобится этот второй двойной цикл. Используя uint8, и вам не нужен метод проверки (wtv читает, что значения должны делать проверку правильности ввода). Как только вы сделаете, что сеттер станет бесполезным (у RGB практически нет инвариантов, поэтому он не нуждается в геттерах и сеттерах). Теперь вы сохранили пространство * и *, если вам нужно заполнить текстуру rgb в любом месте, где вы можете просто memcopy, потому что вы, скорее всего, в нужном формате (который вы используете, если используете int). – Borgleader

+0

Другие мелкие nitpick, вероятно, лучше иметь плоский вектор и эмулировать индексацию 2d, чем вектор векторов, но так как это код OPs ... – Borgleader

+0

Я ценю подсказку, но я стараюсь избегать создания другого класса, если требуется. Нужно ли вообще делать это без необходимости создания структуры RBG. – Caladin00