2017-02-22 1 views
0

mandelbrot-set을 계산하는 C++ 프로그램을 만들었습니다. 이제 시각화하고 싶습니다 (그림으로 저장). 그러나 64k 사진을 저장하려고하면 몇 가지 문제가 발생합니다. 그렇다면 픽셀의 그림을 저장하거나 적어도 시각적으로 저장하는 가장 좋은 방법은 무엇입니까?매우 많은 수의 픽셀을 시각화/저장

편집 : (원래 독일어의 "위치 0x0에 쓰는 동안 ... 액세스 위반"오류가있을 것입니다 예 64K에 대한 (61440 * 34560) 이미지를 생성 할

및 번역) 프로그램이 중지됩니다. 이 오류는 매우 높은 해상도로 나타납니다. 저해상도에서는 프로그램이 예상대로 작동합니다.

#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/) 섹션을 읽어보십시오. on-topic) 및 [ "어떤 유형의 질문을하지 않아야합니까?"] (http://stackoverflow.com/help/dont-ask). 또한 [둘러보기] (http://stackoverflow.com/tour)와 [좋은 질문을하는 방법에 대해 읽어보십시오.] (http://stackoverflow.com/help/how-to-ask). 마지막으로 [Minimal, Complete, Verifiable Example] (http://stackoverflow.com/help/mcve)를 만드는 방법을 배우십시오. –

+5

_ 64k 사진을 저장하려고하면 몇 가지 문제가 _ 발생합니다. 그리고 이러한 문제는 정확히 무엇입니까? 당신은 누군가가 그런 막연한 묘사로 유효한 대답을 줄 것을 기대할 수 없습니다. –

+0

어떤 그림 형식으로 저장합니까? JPEG? 사소한 말다툼? PNG? GIF? BMP? WMF? 사용중인 형식에 대한 크기 제한이 있습니까? –

답변

0

전화가 img.create(width, height, sf::Color::Black); 인 동안 프로그램이 실패합니다. width * height 귀하의 경우와 같이 너무 큰 경우

당신이 newPixels 벡터를 만들어 여기에 끝낸다 sf::Image::create 함수로 단계

이 단순히 실패

//////////////////////////////////////////////////////////// 
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

관련 문제