I'm reading the blog on mosaics by Theodore Gray. I tried the first example:

dir = "d:\\mosaic\\pool\\*.jpg";  
master = "d:\\mosaic\\master.jpg";  
imagePool = Map[With[{i = Import[#]}, {i, Mean[Flatten[N[i[[1, 1]]], 1]]}] &, 
closeMatch[c_] := RandomChoice[Take[SortBy[imagePool, Norm[c - #[[2]]] &], 20]][[1]];
Grid[Reverse[Map[closeMatch, Import[master][[1, 1]], {2}]], Spacings -> {0, 0}]

but it gives me errors:

Part::partd: Part specification (<an image>)[1,1] is longer than depth of object.

I'm using Mathematica version 9. A comment on the blog says the code has to be modified for version 8, so I guess the changes are also required for version 9. How can I make this code work?

  • 3
    $\begingroup$ Have you tried debugging this yourself? It's a very good leaning exercise to try. For a start, you have two lines of code that actually does something (other than definitions). Have you looked at which one causes the error? If you found that out already, have you tried to "peel back" a few layers of functions to find out which exact part of the offending line causes the problem? $\endgroup$
    – Szabolcs
    Feb 2, 2014 at 19:07
  • $\begingroup$ @Szabolcs: I'm a beginner in Mathematica, and the code isn't all clear to me. But I'm confused by image[[1,1]], because I thought the first element of the image object is the pixel map, so the [[1,1]] doesn't seem to make sense. Correct? $\endgroup$ Feb 2, 2014 at 19:18
  • $\begingroup$ I updated the answer with a few more changes. $\endgroup$
    – Szabolcs
    Feb 2, 2014 at 19:28
  • 1
    $\begingroup$ Exact same question on Stack Overflow. $\endgroup$
    – rm -rf
    Feb 2, 2014 at 20:21
  • 2
    $\begingroup$ @rm-rf yeah, but do you really trust the guy who posted the accepted answer? $\endgroup$ Feb 2, 2014 at 21:09

1 Answer 1


The problem is that in version 9 Image became an atomic object, so it's not possible to extract the image data using Part any more. Here's a mention of this change.

You need to change every occurrence of someImage[[1,1]] to ImageData[someImage]

This takes the small images from the example data. It filters only those that have a square aspect ratio.

images = Select[ExampleData /@ ExampleData["TestImage"], Equal @@ ImageDimensions[#] &];

Now let us resize all of them to 50 pixels wide (so they're the same size) and set their magnification to 1. The Magnification option only affects how they're displayed on screen, but doesn't change the image data. This is useful to have to prevent automatic sizing within Grid later, and potential alignment problems when the grid doesn't fit in the window.

images = Image[ImageResize[#, 50], Magnification -> 1] & /@ images

These images won't give a very pretty output unfortunately, but I wanted to post self-contained code that doesn't rely on external image files people might not have.

I took the master image from the example data too. Note that here master holds an image, not a file name, so the rest of the code needs to be changed accordingly. I resized master to 10 by 10 so the resulting grid will also consist of 10 by 10 small images.

master = ImageResize[ExampleData[{"TestImage", "Lena"}], 10]

The rest is mostly identical, except for the change I mention and for using master as an image instead of a file name.

imagePool = 
  Function[i, {i, Mean@Flatten[N@ImageData[i], 1]}] /@ images;

closeMatch[c_] := 
  First@RandomChoice@Take[SortBy[imagePool, Norm[ c - #[[2]] ] &], 20];

Grid[Reverse@Map[closeMatch, ImageData[master], {2}],
  Spacings -> {0, 0}]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.