The R package png
offers the readPNG()
function which can read raster graphics (consisting of "pixel matrices") in PNG format into R. It returns either a single matrix with gray values in [0, 1] or three matrices with the RGB values in [0, 1].
For transforming between [0, 1] and {0, ..., 255} simply multiply or divide with 255 and round, if desired.
For transforming between RGB and grayscale you can use for example the desaturate()
function from the colorspace
package.
As an example, let's download the image you suggested:
download.file("http://www.greenmountaindiapers.com/skin/common_files/modules/Socialize/images/twitter.png",
destfile = "twitter.png")
Then we load the packages mentioned above:
library("png")
library("colorspace")
First, we read the PNG image into an array x
with dimension 28 x 28 x 4. Thus, the image has 28 x 28 pixels and four channels: red, green, blue and alpha (for semi-transparency).
x <- readPNG("twitter.png")
dim(x)
## [1] 28 28 4
Now we can transform this into various other formats: y
is a vector of hex character strings, specifying colors in R. yg
is the corresponding desaturated color (again as hex character) with grayscale only. yn
is the numeric amount of gray. All three objects are arranged into 28 x 28 matrices at the end
y <- rgb(x[,,1], x[,,2], x[,,3], alpha = x[,,4])
yg <- desaturate(y)
yn <- col2rgb(yg)[1, ]/255
dim(y) <- dim(yg) <- dim(yn) <- dim(x)[1:2]
I hope that at least one of these versions is what you are looking for. To check the pixel matrices I have written a small convenience function for visualization:
pixmatplot <- function (x, ...) {
d <- dim(x)
xcoord <- t(expand.grid(1:d[1], 1:d[2]))
xcoord <- t(xcoord/d)
par(mar = rep(1, 4))
plot(0, 0, type = "n", xlab = "", ylab = "", axes = FALSE,
xlim = c(0, 1), ylim = c(0, 1), ...)
rect(xcoord[, 2L] - 1/d[2L], 1 - (xcoord[, 1L] - 1/d[1L]),
xcoord[, 2L], 1 - xcoord[, 1L], col = x, border = "transparent")
}
For illustration let's look at:
pixmatplot(y)
pixmatplot(yg)

If you have a larger image and want to bring it to 28 x 28, I would average the gray values from the corresponding rows/columns and insert the results into a matrix of the desired dimension.
Final note: While it is certainly possible to do all this in R, it might be more convenient to use an image manipulation software instead. Depending on what you aim at, it might be easier to just use ImageMagick's mogrify
for example:
mogrify -resize 28 -type grayscale twitter.png