mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
Optionally tile screenshots at smaller dimensions than the window. #440
This commit is contained in:
parent
4cf133cc32
commit
92be9c57ed
@ -12,7 +12,7 @@ use map_model::{osm, ControlTrafficSignal, IntersectionID, NORMAL_LANE_THICKNESS
|
|||||||
use sim::Sim;
|
use sim::Sim;
|
||||||
use widgetry::{
|
use widgetry::{
|
||||||
lctrl, Btn, Cached, Checkbox, Choice, Color, DrawBaselayer, Drawable, EventCtx, GeomBatch,
|
lctrl, Btn, Cached, Checkbox, Choice, Color, DrawBaselayer, Drawable, EventCtx, GeomBatch,
|
||||||
GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, State, Text, UpdateType,
|
GfxCtx, HorizontalAlignment, Key, Line, Outcome, Panel, ScreenDims, State, Text, UpdateType,
|
||||||
VerticalAlignment, Widget,
|
VerticalAlignment, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ impl DebugMode {
|
|||||||
Checkbox::switch(ctx, "show route for all agents", Key::R, false),
|
Checkbox::switch(ctx, "show route for all agents", Key::R, false),
|
||||||
Widget::col(vec![
|
Widget::col(vec![
|
||||||
Btn::text_fg("unhide everything").build_def(ctx, lctrl(Key::H)),
|
Btn::text_fg("unhide everything").build_def(ctx, lctrl(Key::H)),
|
||||||
Btn::text_fg("screenshot everything").build_def(ctx, None),
|
Btn::text_fg("screenshot everything (for leaflet)").build_def(ctx, None),
|
||||||
Btn::text_fg("screenshot all of the everything").build_def(ctx, None),
|
Btn::text_fg("screenshot all of the everything").build_def(ctx, None),
|
||||||
Btn::text_fg("search OSM metadata").build_def(ctx, Key::Slash),
|
Btn::text_fg("search OSM metadata").build_def(ctx, Key::Slash),
|
||||||
Btn::text_fg("clear OSM search results").build_def(ctx, lctrl(Key::Slash)),
|
Btn::text_fg("clear OSM search results").build_def(ctx, lctrl(Key::Slash)),
|
||||||
@ -222,8 +222,8 @@ impl State<App> for DebugMode {
|
|||||||
self.search_results = None;
|
self.search_results = None;
|
||||||
self.reset_info(ctx);
|
self.reset_info(ctx);
|
||||||
}
|
}
|
||||||
"screenshot everything" => {
|
"screenshot everything (for leaflet)" => {
|
||||||
screenshot_everything(ctx, app);
|
screenshot_everything(ctx, app, ScreenDims::new(256.0, 256.0));
|
||||||
return Transition::Keep;
|
return Transition::Keep;
|
||||||
}
|
}
|
||||||
"screenshot all of the everything" => {
|
"screenshot all of the everything" => {
|
||||||
@ -784,7 +784,7 @@ impl State<App> for ScreenshotTest {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.screenshot_done = true;
|
self.screenshot_done = true;
|
||||||
screenshot_everything(ctx, app);
|
screenshot_everything(ctx, app, ctx.canvas.get_window_dims());
|
||||||
// TODO Sometimes this still gets stuck and needs a mouse wiggle for input event?
|
// TODO Sometimes this still gets stuck and needs a mouse wiggle for input event?
|
||||||
Transition::Keep
|
Transition::Keep
|
||||||
}
|
}
|
||||||
@ -792,10 +792,11 @@ impl State<App> for ScreenshotTest {
|
|||||||
fn draw(&self, _: &mut GfxCtx, _: &App) {}
|
fn draw(&self, _: &mut GfxCtx, _: &App) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn screenshot_everything(ctx: &mut EventCtx, app: &App) {
|
fn screenshot_everything(ctx: &mut EventCtx, app: &App, dims: ScreenDims) {
|
||||||
let name = app.primary.map.get_name();
|
let name = app.primary.map.get_name();
|
||||||
ctx.request_update(UpdateType::ScreenCaptureEverything {
|
ctx.request_update(UpdateType::ScreenCaptureEverything {
|
||||||
dir: format!("screenshots/{}/{}", name.city, name.map),
|
dir: format!("screenshots/{}/{}", name.city, name.map),
|
||||||
zoom: 3.0,
|
zoom: 3.0,
|
||||||
|
dims,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -363,9 +363,9 @@ impl PrerenderInnards {
|
|||||||
self.window_adapter.draw_finished(gfc_ctx_innards)
|
self.window_adapter.draw_finished(gfc_ctx_innards)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn screencap(&self, canvas: &Canvas, filename: String) -> anyhow::Result<()> {
|
pub(crate) fn screencap(&self, dims: ScreenDims, filename: String) -> anyhow::Result<()> {
|
||||||
let width = canvas.window_width as u32;
|
let width = dims.width as u32;
|
||||||
let height = canvas.window_height as u32;
|
let height = dims.height as u32;
|
||||||
|
|
||||||
let mut img = image::DynamicImage::new_rgba8(width, height);
|
let mut img = image::DynamicImage::new_rgba8(width, height);
|
||||||
let pixels = img.as_mut_rgba8().unwrap();
|
let pixels = img.as_mut_rgba8().unwrap();
|
||||||
|
@ -15,7 +15,11 @@ pub enum UpdateType {
|
|||||||
InputOnly,
|
InputOnly,
|
||||||
Game,
|
Game,
|
||||||
Pan,
|
Pan,
|
||||||
ScreenCaptureEverything { dir: String, zoom: f64 },
|
ScreenCaptureEverything {
|
||||||
|
dir: String,
|
||||||
|
zoom: f64,
|
||||||
|
dims: ScreenDims,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventCtx<'a> {
|
pub struct EventCtx<'a> {
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
//#![warn(missing_docs)]
|
//#![warn(missing_docs)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate anyhow;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ impl<A: SharedAppState> State<A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns naming hint. Logically consumes the number of uploads.
|
/// Returns naming hint. Logically consumes the number of uploads.
|
||||||
pub(crate) fn draw(&mut self, prerender: &Prerender, screenshot: bool) -> Option<String> {
|
pub(crate) fn draw(&mut self, prerender: &Prerender, screenshot: bool) -> Option<String> {
|
||||||
let mut g = GfxCtx::new(prerender, &self.canvas, &self.style, screenshot);
|
let mut g = GfxCtx::new(prerender, &self.canvas, &self.style, screenshot);
|
||||||
|
|
||||||
@ -358,8 +358,10 @@ pub fn run<
|
|||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
UpdateType::Pan => {}
|
UpdateType::Pan => {}
|
||||||
UpdateType::ScreenCaptureEverything { dir, zoom } => {
|
UpdateType::ScreenCaptureEverything { dir, zoom, dims } => {
|
||||||
if let Err(err) = screenshot_everything(&mut state, &dir, &prerender, zoom) {
|
if let Err(err) =
|
||||||
|
screenshot_everything(&mut state, &dir, &prerender, zoom, dims)
|
||||||
|
{
|
||||||
error!("Couldn't screenshot everything: {}", err);
|
error!("Couldn't screenshot everything: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
|
|
||||||
use crate::runner::State;
|
use crate::runner::State;
|
||||||
use crate::{Prerender, SharedAppState};
|
use crate::{Prerender, ScreenDims, SharedAppState};
|
||||||
|
|
||||||
/// Take a screenshot of the entire canvas, tiling it based on the window's width and height.
|
/// Take a screenshot of the entire canvas, tiling it based on the window's width and height.
|
||||||
pub(crate) fn screenshot_everything<A: SharedAppState>(
|
pub(crate) fn screenshot_everything<A: SharedAppState>(
|
||||||
@ -9,10 +9,19 @@ pub(crate) fn screenshot_everything<A: SharedAppState>(
|
|||||||
dir_path: &str,
|
dir_path: &str,
|
||||||
prerender: &Prerender,
|
prerender: &Prerender,
|
||||||
zoom: f64,
|
zoom: f64,
|
||||||
|
dims: ScreenDims,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
if dims.width > state.canvas.window_width || dims.height > state.canvas.window_height {
|
||||||
|
bail!(
|
||||||
|
"Can't take screenshots of dims {:?} when the window is only {:?}",
|
||||||
|
dims,
|
||||||
|
state.canvas.get_window_dims()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let mut timer = Timer::new("capturing screen");
|
let mut timer = Timer::new("capturing screen");
|
||||||
let num_tiles_x = (state.canvas.map_dims.0 * zoom / state.canvas.window_width).ceil() as usize;
|
let num_tiles_x = (state.canvas.map_dims.0 * zoom / dims.width).ceil() as usize;
|
||||||
let num_tiles_y = (state.canvas.map_dims.1 * zoom / state.canvas.window_height).ceil() as usize;
|
let num_tiles_y = (state.canvas.map_dims.1 * zoom / dims.height).ceil() as usize;
|
||||||
let orig_zoom = state.canvas.cam_zoom;
|
let orig_zoom = state.canvas.cam_zoom;
|
||||||
let orig_x = state.canvas.cam_x;
|
let orig_x = state.canvas.cam_x;
|
||||||
let orig_y = state.canvas.cam_y;
|
let orig_y = state.canvas.cam_y;
|
||||||
@ -26,8 +35,8 @@ pub(crate) fn screenshot_everything<A: SharedAppState>(
|
|||||||
for tile_y in 0..num_tiles_y {
|
for tile_y in 0..num_tiles_y {
|
||||||
for tile_x in 0..num_tiles_x {
|
for tile_x in 0..num_tiles_x {
|
||||||
timer.next();
|
timer.next();
|
||||||
state.canvas.cam_x = (tile_x as f64) * state.canvas.window_width;
|
state.canvas.cam_x = (tile_x as f64) * dims.width;
|
||||||
state.canvas.cam_y = (tile_y as f64) * state.canvas.window_height;
|
state.canvas.cam_y = (tile_y as f64) * dims.height;
|
||||||
|
|
||||||
let suffix = state.draw(prerender, true).unwrap_or_else(String::new);
|
let suffix = state.draw(prerender, true).unwrap_or_else(String::new);
|
||||||
let filename = format!(
|
let filename = format!(
|
||||||
@ -37,7 +46,7 @@ pub(crate) fn screenshot_everything<A: SharedAppState>(
|
|||||||
tile_y + 1,
|
tile_y + 1,
|
||||||
suffix
|
suffix
|
||||||
);
|
);
|
||||||
prerender.inner.screencap(&state.canvas, filename)?;
|
prerender.inner.screencap(dims, filename)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user