2017-02-22 27 views
0

Я сделал программу на C++, которая вычисляет mandelbrot-set. Теперь я хочу визуализировать его (сохранить его на картинке). Но когда я пытаюсь сохранить изображение 64k, возникают проблемы. Итак, каков наилучший способ сохранить изображение пикселей или, по крайней мере, визуализировать его?Визуализация/сохранение очень большого количества пикселей с помощью

Edit:

Когда я хочу создать для примера 64K (61440 * 34560) изображение будет ошибка «Нарушение прав доступа при записи в позиции 0x0 ...» (первоначально на немецком и перевод), и программа останавливается. Эта ошибка появляется с очень высоким разрешением. При более низких разрешениях программа работает так, как предполагается.

#include <SFML\Graphics.hpp> 
#include <stdlib.h> 
#include <complex> 
#include <cmath> 
#include <thread> 

//4K : 3840 * 2160 
//8K : 7680 * 4320 
//16K: 15360 * 8640 
//32K: 30720 * 17280 
//64K: 61440 * 34560 
//128K:122880 * 69120 


const unsigned long width = 61440; //should be dividable by ratioX & numberOfThreads! 
const unsigned long height = 34560; //should be dividable by ratioY & numberOfThreads! 

const unsigned int maxIterations = 500; 

const unsigned int numberOfThreads = 6; 

const int maxWidth = width/3; 
const int maxHeight = height/2; 
const int minWidth = -maxWidth * 2; 
const int minHeight = -maxHeight; 

const double ratioX = 3.0/width; 
const double ratioY = 2.0/height; 

sf::Image img = sf::Image(); 


int getsGreaterThan2(std::complex<double> z, int noIterations) { 
    double result; 
    std::complex<double> zTmp = z; 
    std::complex<double> c = z; 
    for (int i = 1; i != noIterations; i++) { 
     zTmp = std::pow(z, 2) + c; 
     if (zTmp == z) { 
      return 0; 
     } 
     z = std::pow(z, 2) + c; 
     result = std::sqrt(std::pow(z.real(), 2) + std::pow(z.imag(), 2)); 
     if (result > 2) { 
      return i; 
     } 
    } 
    return 0; 
} 


void fillPixelArrayThreadFunc(int noThreads, int threadNr) { //threadNr ... starts from 0 

    double imgNumber; 
    double realNumber; 

    double tmp; 

    long startWidth = ((double)width)/noThreads * threadNr + minWidth; 
    long endWidth = startWidth + width/noThreads; 

    for (long x = startWidth; x < endWidth; x++) { 
     imgNumber = x * ratioX; 
     for (long y = minHeight; y < maxHeight; y++) { 
      realNumber = y * ratioY; 
      long xArray = x - minWidth; 
      long yArray = y - minHeight; 
      tmp = getsGreaterThan2(std::complex<double>(imgNumber, realNumber), maxIterations); 
      if (tmp == 0) { 
       img.setPixel(xArray, yArray, sf::Color(0, 0, 0, 255)); 
      } 
      else { 
       img.setPixel(xArray, yArray, sf::Color(tmp/maxIterations * 128, tmp/maxIterations * 128, tmp/maxIterations * 255, 255)); 
      } 
     } 
    } 
} 

int main() { 
    img.create(width, height, sf::Color::Black); 

    std::thread *threads = new std::thread[numberOfThreads]; 
    for (int i = 0; i < numberOfThreads; i++) { 
     threads[i] = std::thread(std::bind(fillPixelArrayThreadFunc, numberOfThreads, i)); 
    } 
    for (int i = 0; i < numberOfThreads; i++) { 
     threads[i].join(); 
    } 

    img.saveToFile("filename.png"); 
    return 1; 
} 
+0

Добро пожаловать в stackoverflow.com. Пожалуйста, найдите время [страницы справки] (http://stackoverflow.com/help), особенно разделы с именем [«Какие темы можно задать здесь?»] (Http://stackoverflow.com/help/ по-теме) и [«Какие типы вопросов я должен избегать?»] (http://stackoverflow.com/help/dont-ask). Также, пожалуйста, [возьмите тур] (http://stackoverflow.com/tour) и [читайте о том, как задавать хорошие вопросы] (http://stackoverflow.com/help/how-to-ask). Наконец, узнайте, как создать [Минимальный, Полный и Подтверждаемый пример] (http://stackoverflow.com/help/mcve). –

+5

_ когда я пытаюсь сохранить изображение на 64 КБ, возникают некоторые проблемы _... И что конкретно эти проблемы? Вы не можете ожидать, что кто-нибудь даст правильный ответ с таким неопределенным описанием. –

+0

Какой формат изображения вы сохраняете как: JPEG? TIFF? PNG? GIF? BMP? WMF? Существуют ли ограничения по размеру для формата, который вы используете? –

ответ

0

Ваша программа не работает во время разговора img.create(width, height, sf::Color::Black);.

Когда вы вступаете в функции sf::Image::create вы в конечном итоге здесь, где создается вектор, это просто терпит неудачу, когда width * height слишком велик, как в вашем случае:

//////////////////////////////////////////////////////////// 
void Image::create(unsigned int width, unsigned int height, const Color& color) 
{ 
    if (width && height) 
    { 
     // Create a new pixel buffer first for exception safety's sake 
     std::vector<Uint8> newPixels(width * height * 4); 
            ^61440* ^34560 = 8'493'465'600 bytes !! 

Вывод: SFML не может обрабатывать огромные изображения.

+0

Спасибо! Думаю, мне нужно найти другой способ визуализировать его. – SgtDomo

+0

Создание нескольких небольших изображений и сшивание их вместе может быть способом. –

+0

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