How to store "List of List" when reading RGB values of an Image

Hi everyone,
Attached, I was playfully working with an idea of breaking an image into blocks with the size of x and y when I came across with this issue…
I can store the entire “RGB” values of the Image in one list (Here the list length is 5400), but I cannot divide the RGB values in correspondence with x * y blocks (Here 9 * 6).
Storing R, G, and B values separately just as seen in the image is fine.

Thanks, in advance, for your help.

test 01.gh (8.0 KB)


The input image:
test%2001

Could you pls. send your test image as well?

You got R, G, B values so where is the problem ? use R as x and G as y

Just uploaded.

Am trying to have access to RGBs of each block defined by x and y.
For example:
Block [0][0] contains these RGBs…
Block [0][1] contains these RGBs…

If you can with python find one pixel in the center of every square is better but you can split the list by 5400/(9*6) than choose the center item of every new list (indice 100/2)

colors.gh (18.4 KB)

2 Likes

Hi @Clive,

@seghierkhaled was faster, but here’s an other solution.

I’ve packed everything into a function that returns a nested list of pixels and lets you control the sampling of pixels. What you need to understand is that pixels are color objects that you can easily access the color channel (i.e. ARGB) of, by for instance simply calling pixel.R for the red color value of a pixel.
The nested list of pixels has a sublist for each sampled image row from top to bottom. If you sample 6 pixels in the image height, you get 6 sublists. If you sample 9 pixels in the image width, each of these sublists contains 9 color objects.
This nested list is output as a grasshopper tree with the same structure.

from ghpythonlib import treehelpers
import System

def get_pixels(image_path, samples_x, samples_y):
    """Gets the pixel colors of an image.
    
    Args:
      image_path: An absolute path to an image file.
      samples_x: A number of pixels to sample in image x-direction.
      samples_y: A number of pixels to sample in image y-direction.
    Returns:
      A list of lists with a sublist of pixel colors 
        for each sampled row of the image.
    """
    bitmap = System.Drawing.Bitmap.FromFile(image_path)
    # Calculate the sampling resolution (1=each pixel, 10=every 10th pixel)
    resolution_x = bitmap.Width / samples_x
    resolution_y = bitmap.Height / samples_y
    # Get the pixel colors
    pixels = []
    for y in xrange(bitmap.Height-1,-1,-1):
        if y % resolution_y == 0:
            row_pixels = []
            for x in xrange(bitmap.Width):
                if x % resolution_x == 0:
                    pixel = bitmap.GetPixel(x, y)
                    row_pixels.append(pixel)
            pixels.append(row_pixels)
    return pixels


pixels = get_pixels(ImagePath, SamplesX, SamplesY)

# Access the colors
for row in pixels:
    for color in row:
        a, r, g, b = color
        print "R: {}, G: {}, B: {}".format(r,g,b)

# Outputs
Colors = treehelpers.list_to_tree(pixels)

Here’s the file:
color2.gh (10.6 KB)

2 Likes

@seghierkhaled & @diff-arch
Apologies as I could not put it up clearly.
The problem is not yet solved.
A few points…

  • Extracting RGBs is a not an issue. My question is how to Nest them in some lists.
  • I use Rhino 5, and apparently treehelpers runs in Rhino 6.

Let’s imagine we have an image with 24 pixels.


Now I run a code that divides the image into 6 blocks…
img%2004
All I need is to have access to the list of RGBs within each block.
Something like this…

Hello Clive,

You can use a combination of modular arithmetic and integer division to go from your initial layout to the result you are looking for.

You could first use a set of nested loops to build empty lists in the required structure before repeating the same set of loops to append the appropriate values.

mylist.append([]) puts an empty list into a list.
mylist[0][0] references the first slot in the first sublist.

Does this help?

You can have a look here for how to read and write a DataTree in Rhino 5:

1 Like