Skip to content

Large continuous color palette {was `about image and rgb'}

2 messages · Martin Maechler, Henrik Bengtsson

#
[Answer re-diverted to R-help !]
Olivier> Hi Martin,

    Olivier> Thanks for your help.  I try explain more precisely my problem.
    Olivier> First, i have a matrix which values are between 0 and 2^16-1.

    Olivier> So, this what i would like to do.

    Olivier> 1 Is it possible to convert this matrix into a TIFF format file.

yes:
1) Use the `pixmap' package to produce a "pnm" (portable anymap format)
   file
2) Use a conversion tool to translate this to tiff.
   There are many of those I think.
   On Unix/Linux, there's the ImageMagick software package, with
   a "convert" program.

   On my Linux (redhat), there's also  pnmtotiff with help page {excerpts!}

     >>   NAME
     >> 	 pnmtotiff - convert a a portable anymap into a TIFF file
     >> 
     >>   SYNOPSIS
     >> 	 pnmtotiff  [-none|-packbits|  -lzw|-g3|-g4]  [-2d] [-fill]
     >> 	 [-predictor n] [-msb2lsb|-lsb2msb] [-rowsperstrip  n]  [-X
     >> 	 res| -Y res| -R res] [pnmfile]
     >> 
     >>   DESCRIPTION
     >> 	 Reads a portable anymap as input.  Produces a TIFF file as
     >> 	 output.
     >> 
     >>    ............
     >> 
     >>   NOTES
     >> 	 There  are  myriad variations of the TIFF format, and this
     >> 	 program generates only a few of them.  pnmtotiff creates a
     >> 	 grayscale  TIFF file if its input is a PBM (monochrome) or
     >> 	 PGM (grayscale) file.  If the input is a PPM (color)  file
     >> 	 and  there  are 256 colors or fewer, pnmtotiff generates a
     >> 	 color palette TIFF file.  If there are  more  colors  than
     >> 	 that,  pnmtotiff  generates an RGB (not RGBA) single plane
     >> 	 TIFF  file.   Use  pnmtotiffcmyk  to  generate  the  cyan-
     >> 	 magenta-yellow-black ink color separation TIFF format.
     >> 
     >>   ...

read the "NOTES" section above!

    Olivier> 2 Some R functions are available to represent
    Olivier> images.  So, i would like to represent my matrix
    Olivier> (in the red channel for exemple) but i don't know
    Olivier> how i can use the rgb function to represent it. I
    Olivier> am not familar with image analysis and my problem
    Olivier> is that i don't know how i can take into account
    Olivier> the large scale of my values with only the red
    Olivier> colours.

    Olivier> I can use the rgb function with something like
    Olivier> reds <- rgb(r=1, g=(255:0)/255,b=(255:0)/255) and
    Olivier> image(mat,col=reds).

    Olivier> But the image is not very "good" (all the image is
    Olivier> red) and may be it should be better with more
    Olivier> levels of red colors.

Now I see clearer. I think in principle, you shouldn't use
rgb() at all but rather one of the functions

       rainbow(), heat.colors(), .....   {see the help page for rainbow}

