【问题标题】:Pixel image in R from character arrayR中的像素图像来自字符数组
【发布时间】:2018-04-14 17:22:59
【问题描述】:

我通过将每个输入字符编码为图像中的某种颜色来生成基于像素的图像。例如,在输入txt <- "ABACDAAFFEDDADFAFAED" 中,我将“A”绘制为红色像素,将“B”绘制为紫色,将“C”绘制为蓝色,将“D”绘制为其他颜色。我为此使用了 R。这是我为此寻求帮助的答案 Generate pixel based image in R from character array

现在,我想更新它以处理我有一个角色连续出现 2 或 3 次并且我想给它一个不同的颜色的情况。例如txt <- "ABBACDAABBBEDDADCACABBDB",我想给 A-红色,AA栗色,AAA深红色。 B-绿色,BB-粉色,BBB-黄色, C-浅棕色、CC棕色、CCC深棕色等

我仍然想给每个字符 1 个像素,但是对于连续的 2 或 3 次外观,用不同的颜色为这 2 或 3 个像素着色。我无法在 R 中为它编写一个合理的解决方案。您的帮助将不胜感激。谢谢

【问题讨论】:

  • 请注意有很多边缘情况...例如如果地图包含'AAA'=yellow,并且在文本中是“XAAAAAAX”怎么办?只有前 3 个“A”的颜色应该不同?
  • 现在我想检查 2 或 3 个连续的。在“XAAAAAX”中,前 3 个 AAA 被着色为 AAA 颜色,接下来的 2 个被着色为 AA 颜色。

标签: r image bitmap raster


【解决方案1】:

我更改了功能以支持多个字符:

library(png)
library(tiff)
library(abind)

# function which plots the image
createImage <- function(txt,charToColorMap,destinationFile,format=c('png','tiff'),debugPlot=FALSE,unused.char='#'){

  if(nchar(unused.char) != 1){
    stop('unused.char must be a single character, and you should be sure that it will never be present in your text')
  }



  # 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))

  ######################################
  # MULTIPLE CHAR
  ######################################
  # check if color map contains multiple character names
  multiple <- names(charToColorMap)[nchar(names(charToColorMap)) > 1]
  multiple <- multiple[order(nchar(multiple),decreasing=TRUE)]
  txtForMultiple <- txt
  for(m in multiple){
    idxs <- gregexpr(pattern=m,text=txtForMultiple,fixed=TRUE)[[1]]
    charRanges <- unlist(lapply(idxs,seq,length.out=nchar(m)))
    colorIndexes[charRanges] <- which(names(charToColorMap)==m)[1]
    tmp <- strsplit(txtForMultiple,'')[[1]]
    tmp[charRanges] <- unused.char
    txtForMultiple <- paste(tmp,collapse='')
  }
  #########################################################

  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()
}

使用示例('AAA' 设置为白色):

charToColorMap <- c(A='red',B='blue',C='green',D='black',E='yellow',F='orange',AAA='white')

txt <- "ABACAAAFFEDDADFAFAED"
# please note that unused.char will be used to mark the characters of txt already analyzed
# during the multi-char handling, so it must not be present in txt
createImage(txt,charToColorMap,destinationFile = "test.png",debugPlot=TRUE,unused.char='#')

结果(放大 800 %):

【讨论】:

  • 谢谢@digEmAll。我会试一试,让你知道结果。谢谢。
  • 谢谢@digEmAll。工作完美。我现在可以在它之上做其他事情。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2013-02-18
  • 1970-01-01
  • 2016-09-13
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
相关资源
最近更新 更多