A Qt-s Mandelbrot nagyító (az svn-ben: bevezetes/elsoQt/masodikQt/Frak) példába nem nehéz beépíteni, hogy az S billentyű lenyomására elmentse fájlba a nagyított képet, hiszen a képet egy QImage objektumra rajzoltuk, ami el tudja magát menteni.
A szóban forgó Qt GUI-s példában figyelnünk kellett arra, hogy a számolás időigényes lehet, ezért blokkolhatja a felület megjelenítését, így eleve párhuzamosan külön (QThread) szálban valósítottuk azt meg. Parancssorban egyszerűbb lehet az életünk, itt akár szekvenciálisan is beleszőhetjük a számítást a programunkban. A következő kis példákban használunk néhány könyvtárat, például a png++ vagy a pngwriter könyvtárakat. Az első példában "kockásítjuk" a
képet, azaz kis (kocka_meret) blokkokban kiszámoljuk az pixelek RGB kódjainak átlagát és az így kapott átlagos RGB értékkel színezzük (az alább specifikált kocka függvénnyel) az egész blokkot:
void kocka(png::image<png::rgb_pixel>& kep, int r_atlag, int g_atlag, int b_atlag, int x, int y, int blokk_szelesseg, int blokk_magassag);
fordítva, futtatva
[norbi@sgu mandel]$ g++ kockapng.c++ `libpng-config --ldflags` -o kockapng
ezt kapjuk:
[norbi@sgu mandel]$ ./kockapng obivan3.png obivan3.kocka.png
Kockasitas.................................................................................................................obivan3.kocka.png mentve
a kockapng.c++ forrást majd a poszt végi tovább link kattintása után találod.
A mandelpng.c++ forrás a png++ könyvtárra építve, a mandelpngw.cpp pedig a pngwriter-el rajzolja a Mandelbrot halmazt egy png fájlba, utóbbi "érdekessége", hogy a képre szöveget is rajzol:
kockapng.c++
// "Kockásító" // Programozó Páternoszter // // Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com // http://progpater.blog.hu/2011/03/26/kepes_egypercesek // // Fordítás: // g++ kockapng.c++ `libpng-config --ldflags` -o kockapng #include <iostream> #include "png++/png.hpp" void kocka(png::image<png::rgb_pixel>& kep, int r, int g, int b, int j, int i, int jjj, int iii) { png::rgb_pixel rgb (r/iii*jjj, g/iii*jjj, b/iii*jjj); for (int jj = 0; jj < jjj; ++jj) for (int ii = 0; ii < iii; ++ii) kep.set_pixel (j+jj, i+ii, rgb); } int main (int argc, char *argv[]) { if (argc != 3) { std::cout << "Hasznalat: ./kockapng bemeno_fajlnev kimeno_fajlnev"; return -1; } // png-t készítünk a png++ csomaggal png::image <png::rgb_pixel> kep (argv[1]); std::cout << "Kockasitas"; int ratlag = 0, gatlag = 0, batlag = 0, kocka_meret = 3, iii, jjj; for (int i = 0; i < kep.get_height (); i+=kocka_meret) { for (int j = 0; j < kep.get_width (); j+=kocka_meret) { ratlag = gatlag = batlag = 0; for (int ii = 0; ii < kocka_meret && i+ii < kep.get_height (); ++ii) for (int jj = 0; jj < kocka_meret && j+jj < kep.get_width (); ++jj) { png::rgb_pixel rgb = kep.get_pixel (j+jj, i+ii); ratlag += rgb.red; gatlag += rgb.green; batlag += rgb.blue; iii = ii; jjj = jj; } kocka(kep, ratlag, gatlag, batlag, j, i, jjj, iii); } std::cout << "." << std::flush; } kep.write (argv[2]); std::cout << argv[2] << " mentve" << std::endl; }
mandelpng.c++
// Mandelbrot png // Programozó Páternoszter // // Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com // http://progpater.blog.hu/2011/03/26/kepes_egypercesek // // Fordítás: // g++ mandelpng.c++ `libpng-config --ldflags` -o mandelpng #include <iostream> #include "png++/png.hpp" int main (int argc, char *argv[]) { if (argc != 2) { std::cout << "Hasznalat: ./mandelpng fajlnev"; return -1; } // számítás adatai double a = -2.0, b = .7, c = -1.35, d = 1.35; int szelesseg = 600, magassag = 600, iteraciosHatar = 1000; // png-t készítünk a png++ csomaggal png::image <png::rgb_pixel> kep (szelesseg, magassag); // a számítás double dx = (b-a)/szelesseg; double dy = (d-c)/magassag; double reC, imC, reZ, imZ, ujreZ, ujimZ; // Hány iterációt csináltunk? int iteracio = 0; std::cout << "Szamitas"; // Végigzongorázzuk a szélesség x magasság rácsot: for (int j=0; j<magassag; ++j) { //sor = j; for (int k=0; k<szelesseg; ++k) { // c = (reC, imC) a rács csomópontjainak // megfelelő komplex szám reC = a+k*dx; imC = d-j*dy; // z_0 = 0 = (reZ, imZ) reZ = 0; imZ = 0; iteracio = 0; // z_{n+1} = z_n * z_n + c iterációk // számítása, amíg |z_n| < 2 vagy még // nem értük el a 255 iterációt, ha // viszont elértük, akkor úgy vesszük, // hogy a kiinduláci c komplex számra // az iteráció konvergens, azaz a c a // Mandelbrot halmaz eleme while (reZ*reZ + imZ*imZ < 4 && iteracio < iteraciosHatar) { // z_{n+1} = z_n * z_n + c ujreZ = reZ*reZ - imZ*imZ + reC; ujimZ = 2*reZ*imZ + imC; reZ = ujreZ; imZ = ujimZ; ++iteracio; } kep.set_pixel(k, j, png::rgb_pixel(255-iteracio%256, 255-iteracio%256, 255-iteracio%256)); } std::cout << "." << std::flush; } kep.write (argv[1]); std::cout << argv[1] << " mentve" << std::endl; }
mandelpngw.cpp
// Mandelbrot pngw // Programozó Páternoszter // // Bátfai Norbert, nbatfai@inf.unideb.hu, nbatfai@gmail.com // http://progpater.blog.hu/2011/03/26/kepes_egypercesek // // Fordítás: // g++ mandelpngw.cpp `freetype-config --cflags` -lpng -lpngwriter -lz -lfreetype -o mandelpngw #include <iostream> #include <pngwriter.h> int main (int argc, char *argv[]) { if (argc != 2) { std::cout << "Hasznalat: ./mandelpngw fajlnev"; return -1; } // számítás adatai double a = -2.0, b = .7, c = -1.35, d = 1.35; int szelesseg = 600, magassag = 600, iteraciosHatar = 1000; // png-t készítünk a pngwriter csomaggal pngwriter kep(szelesseg, magassag, 65535, argv[1]); // a számítás double dx = (b-a)/szelesseg; double dy = (d-c)/magassag; double reC, imC, reZ, imZ, ujreZ, ujimZ; // Hány iterációt csináltunk? int iteracio = 0; std::cout << "Szamitas"; // Végigzongorázzuk a szélesség x magasság rácsot: for (int j=0; j<magassag; ++j) { //sor = j; for (int k=0; k<szelesseg; ++k) { // c = (reC, imC) a rács csomópontjainak // megfelelő komplex szám reC = a+k*dx; imC = d-j*dy; // z_0 = 0 = (reZ, imZ) reZ = 0; imZ = 0; iteracio = 0; // z_{n+1} = z_n * z_n + c iterációk // számítása, amíg |z_n| < 2 vagy még // nem értük el a 255 iterációt, ha // viszont elértük, akkor úgy vesszük, // hogy a kiinduláci c komplex számra // az iteráció konvergens, azaz a c a // Mandelbrot halmaz eleme while (reZ*reZ + imZ*imZ < 4 && iteracio < iteraciosHatar) { // z_{n+1} = z_n * z_n + c ujreZ = reZ*reZ - imZ*imZ + reC; ujimZ = 2*reZ*imZ + imC; reZ = ujreZ; imZ = ujimZ; ++iteracio; } kep.plot(k, j, 65535-(65535*iteracio)/iteraciosHatar, 65535-(65535*iteracio)/iteraciosHatar, 65535-(65535*iteracio)/iteraciosHatar); } std::cout << "." << std::flush; } kep.plot_text_utf8("/usr/share/fonts/dejavu/DejaVuLGCSerifCondensed-BoldItalic.ttf", 18,10,magassag-40,0.0, "Programozó Páternoszter",0 ,0 ,0); kep.close(); std::cout << argv[1] << " mentve" << std::endl; }