[R-sig-Geo] Writing PNG files with rgdal

Roger Bivand Roger.Bivand at nhh.no
Mon Aug 17 14:14:12 CEST 2009


On Fri, 14 Aug 2009, Barry Rowlingson wrote:

> I'm wondering if there's an easy way to write PNG files from a matrix?
>
> I've got an NxM matrix of values, z, and I want to produce an NxM
> pixel PNG file. I have a function pfunc(.) that converts values to
> colours.
>
> So currently I do this:
>
>  library(rtiff)
>  library(rgdal)
>  z = matrix(runif(100),10,10)
>  pfunc=colorRamp(c("blue","yellow"))
>
>  tiffPath = "foo.tif"
>  pngPath = "foo.png"
>
> # get the rgb colours:
>  rgb = pfunc(t(z)[ncol(z):1,])
>
> # as a pixmapRGB
>  rgbpixmap = pixmapRGB(c(rgb[,1],rgb[,2],rgb[,3]),ncol(z),nrow(z))
>
> # save as a tiff (require(rtiff) package)
>  writeTiff(rgbpixmap,tiffPath)
>
> # now read in using rgdal and copy, since GDAL PNG driver doesn't have
> a 'create' call:
>  xp=GDAL.open(tiffPath)
>  xx=copyDataset(xp,driver="PNG")
>  saveDataset(xx,pngPath)
>  GDAL.close(xx)
>  GDAL.close(xp)
>
> # we don't need this:
>  file.remove(tiffPath)
>
> But it seems a bit kludgy. I know its not really a 'geo' question, but
> it seems that rgdal might have a better way to do this that I've not
> hit on yet. Any ideas (short of system("convert foo.tif foo.png")). Or
> is my solution as elegant as it can be?

rgdal 0.6-14 (now on sourceforge as source, on its way to CRAN) tries to 
detect whether the driver chosen by the user is one of those flagged as 
not supporting direct creation but supporting GDAL dataset copying, 
including the "PNG" driver. When writeGDAL() sees such a driver, it will 
now write to a temporary dataset (defualt driver "GTiff"), and copy from 
that to the desired file. Using:

GT <- GridTopology(c(0.5, 0.5), c(1, 1), c(10, 10))
set.seed(1)
SGDF <- SpatialGridDataFrame(GT, data=data.frame(z=runif(100)))
opar <- par(mfrow=c(2,2), mar=c(1,1,4,1))
image(SGDF, "z", col=colorRampPalette(c("blue", "yellow"))(20))
title(main="input values")
pfunc <- colorRamp(c("blue","yellow"))
RGB <- pfunc(SGDF$z)
SGDF$red <- RGB[,1]
SGDF$green <- RGB[,2]
SGDF$blue <- RGB[,3]
image(SGDF, red="red", green="green", blue="blue")
title(main="input RGB")
#
# to set up the data for export,
#
tf <- tempfile()
writeGDAL(SGDF[c("red", "green", "blue")], tf, type="Byte",
   drivername="PNG")
#
# will now write the PNG file. Reading in to check gives:
#
t1 <- readGDAL(tf)
image(t1, red=1, green=2, blue=3)
title(main="output PNG RGB")
par(opar)

I know that this is a "geo" answer, but getting the NxM matrix into an 
object that writeGDAL() can export shouldn't be too hard, by first 
defining the GridTopology object, then reshaping the matrix to suit. 
Looking at ?as.image.SpatialGridDataFrame and the code for this function 
may help, as well as image2Grid, to get the right incantation.

Roger

>
> Barry
>
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo at stat.math.ethz.ch
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

-- 
Roger Bivand
Economic Geography Section, Department of Economics, Norwegian School of
Economics and Business Administration, Helleveien 30, N-5045 Bergen,
Norway. voice: +47 55 95 93 55; fax +47 55 95 95 43
e-mail: Roger.Bivand at nhh.no



More information about the R-sig-Geo mailing list