for creating a larger number of *continuous* colours.
However, it seems you don't come close to 2^16 ~= 65000 different colors
easily, using these (e.g.  length(unique(rainbow(2^16))) is only 1530).
{{actually I think you don't want to come really close to 65000,
  I'd guess a few thousands would always suffice in statistics,
  but that's not the point here ...}}
 
---> Challenge to all : Have you found nice easily constructed
continuous color palettes scheme with substantionally more different colors?
One approach could start combining rainbow(n, v, s) with
non-default values of `v' and `s'.  
The more general problem could be stated as :
Maybe restricting yourself to a close neigborhood of a 2-d
surface in that cube (to have only points of 
approximately similar luminance, eg) would be an important option.

So, yes as a matter of fact, we got a nice fun problem to play
around with thanks to your enquiry.

In any case, get the pixmap package and read the (only two) help
pages from it!

    Olivier> For now, i use a log transformation on my data
    Olivier> (image(log(mat),col=2)) and i obtain an image with
    Olivier> more "structures". I have also change my object
    Olivier> reds by using a non linear function for the g and b
    Olivier> values .  But maybe , there is another way to
    Olivier> represent this image.

    Olivier> I hope my problem is more clear.
yes, it has become.
Olivier> Martin Maechler wrote:
>>>>>>> "Olivier" == Olivier Martin <olivier.martin at inrialpes.fr> writes:
    >>>>>>> 
    >> 
    Olivier> I have a 16 bit image (TIFF) and i want to analyse
    Olivier> the pixels distribution.  So, i obtain a matrix
    Olivier> which values are between 0 and 2^16 -1.
    >> ok
    >> 
    Olivier> Now i would like to represnt this image with the
    Olivier> fucntions rgb() and image().  
    >> `perfect'
    >> 
    Olivier> I am not sure , but i think that only 256 colors
    Olivier> are available.  
    >> 
    >> what makes you think so?  It's not true.
    >> 
    >> There are (2^8)^3 (i.e 24-bit) colors in R, as you can see
    >> quickly from looking at the result of rgb(), e.g.
    >> 
    >> Now the for viewing thing is devices, i.e. hardware and
    >> device-driver software.
    >> A few years ago, still many Sun Workstations came with graphics
    >> cards that only permitted 8-bit (i.e. 256 different colors at a time).
    >> 
    >> Can you be more specific about your problems?
    >> 
    Olivier> So is there a solution to represent all the palette
    Olivier> of the colors or i have to limit the
    Olivier> representations with 256 colors.
    >> 
    >> Martin Maechler <maechler at stat.math.ethz.ch>	http://stat.ethz.ch/~maechler/
    >> Seminar fuer Statistik, ETH-Zentrum  LEO C16	Leonhardstr. 27
    >> ETH (Federal Inst. Technology)	8092 Zurich	SWITZERLAND
    >> phone: x-41-1-632-3408		fax: ...-1228			<><

Martin
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
What about

% R --vanilla

intToHex <- function(x) {
  y <- as.integer(x)
  class(y) <- "hexmode"
  y <- as.character(y)
  dim(y) <- dim(x)
  y
}

as.character.hexmode <- function(x) {
  hexDigit <- c(0:9, "A", "B", "C", "D", "E", "F")
  isna <- is.na(x)
  y <- x[!isna]
  ans0 <- character(length(y))
  z <- NULL
  while (any(y > 0) | is.null(z)) {
    z <- y%%16
    y <- floor(y/16)
    ans0 <- paste(hexDigit[z + 1], ans0, sep = "")
  }
  ans <- rep(NA, length(x))
  ans[!isna] <- ans0
  ans
}

rgb256 <- function(r, g, b) {
  r <- intToHex(r %% 256)
  g <- intToHex(g %% 256)
  b <- intToHex(b %% 256)
  rgb <- cbind(r, g, b)
  # Pad a zero to all value less than 10.
  idx <- (nchar(rgb) == 1)
  rgb[idx] <- paste("0", rgb[idx], sep="")
  rgb <- apply(rgb, MARGIN=1, FUN=paste, collapse="")
  paste("#", rgb, sep="")
}

mirror.matrix <- function(x) {
  x <- as.data.frame(x)
  x <- rev(x)
  as.matrix(x)
}

rotate270.matrix <- function(x) {
  mirror.matrix(t(x))
}

image.matrix <- function(z, ...) {
  image(rotate270.matrix(z), ...)
}

imageToPNG <- function(z, colorTable, filename, transparent=NULL) {
  width <- ncol(z)
  height <- nrow(z)
  if (!is.null(transparent))
    z[z == transparent] <- NA
  x <- 1:width
  y <- 1:height
  png(filename, width=width, height=height, bg="transparent")
  on.exit(dev.off())
  par(mar = c(0, 0, 0, 0))
  image.matrix(x=x, y=y, z=z, col=colorTable, axes=FALSE)
}

# Create a palette of all nuances of red combined with 256^2 different
# shades of gray. Was this what you wanted? I don't really get that or
# if it was just an example. BTW, it is only possible to create 256
# different red nuances.
r <- as.vector(matrix(0:255, nrow=256, ncol=256, byrow=TRUE))
g <- b <- 0:255
rgb <- rgb256(r,g,b)

# Create an "image" of 2^16 different color values
ncolors <- 2**16
z <- matrix(0:(ncolors-1), nrow=256, ncol=256)

# Write the "image" to a PNG file
imageToPNG(z, colorTable=rgb, filename="foo.png")

# Or just red nuances
imageToPNG(z, colorTable=rgb256(0:255,0,0), filename="bar.png")

(This code was verify on R v1.5.1/WinMe).

Then, as suggested, use ImageMagick's convert or something to convert this
to TIFF.

Henrik Bengtsson

Dept. of Mathematical Statistics @ Centre for Mathematical Sciences
Lund Institute of Technology/Lund University, Sweden (+2h UTC)
+46 46 2229611 (off), +46 708 909208 (cell), +46 46 2224623 (fax)
h b @ m a t h s . l t h . s e, http://www.maths.lth.se/~hb/
http://stat.ethz.ch/~maechler/
    >> Seminar fuer Statistik, ETH-Zentrum  LEO C16	Leonhardstr. 27
    >> ETH (Federal Inst. Technology)	8092 Zurich	SWITZERLAND
    >> phone: x-41-1-632-3408		fax: ...-1228			<><

Martin
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._.
_._


-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._