使用可视化/保存极大数量的像素

时间:2017-02-22 15:05:29

标签: c++ image visual-c++ sfml mandelbrot

我用C ++编写了一个计算mandelbrot-set的程序。现在我想要将它可视化(将其保存在图片中)。但是当我试图保存64k图片时,会出现一些问题。那么保存像素图片的最佳方法是什么?至少是视觉效果呢?

修改

当我想创建一个示例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;
}

1 个答案:

答案 0 :(得分:0)

您的计划在通话期间失败sf::Image::create

当您进入newPixels功能时,您最终会在此处创建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 !! 过大时,这会失败:

<?php

$key = md5('pass');

function encrypt($string, $key){
    $string = rtrim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $string, MCRYPT_MODE_ECB)));
    return $string;
}

$output = encrypt("test", $key);
echo $output;

?>

结论:SFML无法处理大量图像。