I am trying to use R to create a raster image from a matrix of data. However, I am getting some weird artifacts on the edge of my image.
The code I am using is as follows:
# From the example for rasterImage(). A 3 pixel by 5 pixel b/w checkerboard.
testImage <- as.raster(0:1, nrow=3, ncol=5)
testImage
[,1] [,2] [,3] [,4] [,5]
[1,] "#000000" "#FFFFFF" "#000000" "#FFFFFF" "#000000"
[2,] "#FFFFFF" "#000000" "#FFFFFF" "#000000" "#FFFFFF"
[3,] "#000000" "#FFFFFF" "#000000" "#FFFFFF" "#000000"
png('test.png', width=5, height=3, units='px')
# Just want the image, no margins, boarders or other fancy stuff.
par(mar = c(0,0,0,0) )
plot.new()
plotArea = par('fig')
rasterImage(testImage, plotArea[1], plotArea[3],
plotArea[2], plotArea[4], interpolate = FALSE )
dev.off()
This was executed in R 2.12.0 on OS X but I get the same output from R 2.11.0.
The output I am getting is the following (scaled from 5x3 to 150x90)
The pixels in the corners should be black which suggests some form of interpolation is occurring.
The output I am expecting to see is:
Any suggestions on why my code fails to faithfully produce a raster image from a matrix?
Intended Use
This is for a package I am working on so I would like to stay within the R base packages if possible so as not to introduce additional dependencies. The package implements a graphics device, so if anyone has a C level solution picks up from the info passed by GERaster()
in src/main/engine.c
and creates a PNG using only the R libraries, I would be willing to give that a shot as well.
Solutions for OS X
As pointed out by nico, the errant behavior is the result of antialiasing. The plot behaves as expected if png()
is told to use an output method for which antialiasing can be disabled, such as Cairo graphics:
png('test.png', width=5, height=3, units='px', type='cairo', antialias=NULL)
On OS X the default backend for png()
is Quartz, however png(..., type='quartz')
currently ignores directives set by quartz.options()
. Faithful output can be produced natively on OS X if the device is started by calling quartz()
directly instead of using png()
:
quartz(file='test.png', type='png', width=5, height=3, dpi=1, antialias=FALSE)
Windows Thinks Differently
The following output is generated on Windows:
According to an answer given by Paul Murrell (the benevolent dictator of R graphics devices) on the R-help mailing list:
This is a rounding (truncation) problem. Working on a fix.
This behavior on Windows should not be noticeable unless the raster image contains a very small number of pixels.