[Tex/LaTex] Can TikZ create pixel art images

tikz-pgf

Can you create images like this:

enter image description here

when you have something like

0 = green (#54ff00)
1 = white (#ffffff)
2 = red   (#ff0000)
3 = blue  (#0048ff)

Image (Python list of integers defined above):
[[2,0,0,0,0,0,0],
 [0,3,0,0,0,0,0],
 [0,3,2,1,1,0,0],
 [0,3,2,2,2,1,1],
 [0,3,2,0,0,1,0],
 [0,0,0,0,0,1,0],
 [0,0,0,0,0,1,0]]

with TikZ?

How far I got

The following MWE defines all colors, produces a grid of the correct size (though the size is determined by hand):

\documentclass[varwidth=true, border=2pt]{standalone}
\usepackage{tikz}
\usepackage{xcolor}

\begin{document}
    \newcommand\n{7}
    \definecolor{green}{HTML}{54FF00}
    \definecolor{wite}{HTML}{FFFFFF}
    \definecolor{red}{HTML}{FF0000}
    \definecolor{blue}{HTML}{0048FF}
    \begin{tikzpicture}
        \foreach \x in {1,...,\n}{
            \foreach \y in {1,...,\n}{
                \begin{scope}[shift={(\x,\y)}]
                  \draw [fill=green] (0,0) rectangle (1,1);
                \end{scope}
            }
        }
    \end{tikzpicture}
\end{document}

Of course, I could simpy make a lot of adjusted

                \begin{scope}[shift={(\x,\y)}]
                  \draw [fill=green] (0,0) rectangle (1,1);
                \end{scope}

but I've wondered if this can (with reasonable effort) be done in TikZ / LaTeX.

My problem is giving TikZ the color array. I don't have any idea how to do this.
I only know two types of looks in TikZ:

\foreach \x in {0,1,2,3,4,5}{...}
\foreach \number in {1,...,\n}{...}

I have never seen a nested over a 2D-array. All I have seen so far were 1D-Arrays of tuples (with fixed tuple size).

Best Answer

Here is a completely different approach from my other answer, and this one takes as its input, a form similar to that mentioned by the OP, namely:

\def\map{
[[2,0,0,0,0,0,0]
 [0,3,0,0,0,0,0]
 [0,3,2,1,1,0,0]
 [0,3,2,2,2,1,1]
 [0,3,2,0,0,1,0]
 [0,0,0,0,0,1,0]
 [0,0,0,0,0,1,0]]
}

In this case, this argument is passed to the macro \boxart. The box size is set with \setlength{\boxsize}{}.

EDIT: The OP has asked for a clarification on the code internals of \boxart. In this routine, I use some macros from the stringstrings package to strip out left brackets, turn commas into spaces, and turn right brackets into " . " strings. The result is a space-separated string (\thestring), that will look like

2 0 0 0 0 0 0 . 0 3 0     etc.

The \getargsC macro from readarray knows how to efficiently read space-delimited strings and is fed this string. The number of arguments in the string is stored in \narg and each argument is stored individually in \argi, \argii, \argiii, etc. Once that is done, a loop is set up (to go through \narg iterations, once for each item in \thestring), and each argument is checked. If it is a 0, a \gr is issued for a green block, and so on for 1, 2, and 3. If a . is found, a \par (paragraph) is issued. This while loop is performed inside a \parbox, so that the local line spacing can be set and the result doesn't have to start in the left column of the document (I should point out that the \parbox width was set arbitrarily by me, and may need to be manually tweaked by the user).

For the OP's edification, an \edef is an assignment where the contents of the argument are fully expanded before being assigned. Thus, what is found in \clr are the individual items from \thestring successively stored in the \arg... variables: \argi is 2, \argii is 0, ..., \argviii is ., etc.

\documentclass{article}
\usepackage{xcolor}
\usepackage{stringstrings}
\usepackage{readarray}
\newlength\boxsize
\setlength\boxsize{1ex}
\def\block#1{\fboxsep=0pt\fbox{\color{#1}\rule{\boxsize}{\boxsize}}\kern-\fboxrule}
\def\gr{\block{green}}
\def\rd{\block{red}}
\def\bl{\block{blue}}
\def\wh{\block{white}}
\newcounter{index}%
\newcommand\boxart[1]{%
  \setcounter{index}{0}%
  \convertchar[q]{#1}{,}{ }%
  \convertchar[q]{\thestring}{[}{}%
  \convertchar[q]{\thestring}{]}{ . }%
  \getargsC{\thestring}%
  \parbox[b]{8ex}{%
    \baselineskip\boxsize%
    \parindent 0ex%
    \parskip -.2\boxsize%
    \addtolength{\parskip}{-2\fboxrule}%
    \whiledo{%
      \theindex < \narg}{%
      \stepcounter{index}%
      \edef\clr{\csname arg\romannumeral\theindex\endcsname}%
      \expandafter\if\clr0\gr\fi%
      \expandafter\if\clr1\wh\fi%
      \expandafter\if\clr2\rd\fi%
      \expandafter\if\clr3\bl\fi%
     \expandafter\if\clr.\par\fi%
    }%
  }%
}
\begin{document}
%0 = green (#54ff00)
%1 = white (#ffffff)
%2 = red   (#ff0000)
%3 = blue  (#0048ff)
\def\map{
[[2,0,0,0,0,0,0]
 [0,3,0,0,0,0,0]
 [0,3,2,1,1,0,0]
 [0,3,2,2,2,1,1]
 [0,3,2,0,0,1,0]
 [0,0,0,0,0,1,0]
 [0,0,0,0,0,1,0]]
}
Here it is: \boxart{\map}

\def\map{
[[2,0,0,0,0]
 [0,3,0,0,0]
 [0,3,2,0,0]
 [0,3,2,1,1]
 [0,3,0,1,0]]
}
\setlength{\boxsize}{1.2ex}
Another: \boxart{\map}
\end{document} 

enter image description here