diff --git a/include/FractalApp.hpp b/include/FractalApp.hpp index f7819dc..05f85ab 100644 --- a/include/FractalApp.hpp +++ b/include/FractalApp.hpp @@ -178,6 +178,8 @@ public: } } + void TakeScreenshot(); + protected: private: }; diff --git a/src/FractalApp.cpp b/src/FractalApp.cpp index c4ae564..1c749a0 100644 --- a/src/FractalApp.cpp +++ b/src/FractalApp.cpp @@ -90,6 +90,10 @@ void FractalInspectorApp::ParseCmdLineMessage(const std::string &message) { } + if (misc::string_matches(cmd, {"screenshot", "screeny", "capture"})) { + return TakeScreenshot(); + } + console->Log(std::format("No such command: {}", cmd), Colors::Red); } @@ -215,7 +219,7 @@ void FractalInspectorApp::CreateMenu() { auto* misc = toolbar->AddSubmenu("Miscellaneous"); { - misc->AddButton("Take Screenshot"); + misc->AddButton("Take Screenshot", [this] () { this->TakeScreenshot(); }); misc->AddButton("Take Collage"); } @@ -670,3 +674,61 @@ void FractalInspectorApp::OnKeyDown(const ReWindow::KeyDownEvent &e) { void FractalInspectorApp::OnKeyUp(const ReWindow::KeyUpEvent &e) { scene->ObserveKeyInput(e.key, false); } + +void FractalInspectorApp::TakeScreenshot() { + std::vector pdatac4 = this->canvas->GetTexture()->GetPixelData(); + std::vector pdatac3; + pdatac3.reserve(pdatac4.size()); + for (auto Color:pdatac4) { + pdatac3.emplace_back(Color.r, Color.g, Color.b); + } + uint8_t* frameBuffer = reinterpret_cast(pdatac3.data()); + + time_t t = std::time(nullptr); + tm tm = *std::localtime(&t); + + std::ostringstream filename; + filename << std::put_time(&tm, "%Y-%m-%d %H-%M-%S") << ".bmp"; + + std::ofstream file(filename.str(), std::ios::out | std::ios::binary); + + Vector2i wh = this->canvas->GetDimensions(); + + int fileSize = 54 + 3 * wh.x * wh.y; + unsigned char bmpfileheader[14] = {'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0}; + unsigned char bmpinfoheader[40] = {40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0}; + bmpfileheader[2] = (unsigned char) (fileSize); + bmpfileheader[3] = (unsigned char) (fileSize >> 8); + bmpfileheader[4] = (unsigned char) (fileSize >> 16); + bmpfileheader[5] = (unsigned char) (fileSize >> 24); + bmpinfoheader[4] = (unsigned char) (width); + bmpinfoheader[5] = (unsigned char) (width >> 8); + bmpinfoheader[6] = (unsigned char) (width >> 16); + bmpinfoheader[7] = (unsigned char) (width >> 24); + bmpinfoheader[8] = (unsigned char) (height); + bmpinfoheader[9] = (unsigned char) (height >> 8); + bmpinfoheader[10] = (unsigned char) (height >> 16); + bmpinfoheader[11] = (unsigned char) (height >> 24); + + file.write((char*)bmpfileheader, 14); + file.write((char*)bmpinfoheader, 40); + + int padding = (4 - (width * 3) % 4) % 4; + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + unsigned char pixel[3]; + pixel[0] = frameBuffer[(y * width + x) * 3 + 2]; + pixel[1] = frameBuffer[(y * width + x) * 3 + 1]; + pixel[2] = frameBuffer[(y * width + x) * 3]; + file.write((char*)pixel, 3); + } + for (int p = 0; p < padding; ++p) { + file.write((char*)"\0", 1); + } + } + + file.close(); + + console->Log(std::format("Took screenshot: {}", filename.str())); + +}