Search code examples
rbitmapraster

Generate pixel based image in R from character array


I have a very long character array. I want to generate pixel based image (raster image) by encoding each character to certain color in image. For example, 'A' as red pixel, 'B' as purple, ... and 'Z' by some other color. I am using R for it.

Please help me how can i generate such pixel based image. I search and found raster and pixmap packages in R but i am new to R and not sure how to use them for my case. Any help is appreciated. Thanks


Solution

  • Here's a possible solution :

    library(png)
    library(tiff)
    library(abind)
    
    # function which plots the image
    createImage <- function(txt,charToColorMap,destinationFile,format=c('png','tiff'),debugPlot=FALSE){
    
      # helper function which finds all the divisors of a number
      divisors <- function(x){
        y <- seq_len(x)
        y[ x%%y == 0 ]
      }
    
      # split the string in charaters
      chars <- strsplit(txt,'')[[1]]
    
      # find the most "squared" rectangle that contains all the characters without padding
      d <- divisors(length(chars)) 
      y <- d[length(d) %/% 2]
      x <- length(chars) / y
    
      # create an array with 4 matrices (or planes) one for each RGBA channel
      RGBAmx <- col2rgb(charToColorMap,alpha=TRUE) / 255
      colorIndexes <- match(chars,names(charToColorMap))
    
      colorIndexesR <- matrix(RGBAmx['red',colorIndexes],nrow=y,ncol=x,byrow = TRUE)
      colorIndexesG <- matrix(RGBAmx['green',colorIndexes],nrow=y,ncol=x,byrow = TRUE)
      colorIndexesB <- matrix(RGBAmx['blue',colorIndexes],nrow=y,ncol=x,byrow = TRUE)
      colorIndexesA <- matrix(RGBAmx['alpha',colorIndexes],nrow=y,ncol=x,byrow = TRUE)
    
      planes <- abind(colorIndexesR,colorIndexesG,colorIndexesB,colorIndexesA,along=3)
    
      # write the PNG image
      if(format[1] == 'png'){
        writePNG(planes,destinationFile)
      }else if(format[1] == 'tiff'){
        writeTIFF(planes,destinationFile)
      }else{
        stop('usupported format')
      }
    
      # for debug purpose only we plot the image...
      if(debugPlot){
        mx <- matrix(colorIndexes,nrow=y,ncol=x,byrow = TRUE)
        image(z=t(mx[nrow(mx):1,]),col=charToColorMap)
      }
    
      invisible()
    }
    

    Usage :

    # arbitrary and incomplete LETTER -> COLOR map 
    charToColorMap <- c(A='red',B='blue',C='green',D='black',E='yellow',F='orange')
    
    txt <- "ABACDAAFFEDDADFAFAED"
    
    createImage(txt,charToColorMap,destinationFile = "test.png",debugPlot=TRUE)
    

    Resulting PNG image (800% zoom to see the pixels) :

    enter image description here