Capture live window dataHow to join (merge) data frames (inner, outer, left, right)Drop data frame columns by nameHow to change the colour of raster data when combining raster layer and ggmapCan a capturing group be nested in a non-capturing groupMutate function only mutating first row, and then prints the same result for every subsequent rowHow to plot columns above and below data points in ggplot2For loop to extract data scattered across multiple columns in another R dataframeFilter for two-part response data from another dataframe and join two dataframesGenerate radar charts with ggplot2Inverting Dataframe in R
What is the maximum number of net attacks that one can make in a round?
How to safely destroy (a large quantity of) valid checks?
Is it legal for a bar bouncer to confiscate a fake ID
Why can I traceroute to this IP address, but not ping?
Active low-pass filters --- good to what frequencies?
Is it possible for a vehicle to be manufactured without a catalytic converter?
Are there any important biographies of nobodies?
Why does logistic function use e rather than 2?
Getting UPS Power from One Room to Another
Who enforces MPAA rating adherence?
Meaning of 'lose their grip on the groins of their followers'
Is it a bad idea to to run 24 tap and shock lands in standard
Has there been a multiethnic Star Trek character?
How to hide rifle during medieval town entrance inspection?
bmatrix: how to align elements' subscripts?
Artificer Creativity
How to handle (one's own) self-harm scars (on the arm), in a work environment?
How to use memset in c++?
Print lines between start & end pattern, but if end pattern does not exist, don't print
Why not invest in precious metals?
Generate basis elements of the Steenrod algebra
How to trick the reader into thinking they're following a redshirt instead of the protagonist?
If atoms are mostly vacuum, why are things so rigid around us?
Fixing obscure 8080 emulator bug?
Capture live window data
How to join (merge) data frames (inner, outer, left, right)Drop data frame columns by nameHow to change the colour of raster data when combining raster layer and ggmapCan a capturing group be nested in a non-capturing groupMutate function only mutating first row, and then prints the same result for every subsequent rowHow to plot columns above and below data points in ggplot2For loop to extract data scattered across multiple columns in another R dataframeFilter for two-part response data from another dataframe and join two dataframesGenerate radar charts with ggplot2Inverting Dataframe in R
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I would like to capture image data (like red, green, blue values for pixels) for a specified application window, and to do so periodically (like every 100 milliseconds) in R for the purpose of making a game bot. Ideally, I want the data to be directly read into a dataframe so it can immediately be used as input to a learning algorithm.
What are some suggested ways to do this? I am using R on Ubuntu linux.
r
add a comment |
I would like to capture image data (like red, green, blue values for pixels) for a specified application window, and to do so periodically (like every 100 milliseconds) in R for the purpose of making a game bot. Ideally, I want the data to be directly read into a dataframe so it can immediately be used as input to a learning algorithm.
What are some suggested ways to do this? I am using R on Ubuntu linux.
r
Is it correct to assume your data is stored in the form of say an image on your computer? And this image may change, say every 100 milliseconds, Or do you have lots of different images? Or is it not stored as an image, but rather an excel filed? Or.... you see where this is going.....
– Hector Haffenden
Mar 24 at 19:19
The data should be in the form of an image. I don't intend to 'store' anything as in save it to a file to disk, but if this is inevitable then I would prefer your first scenario where the same image changes rather than storing many images.
– silent_spec
Mar 24 at 21:26
Maybe there is another way, one way would be to store this image, read it into r, do what analysis u want, then overwrite the image etc... Although, this doesn't sound fast enough for your application. If you can store the images as a data frame, this will increase speed, but again unsure of specifics in your case.
– Hector Haffenden
Mar 24 at 21:30
add a comment |
I would like to capture image data (like red, green, blue values for pixels) for a specified application window, and to do so periodically (like every 100 milliseconds) in R for the purpose of making a game bot. Ideally, I want the data to be directly read into a dataframe so it can immediately be used as input to a learning algorithm.
What are some suggested ways to do this? I am using R on Ubuntu linux.
r
I would like to capture image data (like red, green, blue values for pixels) for a specified application window, and to do so periodically (like every 100 milliseconds) in R for the purpose of making a game bot. Ideally, I want the data to be directly read into a dataframe so it can immediately be used as input to a learning algorithm.
What are some suggested ways to do this? I am using R on Ubuntu linux.
r
r
edited Mar 25 at 7:18
Hector Haffenden
916416
916416
asked Mar 24 at 19:01
silent_specsilent_spec
377
377
Is it correct to assume your data is stored in the form of say an image on your computer? And this image may change, say every 100 milliseconds, Or do you have lots of different images? Or is it not stored as an image, but rather an excel filed? Or.... you see where this is going.....
– Hector Haffenden
Mar 24 at 19:19
The data should be in the form of an image. I don't intend to 'store' anything as in save it to a file to disk, but if this is inevitable then I would prefer your first scenario where the same image changes rather than storing many images.
– silent_spec
Mar 24 at 21:26
Maybe there is another way, one way would be to store this image, read it into r, do what analysis u want, then overwrite the image etc... Although, this doesn't sound fast enough for your application. If you can store the images as a data frame, this will increase speed, but again unsure of specifics in your case.
– Hector Haffenden
Mar 24 at 21:30
add a comment |
Is it correct to assume your data is stored in the form of say an image on your computer? And this image may change, say every 100 milliseconds, Or do you have lots of different images? Or is it not stored as an image, but rather an excel filed? Or.... you see where this is going.....
– Hector Haffenden
Mar 24 at 19:19
The data should be in the form of an image. I don't intend to 'store' anything as in save it to a file to disk, but if this is inevitable then I would prefer your first scenario where the same image changes rather than storing many images.
– silent_spec
Mar 24 at 21:26
Maybe there is another way, one way would be to store this image, read it into r, do what analysis u want, then overwrite the image etc... Although, this doesn't sound fast enough for your application. If you can store the images as a data frame, this will increase speed, but again unsure of specifics in your case.
– Hector Haffenden
Mar 24 at 21:30
Is it correct to assume your data is stored in the form of say an image on your computer? And this image may change, say every 100 milliseconds, Or do you have lots of different images? Or is it not stored as an image, but rather an excel filed? Or.... you see where this is going.....
– Hector Haffenden
Mar 24 at 19:19
Is it correct to assume your data is stored in the form of say an image on your computer? And this image may change, say every 100 milliseconds, Or do you have lots of different images? Or is it not stored as an image, but rather an excel filed? Or.... you see where this is going.....
– Hector Haffenden
Mar 24 at 19:19
The data should be in the form of an image. I don't intend to 'store' anything as in save it to a file to disk, but if this is inevitable then I would prefer your first scenario where the same image changes rather than storing many images.
– silent_spec
Mar 24 at 21:26
The data should be in the form of an image. I don't intend to 'store' anything as in save it to a file to disk, but if this is inevitable then I would prefer your first scenario where the same image changes rather than storing many images.
– silent_spec
Mar 24 at 21:26
Maybe there is another way, one way would be to store this image, read it into r, do what analysis u want, then overwrite the image etc... Although, this doesn't sound fast enough for your application. If you can store the images as a data frame, this will increase speed, but again unsure of specifics in your case.
– Hector Haffenden
Mar 24 at 21:30
Maybe there is another way, one way would be to store this image, read it into r, do what analysis u want, then overwrite the image etc... Although, this doesn't sound fast enough for your application. If you can store the images as a data frame, this will increase speed, but again unsure of specifics in your case.
– Hector Haffenden
Mar 24 at 21:30
add a comment |
1 Answer
1
active
oldest
votes
First you would need to have a way to capture a screenshot and save it to a (temporary) file. The best way I found (using this and this) is using ImageMagick.
If you have ImageMagick installed, you can use the following R function/skript to capture the screen, load the data and plot the data in R (you might want to tweak the arguments based on your desired resolution etc.).
Lastly, if you want to do more with the image, I recommend the imager
package.
Skript and load the image into R
library(imager) # for loading and plotting of the PNG file
library(glue) # for string parsing
capture_screen <- function(file = "screenshot.png")
system(glue("import -window root -resize 2560x1440 -delay 200 file"))
invisible(file)
file <- capture_screen()
shot <- load.image(file)
shot
#> Image. Width: 2560 pix Height: 1440 pix Depth: 1 Colour channels: 3
shot[1:10, 1:10, ]
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [2,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [3,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [4,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [5,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [6,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [7,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [8,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [9,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [10,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [2,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [3,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [4,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [5,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [6,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [7,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [8,] 0.3221790 0.3186389 0.3138781 0.3112840
#> [9,] 0.3221790 0.3186389 0.3138018 0.3109636
#> [10,] 0.3221942 0.3185931 0.3136797 0.3123674
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [2,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [3,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [4,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [5,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [6,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [7,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [8,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [9,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [10,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [2,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [3,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [4,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [5,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [6,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [7,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [8,] 0.3121691 0.3096513 0.3048905 0.3013352
#> [9,] 0.3121691 0.3096513 0.3048600 0.3008164
#> [10,] 0.3121996 0.3095750 0.3045701 0.3070420
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [2,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [3,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [4,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [5,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [6,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [7,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [8,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [9,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [10,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2829328
#> [,8] [,9] [,10]
#> [1,] 0.2799268 0.2769360 0.2740215
#> [2,] 0.2799268 0.2769360 0.2740215
#> [3,] 0.2799268 0.2769360 0.2740215
#> [4,] 0.2799268 0.2769360 0.2740215
#> [5,] 0.2799268 0.2769360 0.2740215
#> [6,] 0.2799268 0.2769360 0.2740215
#> [7,] 0.2799268 0.2769360 0.2740215
#> [8,] 0.2799268 0.2769360 0.2740215
#> [9,] 0.2799268 0.2769207 0.2734569
#> [10,] 0.2796063 0.2775616 0.2841840
Plot the image
plot(shot)
# render only a subset
imsub(shot, y <= 200, y >= 100, x <= 500, x >= 200) %>% plot()
Created on 2019-03-25 by the reprex package (v0.2.1)
Edit
If you only want to load the data without the screenshot.png
file, you can also do
capture_screen2 <- function(xmin = 0, xmax = Inf, ymin = 0, ymax = Inf)
tmp <- tempfile(fileext = ".png")
system(glue("import -window root -resize 2560x1440 -delay 200 tmp"))
img <- load.image(tmp)
a <- try(unlink(tmp))
imsub(img, x >= xmin, x <= xmax, y >= ymin, y <= ymax)
shot <- capture_screen2()
Edit 2: Speed Issues
I did some benchmarking of the speed of the code, the fastest option is to use scrot
(sudo apt install scrot
on Ubuntu) in combination with the png
package:
system(glue::glue("scrot --silent screenshot.png"))
img <- png::readPNG("screenshot.png")
dim(img)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55327407%2fcapture-live-window-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
First you would need to have a way to capture a screenshot and save it to a (temporary) file. The best way I found (using this and this) is using ImageMagick.
If you have ImageMagick installed, you can use the following R function/skript to capture the screen, load the data and plot the data in R (you might want to tweak the arguments based on your desired resolution etc.).
Lastly, if you want to do more with the image, I recommend the imager
package.
Skript and load the image into R
library(imager) # for loading and plotting of the PNG file
library(glue) # for string parsing
capture_screen <- function(file = "screenshot.png")
system(glue("import -window root -resize 2560x1440 -delay 200 file"))
invisible(file)
file <- capture_screen()
shot <- load.image(file)
shot
#> Image. Width: 2560 pix Height: 1440 pix Depth: 1 Colour channels: 3
shot[1:10, 1:10, ]
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [2,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [3,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [4,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [5,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [6,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [7,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [8,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [9,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [10,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [2,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [3,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [4,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [5,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [6,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [7,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [8,] 0.3221790 0.3186389 0.3138781 0.3112840
#> [9,] 0.3221790 0.3186389 0.3138018 0.3109636
#> [10,] 0.3221942 0.3185931 0.3136797 0.3123674
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [2,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [3,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [4,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [5,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [6,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [7,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [8,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [9,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [10,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [2,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [3,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [4,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [5,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [6,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [7,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [8,] 0.3121691 0.3096513 0.3048905 0.3013352
#> [9,] 0.3121691 0.3096513 0.3048600 0.3008164
#> [10,] 0.3121996 0.3095750 0.3045701 0.3070420
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [2,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [3,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [4,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [5,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [6,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [7,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [8,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [9,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [10,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2829328
#> [,8] [,9] [,10]
#> [1,] 0.2799268 0.2769360 0.2740215
#> [2,] 0.2799268 0.2769360 0.2740215
#> [3,] 0.2799268 0.2769360 0.2740215
#> [4,] 0.2799268 0.2769360 0.2740215
#> [5,] 0.2799268 0.2769360 0.2740215
#> [6,] 0.2799268 0.2769360 0.2740215
#> [7,] 0.2799268 0.2769360 0.2740215
#> [8,] 0.2799268 0.2769360 0.2740215
#> [9,] 0.2799268 0.2769207 0.2734569
#> [10,] 0.2796063 0.2775616 0.2841840
Plot the image
plot(shot)
# render only a subset
imsub(shot, y <= 200, y >= 100, x <= 500, x >= 200) %>% plot()
Created on 2019-03-25 by the reprex package (v0.2.1)
Edit
If you only want to load the data without the screenshot.png
file, you can also do
capture_screen2 <- function(xmin = 0, xmax = Inf, ymin = 0, ymax = Inf)
tmp <- tempfile(fileext = ".png")
system(glue("import -window root -resize 2560x1440 -delay 200 tmp"))
img <- load.image(tmp)
a <- try(unlink(tmp))
imsub(img, x >= xmin, x <= xmax, y >= ymin, y <= ymax)
shot <- capture_screen2()
Edit 2: Speed Issues
I did some benchmarking of the speed of the code, the fastest option is to use scrot
(sudo apt install scrot
on Ubuntu) in combination with the png
package:
system(glue::glue("scrot --silent screenshot.png"))
img <- png::readPNG("screenshot.png")
dim(img)
add a comment |
First you would need to have a way to capture a screenshot and save it to a (temporary) file. The best way I found (using this and this) is using ImageMagick.
If you have ImageMagick installed, you can use the following R function/skript to capture the screen, load the data and plot the data in R (you might want to tweak the arguments based on your desired resolution etc.).
Lastly, if you want to do more with the image, I recommend the imager
package.
Skript and load the image into R
library(imager) # for loading and plotting of the PNG file
library(glue) # for string parsing
capture_screen <- function(file = "screenshot.png")
system(glue("import -window root -resize 2560x1440 -delay 200 file"))
invisible(file)
file <- capture_screen()
shot <- load.image(file)
shot
#> Image. Width: 2560 pix Height: 1440 pix Depth: 1 Colour channels: 3
shot[1:10, 1:10, ]
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [2,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [3,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [4,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [5,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [6,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [7,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [8,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [9,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [10,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [2,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [3,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [4,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [5,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [6,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [7,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [8,] 0.3221790 0.3186389 0.3138781 0.3112840
#> [9,] 0.3221790 0.3186389 0.3138018 0.3109636
#> [10,] 0.3221942 0.3185931 0.3136797 0.3123674
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [2,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [3,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [4,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [5,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [6,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [7,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [8,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [9,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [10,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [2,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [3,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [4,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [5,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [6,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [7,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [8,] 0.3121691 0.3096513 0.3048905 0.3013352
#> [9,] 0.3121691 0.3096513 0.3048600 0.3008164
#> [10,] 0.3121996 0.3095750 0.3045701 0.3070420
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [2,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [3,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [4,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [5,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [6,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [7,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [8,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [9,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [10,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2829328
#> [,8] [,9] [,10]
#> [1,] 0.2799268 0.2769360 0.2740215
#> [2,] 0.2799268 0.2769360 0.2740215
#> [3,] 0.2799268 0.2769360 0.2740215
#> [4,] 0.2799268 0.2769360 0.2740215
#> [5,] 0.2799268 0.2769360 0.2740215
#> [6,] 0.2799268 0.2769360 0.2740215
#> [7,] 0.2799268 0.2769360 0.2740215
#> [8,] 0.2799268 0.2769360 0.2740215
#> [9,] 0.2799268 0.2769207 0.2734569
#> [10,] 0.2796063 0.2775616 0.2841840
Plot the image
plot(shot)
# render only a subset
imsub(shot, y <= 200, y >= 100, x <= 500, x >= 200) %>% plot()
Created on 2019-03-25 by the reprex package (v0.2.1)
Edit
If you only want to load the data without the screenshot.png
file, you can also do
capture_screen2 <- function(xmin = 0, xmax = Inf, ymin = 0, ymax = Inf)
tmp <- tempfile(fileext = ".png")
system(glue("import -window root -resize 2560x1440 -delay 200 tmp"))
img <- load.image(tmp)
a <- try(unlink(tmp))
imsub(img, x >= xmin, x <= xmax, y >= ymin, y <= ymax)
shot <- capture_screen2()
Edit 2: Speed Issues
I did some benchmarking of the speed of the code, the fastest option is to use scrot
(sudo apt install scrot
on Ubuntu) in combination with the png
package:
system(glue::glue("scrot --silent screenshot.png"))
img <- png::readPNG("screenshot.png")
dim(img)
add a comment |
First you would need to have a way to capture a screenshot and save it to a (temporary) file. The best way I found (using this and this) is using ImageMagick.
If you have ImageMagick installed, you can use the following R function/skript to capture the screen, load the data and plot the data in R (you might want to tweak the arguments based on your desired resolution etc.).
Lastly, if you want to do more with the image, I recommend the imager
package.
Skript and load the image into R
library(imager) # for loading and plotting of the PNG file
library(glue) # for string parsing
capture_screen <- function(file = "screenshot.png")
system(glue("import -window root -resize 2560x1440 -delay 200 file"))
invisible(file)
file <- capture_screen()
shot <- load.image(file)
shot
#> Image. Width: 2560 pix Height: 1440 pix Depth: 1 Colour channels: 3
shot[1:10, 1:10, ]
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [2,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [3,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [4,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [5,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [6,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [7,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [8,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [9,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [10,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [2,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [3,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [4,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [5,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [6,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [7,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [8,] 0.3221790 0.3186389 0.3138781 0.3112840
#> [9,] 0.3221790 0.3186389 0.3138018 0.3109636
#> [10,] 0.3221942 0.3185931 0.3136797 0.3123674
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [2,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [3,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [4,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [5,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [6,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [7,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [8,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [9,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [10,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [2,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [3,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [4,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [5,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [6,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [7,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [8,] 0.3121691 0.3096513 0.3048905 0.3013352
#> [9,] 0.3121691 0.3096513 0.3048600 0.3008164
#> [10,] 0.3121996 0.3095750 0.3045701 0.3070420
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [2,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [3,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [4,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [5,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [6,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [7,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [8,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [9,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [10,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2829328
#> [,8] [,9] [,10]
#> [1,] 0.2799268 0.2769360 0.2740215
#> [2,] 0.2799268 0.2769360 0.2740215
#> [3,] 0.2799268 0.2769360 0.2740215
#> [4,] 0.2799268 0.2769360 0.2740215
#> [5,] 0.2799268 0.2769360 0.2740215
#> [6,] 0.2799268 0.2769360 0.2740215
#> [7,] 0.2799268 0.2769360 0.2740215
#> [8,] 0.2799268 0.2769360 0.2740215
#> [9,] 0.2799268 0.2769207 0.2734569
#> [10,] 0.2796063 0.2775616 0.2841840
Plot the image
plot(shot)
# render only a subset
imsub(shot, y <= 200, y >= 100, x <= 500, x >= 200) %>% plot()
Created on 2019-03-25 by the reprex package (v0.2.1)
Edit
If you only want to load the data without the screenshot.png
file, you can also do
capture_screen2 <- function(xmin = 0, xmax = Inf, ymin = 0, ymax = Inf)
tmp <- tempfile(fileext = ".png")
system(glue("import -window root -resize 2560x1440 -delay 200 tmp"))
img <- load.image(tmp)
a <- try(unlink(tmp))
imsub(img, x >= xmin, x <= xmax, y >= ymin, y <= ymax)
shot <- capture_screen2()
Edit 2: Speed Issues
I did some benchmarking of the speed of the code, the fastest option is to use scrot
(sudo apt install scrot
on Ubuntu) in combination with the png
package:
system(glue::glue("scrot --silent screenshot.png"))
img <- png::readPNG("screenshot.png")
dim(img)
First you would need to have a way to capture a screenshot and save it to a (temporary) file. The best way I found (using this and this) is using ImageMagick.
If you have ImageMagick installed, you can use the following R function/skript to capture the screen, load the data and plot the data in R (you might want to tweak the arguments based on your desired resolution etc.).
Lastly, if you want to do more with the image, I recommend the imager
package.
Skript and load the image into R
library(imager) # for loading and plotting of the PNG file
library(glue) # for string parsing
capture_screen <- function(file = "screenshot.png")
system(glue("import -window root -resize 2560x1440 -delay 200 file"))
invisible(file)
file <- capture_screen()
shot <- load.image(file)
shot
#> Image. Width: 2560 pix Height: 1440 pix Depth: 1 Colour channels: 3
shot[1:10, 1:10, ]
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [2,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [3,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [4,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [5,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [6,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [7,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [8,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [9,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [10,] 0.3440452 0.3385519 0.3357443 0.3331807 0.3284199 0.3248798
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [2,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [3,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [4,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [5,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [6,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [7,] 0.3221790 0.3186389 0.3138781 0.3112993
#> [8,] 0.3221790 0.3186389 0.3138781 0.3112840
#> [9,] 0.3221790 0.3186389 0.3138018 0.3109636
#> [10,] 0.3221942 0.3185931 0.3136797 0.3123674
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [2,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [3,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [4,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [5,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [6,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [7,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [8,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [9,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [10,] 0.3319905 0.3292439 0.3244831 0.3209583 0.3181506 0.3152209
#> [,7] [,8] [,9] [,10]
#> [1,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [2,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [3,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [4,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [5,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [6,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [7,] 0.3121691 0.3096513 0.3048905 0.3013504
#> [8,] 0.3121691 0.3096513 0.3048905 0.3013352
#> [9,] 0.3121691 0.3096513 0.3048600 0.3008164
#> [10,] 0.3121996 0.3095750 0.3045701 0.3070420
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [2,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [3,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [4,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [5,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [6,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [7,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [8,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [9,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2828412
#> [10,] 0.300679 0.2975357 0.2945907 0.2916915 0.2887007 0.2857862 0.2829328
#> [,8] [,9] [,10]
#> [1,] 0.2799268 0.2769360 0.2740215
#> [2,] 0.2799268 0.2769360 0.2740215
#> [3,] 0.2799268 0.2769360 0.2740215
#> [4,] 0.2799268 0.2769360 0.2740215
#> [5,] 0.2799268 0.2769360 0.2740215
#> [6,] 0.2799268 0.2769360 0.2740215
#> [7,] 0.2799268 0.2769360 0.2740215
#> [8,] 0.2799268 0.2769360 0.2740215
#> [9,] 0.2799268 0.2769207 0.2734569
#> [10,] 0.2796063 0.2775616 0.2841840
Plot the image
plot(shot)
# render only a subset
imsub(shot, y <= 200, y >= 100, x <= 500, x >= 200) %>% plot()
Created on 2019-03-25 by the reprex package (v0.2.1)
Edit
If you only want to load the data without the screenshot.png
file, you can also do
capture_screen2 <- function(xmin = 0, xmax = Inf, ymin = 0, ymax = Inf)
tmp <- tempfile(fileext = ".png")
system(glue("import -window root -resize 2560x1440 -delay 200 tmp"))
img <- load.image(tmp)
a <- try(unlink(tmp))
imsub(img, x >= xmin, x <= xmax, y >= ymin, y <= ymax)
shot <- capture_screen2()
Edit 2: Speed Issues
I did some benchmarking of the speed of the code, the fastest option is to use scrot
(sudo apt install scrot
on Ubuntu) in combination with the png
package:
system(glue::glue("scrot --silent screenshot.png"))
img <- png::readPNG("screenshot.png")
dim(img)
edited Mar 26 at 8:49
answered Mar 25 at 7:45
DavidDavid
3,4862537
3,4862537
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55327407%2fcapture-live-window-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Is it correct to assume your data is stored in the form of say an image on your computer? And this image may change, say every 100 milliseconds, Or do you have lots of different images? Or is it not stored as an image, but rather an excel filed? Or.... you see where this is going.....
– Hector Haffenden
Mar 24 at 19:19
The data should be in the form of an image. I don't intend to 'store' anything as in save it to a file to disk, but if this is inevitable then I would prefer your first scenario where the same image changes rather than storing many images.
– silent_spec
Mar 24 at 21:26
Maybe there is another way, one way would be to store this image, read it into r, do what analysis u want, then overwrite the image etc... Although, this doesn't sound fast enough for your application. If you can store the images as a data frame, this will increase speed, but again unsure of specifics in your case.
– Hector Haffenden
Mar 24 at 21:30