Join Chris Reilly for an in-depth discussion in this video Image sampling, part of Learning Grasshopper.
Image Sampling is a technique that allows us to take pixel data stored in an image file, and covert that data into numbers, which can then be used for transformations. Let's take a look at a simple example using Image Sampling, to control the scale of a large group of spheres. I'll start by setting up my Image Sampler component, and that's located under Params > Input. I'll click and drag that onto the canvas and then right click to access settings in the Contextual menu. To select an image file to work with, I'll click on the file path dialog here.
Now, the examples are all different gradients. Now, of course, you could use any sort of image you like, but these will just give us some nice patterns to work with. Below the file path dialogue I'll leave the auto update and save in file boxes checked. This will keep a copy of the file along with my Grasshopper definition. And it'll also look to see whether the original file has been updated. And if so, pull that in to Grasshopper. I also have some other settings here. Up above, I have an x and a y domain setting. Now, to get Image Sampler working properly, we'll need to feed it a series of points as input to tell it where in the image to sample.
So setting the domain of zero to one, let's just treat the width and the height of the image sort of like a percentage rather than having to worry about what the actual pixel dimensions are. So we'll leave that at the default setting of zero to one for both. Ah,down below we have channel options, so here we can tell Image Sampler which parts of the pixel data we'd like to look at. The RGB information all together, individual color channels like red, green or blue, transparency, hue, saturation. In this case, we want to look at brightness. So we'll just be looking at tones from light to dark, over the image.
Okay, so I'm all set here. I'll click OK. And now I need to set up a grid of points to feed into our Image Sampler. So first off, I'll go into Rhino and just click the Draw a Plane, doesn't really matter what size it is at this point, we could come back and change it, if we wanted to. And back in Grasshopper, I'll add a surface component from the Params > Geometry Component menu. I'll right click and select Set One Surface and bring my surface in from Rhino. And I'll also do a couple more things here just to get myself set up.
I want to make sure that I select this Reparametrize option from the Surface Contextual menu. So this sets the local UV coordinates of the surface to domains of zero to one. That way the domains of both the surface and the Image Sampler will match up. I'll also right click and select Internalized Data. So this will actually copy the plane data into my Grasshopper definition and I can delete the Rhino geometry. And that just makes it a little bit more convenient to work in Grasshopper. So now I'll use a divide surface component to generate a grid of UV points from my surface.
So I'll grab that from the Surface > Util Component Panel. And I'll connect my surface output to divide surface input and then I'll make two integer number sliders for the U and V counts of the divide surface component. And I'm just left clicking and holding down Alt and dragging to duplicate that component. And now I can see I get a grid of UV points over the surface and I can adjust the number of divisions, vertically or horizontally by scrubbing those number sliders. So now what I'd like to do, is make a series of spheres that align with each one of these points that are coming out of the divide surfaces component.
So look under> Surface > Primitive, and grab the Sphere Component. And I'll plug the divide surfaces points as tree, so those are the world coordinate points or the xyz points. I'll plug that into the sphere's base plane input. And that'll give me one sphere at each UV coordinate. And I can go ahead and disable the preview on my input surface, because I'm really just worried about those spheres. Now to get some information from our Image Sampler, we'll connect the divide surfaces UV output to the Image Samplers one input.
And then the Image Samplers output will connect to the radius input of the sphere's component. Whoops, now something's gone wrong here, I'm getting an error. If I right click and look at Runtime errors, that's a little bit cryptic but luckily, I already know what's going on here. What is happening is, since we're sampling the brightness of the image, there is a possibility that the value sampled from a given point will be zero. And if we pass a zero value into this sphere's radius, we'll get an error. So to fix that, I'll just add a little expression in between these two connections here. Adding a small value to the radius, maybe something like 0.2. So, look under > Script > Evaluate. And my expression here is just going to have one input. So I only need the x input here. So I'll zoom in so I can get to these little plus minus icons and get rid of y. And I'll connect the image sampler output to x and then the output of the evaluate component to the sphere's radius input and then under Params > Input, I'll grab a panel and I'll use that to feed my expression into the evaluate component and just resize.
And so make something like x plus 0.2 and that will just add a little bit to each radius to make sure that it will never be zero. So now the Image Sampler can look at the corresponding pixelity of the image for each UV point on the grid and use the brightness information found there to set the radius of the sphere at the same point on our surface. Let me just turn off the preview here on the points from our divide surface component. You can see a little bit more clearly what's going on. So now I can do things like maybe change the image. And adjust the U and V settings to get different results. So that's just a quick crash course into using image sampling to control transformations in Grasshopper
- What is Grasshopper?
- What's an algorithm?
- Setting input data
- Using data matching
- Looking at mathematical and logical functions
- Analyzing curves and surface data
- Working with transformations
- Manipulating the Data Tree