// Actually creates a histogram of colors. // Could be used for other things. unsigned Surface::getColorCount(ColorCountFlags flags) { const unsigned char* pix = reinterpret_cast<const unsigned char*>(pixels()); const int bpp = pf_->bytesPerPixel(); std::unordered_map<uint32_t,uint32_t> color_list; for(int y = 0; y < height(); ++y) { for(int x = 0; x < width(); ++x) { const unsigned char* p = pix; uint8_t r, g, b, a; switch(bpp) { case 1: pf_->getRGBA(*p, r, g, b, a); break; case 2: pf_->getRGBA(*reinterpret_cast<const unsigned short*>(p), r, g, b, a); break; case 3: pf_->getRGBA(*reinterpret_cast<const unsigned long*>(p), r, g, b, a); break; case 4: pf_->getRGBA(*reinterpret_cast<const unsigned long*>(p), r, g, b, a); break; } uint32_t col = (r << 24) | (g << 16) | (b << 8) | (flags & ColorCountFlags::IGNORE_ALPHA_VARIATIONS ? 255 : a); if(color_list.find(col) == color_list.end()) { color_list[col] = 0; } else { color_list[col]++; } p += bpp; } pix += rowPitch(); } return color_list.size(); }
//! Save the current window display to a file std::string Window::saveFrameBuffer(const std::string& filename) { auto surface = Surface::create(width_, height_, PixelFormat::PF::PIXELFORMAT_RGB24); int stride = surface->rowPitch(); std::vector<uint8_t> pixels; pixels.resize(stride * height_); if(display_->readPixels(0, 0, width_, height_, ReadFormat::RGB, AttrFormat::UNSIGNED_BYTE, pixels, stride)) { surface->writePixels(&pixels[0], height_ * stride); return surface->savePng(filename); } else { LOG_ERROR("Failed to save screenshot"); } return std::string(); }
void SurfaceSDL::writePixels(int bpp, uint32_t rmask, uint32_t gmask, uint32_t bmask, uint32_t amask, const void* pixels) { SDL_FreeSurface(surface_); ASSERT_LOG(pixels != nullptr, "nullptr value for pixels while creating surface."); surface_ = SDL_CreateRGBSurfaceFrom(const_cast<void*>(pixels), width(), height(), bpp, rowPitch(), rmask, gmask, bmask, amask); ASSERT_LOG(surface_ != nullptr, "Error creating surface: " << SDL_GetError()); setPixelFormat(PixelFormatPtr(new SDLPixelFormat(surface_->format->format))); }