2016-06-01 5 views
0

Я хочу вычислить кучу пикселей, а затем поместить их в QImage, используя QtConcurrent::mappedReduced. Но я получаю ошибку QImage::setPixel: coordinate (636,442) out of range. Вероятно, это связано с использованием конструктора QImage по умолчанию, который создает нулевой образ. Я не нашел никакого способа в документации, как установить аргументы конструктора или как обеспечить начальное значение для сокращения. Есть ли способ, как это сделать? Я думал, что для сокращения требуется указать начальное значение ... как в JS ... но у Qt, вероятно, была другая идея.QtConcurrent уменьшить с начальным значением

скелет:

struct Pixel{ 
    QRgb value; 
    QPoint pos; 
}; 

void reducer(QImage &result, const Pixel &pixel){ 
    result.setPixel(pixel.pos,pixel.value); 
} 

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

void reducer(QImage &result, const Pixel &pixel, int width, int height){ 
    if(result.width()==0) 
     result = QImage(width,height, QImage::Format_RGB888); 
    result.setPixel(pixel.pos,pixel.value); 
} 
... 
auto boundReducer = std::bind(reducer,_1,_2,width,height); 

ответ

0

Эта проверка очень дешевая, но ваш редуктор очень мало работает, поэтому у вас будут проблемы с производительностью, несмотря ни на что.

Чтобы сделать это немного более чистым, проверьте, не построено ли изображение по умолчанию - т. Е. Значение null, и передайте начальное изображение в качестве параметра вместо пропуска ширины/высоты.

void reducer(QImage &result, const Pixel &pixel, const QImage& initial) { 
    if (result.isNull()) 
     result = initial; 
    result.setPixel(pixel.pos,pixel.value); 
} 

auto boundReducer = std::bind(reducer, _1, _2, 
           QImage(width,height,QImage::Format_RGB888)); 

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

+0

Спасибо: D Да ... прохождение в предварительно сконструированном изображении имеет смысл ... но почему вы думаете, что будут проблемы с производительностью из-за простоты редуктора? – petoknm

+0

@petoknm Поскольку операция 'setPixel' занимает гораздо меньше времени, чем накладные расходы на итерацию контейнера' pixel' и отправку пикселей в пул потоков для обработки. «SetPixel» - это 32-разрядная операция записи в память. Там нет смысла распараллеливать его, в значительной степени, потому что быстрее всего вы можете это сделать с полной пропускной способностью памяти. Другими словами, эта операция ограничена полосой пропускания. Ограничения ввода-вывода не получаются от распараллеливания. Вы можете отсортировать контейнер пикселя вдоль y, x, затем повторить его, и он будет находиться на скорости ОЗУ. –

+0

Спасибо за объяснение – petoknm