Unable to open png device in loop
Asked Answered
L

4

11

I've been fiddling around with a function in R, where, long story short, I have a for-loop, and at each step, I save a plot using png, then immediately readPNG so that I can extract RGB information. I then make a second plot, then readPNG this so I can compare the RGB of the two images. The problem is that I keep getting an error message about being unable to start the png() device, or to open the file for writing, after a number of loops (can be as few as a handful of loops, or as many as a few thousand).

Here is really simplified code, but it has the bare essentials, and generates the error message:

testfun<-function(beg,fini)
{
 library(png)
 setwd("D://mydirectory")
 for (i in beg:fini)
 {
  png("test.png",width=277,height=277) #candidate image
  par(mai=c(0,0,0,0))
  plot(1,type="n",ann=FALSE,xlim=c(0,255),ylim=c(0,255),
         xaxt="n",yaxt="n",frame.plot=F)
  polygon(x=c(10,60,60),y=c(10,10,60),col="red")
  graphics.off()

  image<-readPNG("test.png")
  #code where I get rgb values for original

  png("test2.png",width=277,height=277) #candidate image with diferent params
  par(mai=c(0,0,0,0))
  plot(1,type="n",ann=FALSE,xlim=c(0,255),ylim=c(0,255),
         xaxt="n",yaxt="n",frame.plot=F)
  polygon(x=c(10,60,60),y=c(10,10,60),col="blue")
  graphics.off()

  image<-readPNG("test2.png")
  #code where I get rgb values for second image, and compare
 }
}

And the error message:

Error in png("test.png", width = 277, height = 277) : 
  unable to start png() device
In addition: Warning messages:
1: In png("test.png", width = 277, height = 277) :
  Unable to open file 'test.png' for writing
2: In png("test.png", width = 277, height = 277) : opening device failed

Originally I had graphics.off() as dev.off() but then thought maybe the loop was so fast that turning off one device wasn't fast enough before needing to be open again and it was getting 'confused' somehow. I also tried using Sys.sleep(0.1) after each graphics.off, but that didn't help either. Am I missing something stupid and obvious, or is this just a device bug?

Linguist answered 30/12, 2012 at 19:22 Comment(8)
@your final question: there is no problem with dev.off, the code is executed in sequence. So however fast everything happens, first the device is killed and then a new device is openend.Psychogenic
Do you run this code in an interactive console, or using e.g. Rscript. And, does png work with an even more minimal code, e.g. : png("bla.png");plot(1:10);dev.off().Psychogenic
I send the function from Tinn-R, then just call it from Rgui. Png works fine on its own. But I just wrote a simple test where I had the code you suggested, in a loop. Ran it 10 times, no problem. Ran it 100 times, and got this: Error in png("test3.png") : unable to start png() device In addition: Warning messages: 1: In png("test3.png") : Unable to open file 'test3.png' for writing 2: In png("test3.png") : opening device failed (Sorry, I'm new to this and formatting a comment is still causing me hassle.)Linguist
Why do you need to the png device as a go-between? Not using png will solve your issue with it :).Psychogenic
Yeah, I was hoping to avoid png device, too. Short story long: My function is a genetic algorithm. I have original rgb values. I use my 'chromosome', plot the image. Save it, read it, get rgb, compare to original rgb values. I tried finding a way to extract rgb values from a plot without saving it first, but no luck. Only other option is to create a matrix the same size as my image, and use convex hulls and point.in.polygon to work out what the rgb of every single pixel would be after using mixcolor. Plotting and loading seemed the saner option..Linguist
Your code runs without error for me on Windows 7 with testfun(1,3000). Have you tried changing the name of the png with something like fname=paste("test",beg%%5,".png",sep=""); png(fname,width=277,height=277) #candidate image so that you are not writing then attempting to read immediately the same file?Teletypewriter
Interesting... I just tried that and it definitely lasted longer, but eventually ended up with an error. So now I'm just naming them by loop number, and it seems to be working (2500 loops through, no error so far, the most I've managed all day). Funnily enough, this is pretty much the way I had things in v1.0 of my code, but I changed it so I wouldn't end up with thousands of transient jpegs. So much for efficiency. Guess I'll just manually delete them every so often. Thanks, I'll upvote your answer once I have enough reputation to do so!Linguist
Conducting this adventure in comments is inappropriate. It is still not a reproducible question. Some stack limit or buffer size appears being exceeded. @Herc: Please make this reproducible.Munda
J
20

I've had the same problem occur, although not in a loop situation. In my case, it was because I was pointing the .png output to a directory that did not exist.

png('./tweets/graphics/unique words.png', width=12, height=8, units='in', res=300)

Once I created the directory, and referenced it correctly, the error went away and I got my .png image.

Jape answered 30/9, 2014 at 14:7 Comment(2)
You don't know how helpful you have been to me ! Spent hours trying to figure out the memory leak that other answers were mentioning and it was so simple... Thank you !Kinson
just set your wd with setwd() before you use png()Gargan
C
10

I had this issue while saving plots in a loop also. @Dino Fire gave me a hint, my loop-generated file name contained an illegal character...

Ensure that the file name is legal (look for slashes, ampersands, apostrophes etc.)

Clarendon answered 26/3, 2015 at 4:22 Comment(0)
B
0

For me, the reason readPNG() wasn't working was because I was running it from within a Rmd (RMarkdown) file.

As soon as I ran the code in the R console or a regular script, it worked immediately.

Broek answered 30/4, 2020 at 9:24 Comment(0)
C
0

if you are using RStudio (or R) set working directory to where pictures are (.jpg, .png) . It should be a directory, not just (C:/).

getwd()
setwd("C:/RCode/Deep Learning/Downloads/")
getwd()
Cobby answered 15/5, 2020 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.