GILの練習
GILの練習に、勉強中のboostをできるだけ濫用したサンプルを作ってみた。
しかし、GILの学習曲線はまるで地を這うようだ。
白い画像を生成してから、
乱数で座標を生成して点を打ちます。
#include <iostream> #include <boost/random.hpp> #include <boost/gil/gil_all.hpp> #include <boost/gil/extension/io/bmp_dynamic_io.hpp> #include <boost/timer.hpp> #include <boost/lexical_cast.hpp> #include <boost/iterator/iterator_facade.hpp> // 乱数イテレータ template<typename Value, class Engine, class Distribution> struct randomIterator : public boost::iterator_facade<randomIterator<Value, Engine, Distribution>, Value, boost::forward_traversal_tag, Value> { typedef boost::variate_generator<Engine, Distribution> Generator; Generator *rand_; unsigned int counter_; randomIterator(const Distribution &distribution) : rand_(new Generator(Engine(), distribution)), counter_(0) { } randomIterator(const Distribution &distribution, boost::uint32_t seed) : rand_(new Generator(Engine(seed), distribution)), counter_(0) { } randomIterator(const int endCount) : rand_(NULL), counter_(endCount) { } ~randomIterator() { delete rand_; } Value dereference() const { return rand_->operator()(); } void increment(){ ++counter_; } bool equal(const randomIterator &rhs) const { return counter_==rhs.counter_; } }; // GIL用 namespace GIL=boost::gil; // 座標単位 typedef int unit_t; typedef GIL::point2<unit_t> point_t; typedef GIL::rgb8_image_t image_t; typedef GIL::rgb8_view_t view_t; typedef GIL::rgb8_pixel_t pixel_t; // 点打ち struct FPut { const view_t &view_; const pixel_t &color_; FPut(const view_t &view, const pixel_t &color) : view_(view), color_(color) {} void operator()(const unit_t value) { view_[value]=color_; } }; void test_1(const char *fileName, unsigned int imageSize, unsigned int pointCount) { std::cerr << fileName << '(' << imageSize << 'x' << imageSize << ") " << pointCount << " random points." << std::endl; // create image image_t img(imageSize, imageSize); // fill white GIL::fill_pixels(GIL::view(img), pixel_t(255, 255, 255)); // random engine typedef boost::mt19937 Engine; //typedef boost::rand48 Engine; //typedef boost::ecuyer1988 Engine; //typedef boost::kreutzer1986 Engine; //typedef boost::hellekalek1995 Engine; //typedef boost::lagged_fibonacci607 Engine; // distribution typedef boost::uniform_int<unit_t> Distribution; Distribution dist(static_cast<unit_t>(0), static_cast<unit_t>(imageSize*imageSize-1)); //typedef boost::binomial_distribution<unit_t> Distribution; //Distribution dist(static_cast<unit_t>(imageSize-1)); // put random points typedef randomIterator<unit_t, Engine, Distribution >MersenneIterator; std::for_each( MersenneIterator(dist), MersenneIterator(pointCount), FPut(GIL::view(img), pixel_t(0,0,0))); // write bitmap GIL::bmp_write_view(fileName, GIL::view(img)); } int main(int argc, char **argv) { if(argc<4){ std::cerr << "usage: " << argv[0] << " {write bitmap} {btimap size} {point number}" << std::endl; return 1; } boost::timer t; test_1(argv[1], boost::lexical_cast<unsigned int>(argv[2]), boost::lexical_cast<unsigned int>(argv[3])); std::cerr << t.elapsed() << " sec." << std::endl; return 0; }
>release\sample.exe tmp2.bmp 200 10000 tmp2.bmp(200x200) 1000000 random points. 0.265 sec.