void save_screenshot(const char* filename) { log::msg("saving screenshot to %s...", filename); int32_t rmask, gmask, bmask, amask; rmask = 0x000000FF; gmask = 0x0000FF00; bmask = 0x00FF0000; amask = 0xFF000000; SDL_Surface *screen = SDL_CreateRGBSurface(SDL_SWSURFACE, window_size.x, window_size.y, 32, rmask, gmask, bmask, amask); size_t pxcount = screen->w * screen->h; uint32_t *pxdata = new uint32_t[pxcount]; glReadPixels(0, 0, window_size.x, window_size.y, GL_RGBA, GL_UNSIGNED_BYTE, pxdata); uint32_t *surface_pxls = (uint32_t *)screen->pixels; //we need to invert all rows, but leave column order the same. for (ssize_t row = 0; row < screen->h; row++) { ssize_t irow = screen->h - 1 - row; for (ssize_t col = 0; col < screen->w; col++) { uint32_t pxl = pxdata[irow * screen->w + col]; //TODO: store the alpha channels in the screenshot, is buggy at the moment.. surface_pxls[row * screen->w + col] = pxl | 0xFF000000; } } delete[] pxdata; IMG_SavePNG(screen, filename); SDL_FreeSurface(screen); }
int IMG_SaveFrameBuffer(const char* file, int compression) { const int w = preferences::actual_screen_width(); const int h = preferences::actual_screen_height(); #if SDL_VERSION_ATLEAST(2, 0, 0) graphics::surface s(SDL_CreateRGBSurface(0, w, h, 24, SURFACE_MASK_RGB)); #else graphics::surface s(SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 24, SURFACE_MASK_RGB)); #endif glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, s->pixels); unsigned char* pixels = (unsigned char*)s->pixels; for(int n = 0; n != h/2; ++n) { unsigned char* s1 = pixels + n*w*3; unsigned char* s2 = pixels + (h-n-1)*w*3; for(int m = 0; m != w*3; ++m) { std::swap(s1[m], s2[m]); } } const int result = IMG_SavePNG(file, s.get(), compression); if(result == -1) { fprintf(stderr, "FAILED TO SAVE SCREENSHOT\n"); return result; } fprintf(stderr, "SAVED SCREENSHOT TO %s.\n", file); return result; }
static EEL_xno img_SavePNG(EEL_vm *vm) { EEL_value *arg = vm->heap + vm->argv; int res; SDL_Surface *from; int comp = -1; /* Filename */ const char *fn = eel_v2s(arg); if(!fn) return EEL_XNEEDSTRING; /* Surface */ if(EEL_CLASS(arg + 1) != esdl_md.surface_cid) return EEL_XWRONGTYPE; from = o2ESDL_surface(arg[1].objref.v)->surface; /* Compression level */ if(vm->argc >= 3) { comp = eel_v2l(arg + 2); #if 0 if(comp < -1) return EEL_XLOWVALUE; if(comp > 9) return EEL_XHIGHVALUE; #endif } res = IMG_SavePNG(fn, from, comp); if(res) return EEL_XCANTWRITE; return 0; }
bool screenshot_( const std::string& filename ) noexcept { int err = 0; int w, h; SDL_Surface * sshot_surface; SDL_GetWindowSize( window, &w, &h ); sshot_surface = SDL_CreateRGBSurface( 0, w, h, ARGB_DEPTH, RMASK, GMASK, BMASK, AMASK ); if ( sshot_surface == nullptr ) return false; err = SDL_RenderReadPixels( renderer, nullptr, SDL_PIXELFORMAT_RGBA8888, sshot_surface->pixels, sshot_surface->pitch ); if ( err == -1 ) { // Cannot read the pixels from the renderer SDL_FreeSurface( sshot_surface ); return false; } err = IMG_SavePNG( sshot_surface, filename.c_str() ); SDL_FreeSurface( sshot_surface ); return err == 0; }
bool Surface::Save(const char *fn) const { #ifdef WITH_IMAGE return !surface || !fn || IMG_SavePNG(fn, surface, -1) ? false : true; #else return !surface || !fn || SDL_SaveBMP(surface, fn) ? false : true; #endif }
void Graphic::SaveImageBMP( std::string File) { // Save Image File = File + ".png"; /*SDL_RWops *file = SDL_RWFromFile( File.c_str(), "wb"); SDL_SaveBMP_RW( m_display->GetSurface(), file, 0); file->close(file);*/ if( IMG_SavePNG( m_display->GetSurface(), File.c_str())) { printf("Unable to save png -- %s\n", SDL_GetError()); } }
CAMLprim value sdlimagestub_savepng(value surf, value file) { CAMLparam2(surf, file); int ret = IMG_SavePNG( String_val(file), SDL_Surface_val(surf), IMG_COMPRESS_MAX); if(ret != 0) raise_failure(); CAMLreturn(Val_unit); }
void Texture2dData::store(const util::Path& file) const { log::log(MSG(info) << "Saving texture data to " << file); if (this->info.get_format() != pixel_format::rgba8) { throw Error(MSG(err) << "Storing 2D textures into files is unimplemented. PRs welcome :D"); } auto size = this->info.get_size(); // If an older SDL2 is used, we have to specify the format manually. #ifndef SDL_PIXELFORMAT_RGBA32 uint32_t rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else // little endian, like x86 rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf( SDL_CreateRGBSurfaceFrom( // const_cast is okay, because the surface doesn't modify data const_cast<void*>(static_cast<void const*>(this->data.data())), size.first, size.second, 32, this->info.get_row_size(), rmask, gmask, bmask, amask ), &SDL_FreeSurface ); #else std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf( SDL_CreateRGBSurfaceWithFormatFrom( // const_cast is okay, because the surface doesn't modify data const_cast<void*>(static_cast<void const*>(this->data.data())), size.first, size.second, 32, this->info.get_row_size(), SDL_PIXELFORMAT_RGBA32 ), &SDL_FreeSurface ); #endif // Call sdl_image for saving the screenshot to PNG std::string path = file.resolve_native_path_w(); IMG_SavePNG(surf.get(), path.c_str()); }
bool Surface::Save(const std::string & fn) const { int res = 0; #ifdef WITH_IMAGE #if SDL_VERSION_ATLEAST(2, 0, 0) res = IMG_SavePNG(surface, fn.c_str()); #else res = IMG_SavePNG(fn.c_str(), surface, -1); #endif #else res = SDL_SaveBMP(surface, fn.c_str()); #endif if(0 != res) { ERROR(SDL_GetError()); return false; } return true; }
bool save_png ( SDL_SURFACE::RawPtr buffer, const std::string& filename ) { if ( buffer == nullptr ) { NOM_LOG_ERR( NOM, "Video surface memory is not valid for saving output"); return false; } // Undocumented method for writing out a PNG file with SDL2_image if ( IMG_SavePNG ( buffer, filename.c_str() ) != 0 ) { NOM_LOG_ERR(NOM,SDL_GetError()); return false; } return true; }
bool Image::save_png ( const std::string& filename ) const { if ( this->valid() == false ) { NOM_LOG_ERR(NOM, "Image is not valid for saving output" ); return false; } // Undocumented method for writing out a PNG file with SDL2_image if ( IMG_SavePNG ( this->image(), filename.c_str() ) != 0 ) { NOM_LOG_ERR ( NOM, SDL_GetError() ); return false; } return true; }
void LectorTerreno::guardarMatrizEnPNG(string nombreArchivo){ Uint32* vectorPixeles = new Uint32[altoMatriz*anchoMatriz]; SDL_Surface* surNueva = IMG_Load(propiedadesPNG); for(unsigned y = 0; y < altoMatriz; y++) for(unsigned x = 0; x < anchoMatriz; x++){ vectorPixeles[x + (y*anchoMatriz)] = pixelToUint32(matrizTerreno[x][y], surNueva->format); } surNueva->h = altoMatriz; surNueva->w = anchoMatriz; surNueva->pitch = anchoMatriz*4; //pitch: tamaño en bits de cada linea (ancho x bytes por pixel) surNueva->pixels = vectorPixeles; IMG_SavePNG(surNueva, nombreArchivo.c_str()); delete[] vectorPixeles; }
void convert(const std::string &fileName) { if (fileName.rfind(".bmp") == std::string::npos) return; std::string out = fileName; size_t extPos = out.rfind('.'); if (extPos != std::string::npos) out = out.substr(0, extPos); out += ".png"; if (!g_dryrun) { SDL_Surface *surf = IMG_Load(fileName.c_str()); if (!surf) { std::cerr << std::string("Couldn't open ") << fileName << ": " << IMG_GetError() << std::endl; return; } uint8_t r, g, b, a; if (surf->format->palette) { SDL_GetRGBA(0, surf->format, &r, &g, &b, &a); std::cout << fileName << ": converting [" << uint16_t(r) << ", " << uint16_t(g) << ", " << uint16_t(b) << ", " << uint16_t(a) << "] to alpha" << std::endl; SDL_SetColorKey(surf, SDL_TRUE, 0); } else { std::cout << fileName << ": no palette" << std::endl; } SDL_Surface *other = SDL_ConvertSurfaceFormat(surf, SDL_PIXELFORMAT_RGBA8888, 0); SDL_FreeSurface(surf); if (!other) { std::cerr << "Couldn't convert " << fileName << ": " << SDL_GetError() << std::endl; return; } uint32_t *pixels = (uint32_t *)other->pixels; for (int i = 0; i < other->w * other->h; i++, pixels++) { SDL_GetRGBA(*pixels, other->format, &r, &g, &b, &a); float aFloat = a / 255; r *= aFloat; g *= aFloat; b *= aFloat; *pixels = SDL_MapRGBA(other->format, r, g, b, a); } if (IMG_SavePNG(other, out.c_str()) == -1) std::cerr << "Couldn't save " << out << ":" << IMG_GetError() << std::endl; SDL_FreeSurface(other); } else { std::cout << "converting " << fileName << " to " << out << std::endl; } }
int image_sdl_save(SDL_Surface *src, const char *path, enum img_fmt fmt) { int ret = -1; assert(src); assert(path); assert(strlen(path) > 0); assert(fmt != IMGFMT_NONE); if(fmt == IMGFMT_PNG) { ret = IMG_SavePNG(src, path); if(ret != 0) sg_log_err("Image save error, %s.", SDL_GetError()); } else sg_log_err("Only png is supportted for now."); return ret; }
void ScreenshotManager::save_screenshot() { std::string filename = this->gen_next_filename(); log::log(MSG(info) << "Saving screenshot to " << filename); int32_t rmask, gmask, bmask, amask; rmask = 0x000000FF; gmask = 0x0000FF00; bmask = 0x00FF0000; amask = 0xFF000000; SDL_Surface *screen = SDL_CreateRGBSurface( SDL_SWSURFACE, this->window_size.x, this->window_size.y, 32, rmask, gmask, bmask, amask); size_t pxcount = screen->w * screen->h; auto pxdata = std::make_unique<uint32_t[]>(pxcount); glReadPixels(0, 0, this->window_size.x, this->window_size.y, GL_RGBA, GL_UNSIGNED_BYTE, pxdata.get()); uint32_t *surface_pxls = (uint32_t *)screen->pixels; // we need to invert all pixel rows, but leave column order the same. for (ssize_t row = 0; row < screen->h; row++) { ssize_t irow = screen->h - 1 - row; for (ssize_t col = 0; col < screen->w; col++) { uint32_t pxl = pxdata[irow * screen->w + col]; // TODO: store the alpha channels in the screenshot, is buggy at the moment.. surface_pxls[row * screen->w + col] = pxl | 0xFF000000; } } // call sdl_image for saving the screenshot to png IMG_SavePNG(screen, filename.c_str()); SDL_FreeSurface(screen); }
void SDLFrontend::makeScreenshot (const std::string& filename) { assert(_renderer); SDL_Rect viewport; int bpp; Uint32 rmask, gmask, bmask, amask; SDL_RenderGetViewport(_renderer, &viewport); SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGBA8888, &bpp, &rmask, &gmask, &bmask, &amask); ScopedPtr<SDL_Surface> surface(SDL_CreateRGBSurface(0, viewport.w, viewport.h, bpp, rmask, gmask, bmask, amask)); if (!surface) return; if (SDL_RenderReadPixels(_renderer, nullptr, surface->format->format, surface->pixels, surface->pitch) < 0) return; const std::string fullFilename = FS.getAbsoluteWritePath() + filename + "-" + dateutil::getDateString() + ".png"; IMG_SavePNG(surface, fullFilename.c_str()); }
int write_image( const Image& image, const char *filename ) { if(std::string(filename).rfind(".png") == std::string::npos && std::string(filename).rfind(".PNG") == std::string::npos ) { printf("writing color image '%s'... failed, not a PNG image.\n", filename); return -1; } // flip de l'image : Y inverse entre GL et BMP Image flip= create_image(image.width, image.height, 4, make_color(0, 0, 0)); for(int y= 0; y < image.height; y++) for(int x= 0; x < image.width; x++) image_set_pixel(flip, x, image.height - y -1, image_pixel(image, x, y)); SDL_Surface *bmp= SDL_CreateRGBSurfaceFrom((void *) &flip.data.front(), image.width, image.height, 32, image.width * 4, #if 0 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #else 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #endif ); int code= IMG_SavePNG(bmp, filename); SDL_FreeSurface(bmp); release_image(flip); if(code < 0) printf("writing color image '%s'... failed\n%s\n", filename, SDL_GetError()); else printf("writing color image '%s'...\n", filename); return code; }
std::string WadImageCache::image_to_new_name(SDL_Surface *image, int32 *filesize) const { // create name boost::uuids::random_generator gen; boost::uuids::uuid u = gen(); std::string ustr = boost::uuids::to_string(u); FileSpecifier File; File.SetToImageCacheDir(); File.AddPart(ustr); FileSpecifier TempFile; TempFile.SetTempName(File); int ret; //#if defined(HAVE_PNG) && defined(HAVE_SDL_IMAGE) // ret = aoIMG_SavePNG(TempFile.GetPath(), image, IMG_COMPRESS_DEFAULT, NULL, 0); #ifdef HAVE_SDL_IMAGE ret = IMG_SavePNG(image, TempFile.GetPath()); #else ret = SDL_SaveBMP(image, TempFile.GetPath()); #endif if (ret == 0 && TempFile.Rename(File)) { if (filesize) { OpenedFile of; if (File.Open(of)) of.GetLength(*filesize); } return ustr; } if (filesize) *filesize = 0; return ""; }
void ProcessFile(char* fileName) { SDL_Surface* font = IMG_Load(fileName); if (font == NULL) { fprintf(stderr, "File not found or not correct image format.\n"); return; } if (font->format->BitsPerPixel != 32) { fprintf(stderr, "Pixel format is not 32bit.\n"); return; } Uint32* pix = (Uint32*)font->pixels; FRectangle* charRectangle; int currentCharIndex = 0; State = SEEKING; int i = 0, j = 0; int iters = 0; while (true) { if (i >= font->w) { return; } Uint32 px = pix[i + (j * font->w)]; switch (State) { case SEEKING: { if (j >= font->h) { i++; j = 0; } else { if (px != BLANK) { State = BEGIN_CHAR; } else { j++; } } break; } case BEGIN_CHAR: { charRectangle = new FRectangle(); charRectangle->Left = i; charRectangle->Top = j; charRectangle->Right = i; charRectangle->Bottom = j; State = PIXEL_FOUND; break; } case LINE_SEEK: { if (j >= font->h) { if (charRectangle->Right != i) { State = END_CHAR; } i++; j = 0; } else { if (px != BLANK) { State = PIXEL_FOUND; break; } j++; } break; } case PIXEL_FOUND: { if (j >= font->h) { State = LINE_SEEK; break; } if (px != BLANK) { if (j < charRectangle->Top) { charRectangle->Top = j; } if (j > charRectangle->Bottom) { charRectangle->Bottom = j; } if (i > charRectangle->Right) { charRectangle->Right = i; } } j++; break; } case END_CHAR: { SDL_Rect rec = FRectToSDL_Rect(*charRectangle); rec.w += 1; // Have to add +1 to w and h to compensate the comversion from my rec to sdl rec. TODO : Problem in FRect impl ? rec.h += 1; SDL_Surface* subSurf = SDL_CreateRGBSurface(0, rec.w, rec.h, 32, font->format->Rmask, font->format->Gmask, font->format->Bmask, font->format->Amask); SDL_BlitSurface(font, &rec, subSurf, NULL); char fileName[260]; if (islower(CharacterSet[currentCharIndex])) { sprintf(fileName, "letters/%c_.png", CharacterSet[currentCharIndex]); } else { sprintf(fileName, "letters/%c.png", CharacterSet[currentCharIndex]); } IMG_SavePNG(subSurf, fileName); currentCharIndex++; State = SEEKING; break; } } iters++; } }
void makeScreenShot () { char fname[256]; int ret; int align; int dlen, ishot, iline, w = window_width, h = window_height; unsigned char *pixels; SDL_Surface *surf; #if SDL_BYTEORDER == SDL_BIG_ENDIAN int rmask = 0x00ff0000; int gmask = 0x0000ff00; int bmask = 0x000000ff; #else int rmask = 0x000000ff; int gmask = 0x0000ff00; int bmask = 0x00ff0000; #endif int amask = 0x00000000; /* see if the screenshots directory exists */ safe_snprintf (fname, sizeof (fname), "%sscreenshots", configdir); ret = file_exists(fname); if(ret == 0) { if(MKDIR(fname) < 0) { LOG_ERROR ("Unable to create directory \"%s\"\n", fname); return; } } else if (ret == -1) { return; } dlen = strlen (fname); /* try to find a file name which isn't taken yet */ for (ishot = 1; ishot < 1000; ishot++) { safe_snprintf (fname+dlen, sizeof(fname)-dlen, "/elscreen%03d.png", ishot); ret = file_exists(fname); if(ret == 0) { break; } else if(ret == -1) { return; //we hit an error, it's already reported } } /* if all numbered file names have been taken, use the default */ if (ishot >= 1000) { LOG_TO_CONSOLE(c_red2, max_screenshots_warning_str); safe_snprintf (fname+dlen, sizeof(fname)-dlen, "/elscreen.png"); } LOG_TO_CONSOLE(c_green1, fname); /* read the pixels from the GL scene */ glGetIntegerv(GL_PACK_ALIGNMENT, &align); pixels = malloc(h * align * ((3 * w - 1) / align + 1)); glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels); /* Let SDL worry about creating a BMP from it: create a surface */ surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 24, rmask, gmask, bmask, amask); /* simply memcpy'ing the pixels results in an upside-down image, * so copy the lines in reverse order */ if (SDL_MUSTLOCK(surf)) SDL_LockSurface(surf); for (iline = 0; iline < h; iline++) memcpy ((char *)surf->pixels + surf->pitch*iline, pixels + surf->pitch*(h-iline-1), 3*w); if (SDL_MUSTLOCK(surf)) SDL_UnlockSurface(surf); //SDL_SaveBMP (surf, fname); IMG_SavePNG (surf, fname); free (pixels); SDL_FreeSurface (surf); }
// ========================================================================= int main(int argc, char** argv) { const char * usage = "Usage: lmu2png map.lmu chipset.png output.png\n"; if(argc < 4 || argc > 5) { std::cout<<usage; exit(EXIT_FAILURE); } const char* map_path = argv[1]; const char* chipset_path = argv[2]; const char* output_path = argv[3]; std::unique_ptr<RPG::Map> map = LMU_Reader::Load(map_path, ""); if (map.get() == NULL) { std::cerr<<LcfReader::GetError()<<std::endl; exit(EXIT_FAILURE); } SDL_Surface* chipset = IMG_Load(chipset_path); if (chipset == NULL) { std::cerr<<IMG_GetError()<<std::endl; exit(EXIT_FAILURE); } if (IMG_isBMP(SDL_RWFromFile(chipset_path, "rb"))) { // Set as color key the first color in the palette SDL_Color ckey = chipset->format->palette->colors[0]; SDL_SetColorKey(chipset, SDL_TRUE, SDL_MapRGB(chipset->format, ckey.r, ckey.g, ckey.b)); } SDL_Surface* output = SDL_CreateRGBSurface(0, map->width * 16, map->height * 16, 8, 0, 0, 0, 0); output->format->palette = chipset->format->palette; stChipset gen; gen.GenerateFromSurface(chipset); for (int y = 0; y < map->height; ++y) for (int x = 0; x < map->width; ++x) { gen.RenderTile(output, x*16, y*16, map->lower_layer[x+y*map->width], 0); gen.RenderTile(output, x*16, y*16, map->upper_layer[x+y*map->width], 0); } std::vector<RPG::Event>::iterator ev; for (ev = map->events.begin(); ev != map->events.end(); ++ev) { RPG::EventPage evp = ev->pages[0]; if (evp.character_name.empty()) gen.RenderTile(output, (ev->x)*16, (ev->y)*16, 0x2710 + evp.character_index, 0); } if(IMG_SavePNG(output, output_path) < 0) { std::cerr<<IMG_GetError()<<std::endl; exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
SDL_Surface *LoadSvg(char *fname, int hor_width, int hor_height, bool rot, bool cache) { SDL_Surface *res = NULL; bool skip = false; rsvg_init(); GError *error = NULL; RsvgHandle *rsvg_handle = rsvg_handle_new_from_file(fname, &error); if (!rsvg_handle) { log_error("can't load vector image `%s'", fname); LoadImgErrors++; skip = true; } if (!skip) { RsvgDimensionData dimensions; rsvg_handle_get_dimensions(rsvg_handle, &dimensions); int svg_width = dimensions.width; int svg_height = dimensions.height; float svg_koef = (float)svg_width / svg_height; float hor_koef = (float)hor_width / hor_height; float scale = (svg_koef > hor_koef ? (float)hor_height / svg_height : (float)hor_width / svg_width); int scaled_width = (int)(svg_width * scale); int scaled_height = (int)(svg_height * scale); int res_width = (rot ? hor_height : hor_width); int res_height = (rot ? hor_width : hor_height); bool loaded_from_cache = false; char *cached_file_full = NULL; char *file = NULL; char *file_hash = NULL; if (cache && can_cache) { int mod_time = 0; struct stat st; if (stat(fname, &st) == 0) mod_time = st.st_mtime; char *last_slash_ptr = strrchr(fname, '/'); file = (last_slash_ptr ? last_slash_ptr + 1 : fname); int max_overhead = 64; cached_file_full = (char*)malloc(strlen(cache_dir_full) + strlen("/") + strlen(file) + max_overhead + 1); file_hash = (char*)malloc(strlen(file) + max_overhead + 1); char *state = (rot ? "rotated" : "normal"); sprintf(cached_file_full, "%s/%s_%x-%dx%d-%s.png", cache_dir_full, file, mod_time, res_width, res_height, state); sprintf(file_hash, "%s_%x", file, mod_time); res = LoadImg(cached_file_full, false); if (res) { log_info("vector image `%s' was loaded from cache `%s'", fname, cached_file_full); loaded_from_cache = true; } } if (!loaded_from_cache) { int stride = res_width * 4; /* 4 bytes/pixel (32bpp RGBA) */ void *image = calloc(stride * res_height, 1); cairo_surface_t *cairo_surf = cairo_image_surface_create_for_data( image, CAIRO_FORMAT_ARGB32, res_width, res_height, stride); cairo_t *cr = cairo_create(cairo_surf); if (rot) { cairo_translate(cr, -(scaled_height-res_width)/2, res_height+(scaled_width-res_height)/2); cairo_scale(cr, scale, scale); cairo_rotate(cr, -M_PI/2); } else { cairo_translate(cr, -(scaled_width-res_width)/2, -(scaled_height-res_height)/2); cairo_scale(cr, scale, scale); } rsvg_handle_render_cairo(rsvg_handle, cr); cairo_surface_finish(cairo_surf); cairo_destroy(cr); uint32_t rmask = 0x00ff0000; uint32_t gmask = 0x0000ff00; uint32_t bmask = 0x000000ff; uint32_t amask = 0xff000000; //Notice that it matches CAIRO_FORMAT_ARGB32 res = SDL_CreateRGBSurfaceFrom( (void*) image, res_width, res_height, 32, //4 bytes/pixel = 32bpp stride, rmask, gmask, bmask, amask); } if (cache && can_cache) { if (!loaded_from_cache && res) { if (TouchDir(save_dir_full) && TouchDir(cache_dir_full)) { ClearCache(file, file_hash); if (IMG_SavePNG(res, cached_file_full) == 0) log_info("vector image `%s' was cached to `%s'", fname, cached_file_full); else log_error("can't cache vector image `%s' to `%s'", fname, cached_file_full); } else can_cache = false; } free(cached_file_full); free(file_hash); } } rsvg_term(); return res; }
void dump_screen(void) { // Find suitable file name FileSpecifier file; int i = 0; do { char name[256]; const char* suffix; #ifdef HAVE_PNG suffix = "png"; #else suffix = "bmp"; #endif if (get_game_state() == _game_in_progress) { sprintf(name, "%s_%04d.%s", to_alnum(static_world->level_name).c_str(), i, suffix); } else { sprintf(name, "Screenshot_%04d.%s", i, suffix); } file = screenshots_dir + name; i++; } while (file.Exists()); #ifdef HAVE_PNG // build some nice metadata std::vector<IMG_PNG_text> texts; std::map<std::string, std::string> metadata; metadata["Source"] = expand_app_variables("$appName$ $appVersion$ ($appPlatform$)"); time_t rawtime; time(&rawtime); char time_string[32]; strftime(time_string, 32,"%d %b %Y %H:%M:%S +0000", gmtime(&rawtime)); metadata["Creation Time"] = time_string; if (get_game_state() == _game_in_progress) { const float FLOAT_WORLD_ONE = float(WORLD_ONE); const float AngleConvert = 360/float(FULL_CIRCLE); metadata["Level"] = static_world->level_name; char map_file_name[256]; FileSpecifier fs = environment_preferences->map_file; fs.GetName(map_file_name); metadata["Map File"] = map_file_name; if (Scenario::instance()->GetName().size()) { metadata["Scenario"] = Scenario::instance()->GetName(); } metadata["Polygon"] = boost::lexical_cast<std::string>(world_view->origin_polygon_index); metadata["X"] = boost::lexical_cast<std::string>(world_view->origin.x / FLOAT_WORLD_ONE); metadata["Y"] = boost::lexical_cast<std::string>(world_view->origin.y / FLOAT_WORLD_ONE); metadata["Z"] = boost::lexical_cast<std::string>(world_view->origin.z / FLOAT_WORLD_ONE); metadata["Yaw"] = boost::lexical_cast<std::string>(world_view->yaw * AngleConvert); short pitch = world_view->pitch; if (pitch > HALF_CIRCLE) pitch -= HALF_CIRCLE; metadata["Pitch"] = boost::lexical_cast<std::string>(pitch * AngleConvert); } for (std::map<std::string, std::string>::const_iterator it = metadata.begin(); it != metadata.end(); ++it) { IMG_PNG_text text; text.key = const_cast<char*>(it->first.c_str()); text.value = const_cast<char*>(it->second.c_str()); texts.push_back(text); } IMG_PNG_text* textp = texts.size() ? &texts[0] : 0; #endif // Without OpenGL, dumping the screen is easy if (!MainScreenIsOpenGL()) { //#ifdef HAVE_PNG // aoIMG_SavePNG(file.GetPath(), MainScreenSurface(), IMG_COMPRESS_DEFAULT, textp, texts.size()); #ifdef HAVE_SDL_IMAGE IMG_SavePNG(MainScreenSurface(), file.GetPath()); #else SDL_SaveBMP(MainScreenSurface(), file.GetPath()); #endif return; } int video_w = MainScreenPixelWidth(); int video_h = MainScreenPixelHeight(); #ifdef HAVE_OPENGL // Otherwise, allocate temporary surface... SDL_Surface *t = SDL_CreateRGBSurface(SDL_SWSURFACE, video_w, video_h, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, 0); #else 0x00ff0000, 0x0000ff00, 0x000000ff, 0); #endif if (t == NULL) return; // ...and pixel buffer void *pixels = malloc(video_w * video_h * 3); if (pixels == NULL) { SDL_FreeSurface(t); return; } // Read OpenGL frame buffer glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, video_w, video_h, GL_RGB, GL_UNSIGNED_BYTE, pixels); glPixelStorei(GL_PACK_ALIGNMENT, 4); // return to default // Copy pixel buffer (which is upside-down) to surface for (int y = 0; y < video_h; y++) memcpy((uint8 *)t->pixels + t->pitch * y, (uint8 *)pixels + video_w * 3 * (video_h - y - 1), video_w * 3); free(pixels); // Save surface //#ifdef HAVE_PNG // aoIMG_SavePNG(file.GetPath(), t, IMG_COMPRESS_DEFAULT, textp, texts.size()); #ifdef HAVE_SDL_IMAGE IMG_SavePNG(t, file.GetPath()); #else SDL_SaveBMP(t, file.GetPath()); #endif SDL_FreeSurface(t); #endif }