0

I've been using the Image module in PIL in python, and I'm trying to generate an image using an array of hex codes. I have the width of the image set to the number of colours, and I want to create an image where each pixel is a different colour listed in the array. The only issue is, I can't find any examples of this. It seems that the Image module is pretty limited, and I can't use the Choir function, since the number of colours needed isn't set. Is there any workaround for this?

martineau
  • 119,623
  • 25
  • 170
  • 301
KeTTLe
  • 1
  • 1
    Why can't you convert your data to a [bytes](https://docs.python.org/3/library/functions.html#func-bytes) object and then use [Image.frombytes](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.frombytes)? – Ture Pålsson Feb 17 '22 at 09:36
  • Your image is only one row? – martineau Feb 17 '22 at 10:07
  • Yep, just one row. I'm generating a palette using the colours from an image, so I only need one pixel per colour. – KeTTLe Feb 17 '22 at 10:25
  • Please share your array of hex codes, or if it is more than a few tens of elements just share the first 4-5 and give an indication of how many you have. Use the [edit] button rather than comments. Thank you. – Mark Setchell Feb 17 '22 at 10:40

1 Answers1

1

You can do using the PIL Image.frombytes() function as @Ture Pålsson suggested. I don't know exactly what format your "array of hex codes" is in, but the following illustrates the basic idea. The format of the data used is 3 bytes-per-pixel RGB.

from PIL import Image

data = bytes.fromhex('FF0000 00FF00 0000FF 00FF00 0000FF FF0000 0000FF FF0000 00FF00')
width = len(data) // 3
img = Image.frombuffer("RGB", (width, 1), data, "raw", "RGB", 0, 1)
img.show()

Screenshot of result (magnified):

screenshot

martineau
  • 119,623
  • 25
  • 170
  • 301
  • It's a list, like this: ["#123456", "#123466"], etc. Can I use a list in place of the fromhex function you've used there? – KeTTLe Mar 07 '22 at 03:10
  • You can't use a list of strings in that format directly, but you could probably convert it into a list of bytes without too much trouble. Does `"#123456"` represent the 3 byte byte hexadecimal value `0x123456`? – martineau Mar 07 '22 at 09:29
  • Just used a dodgy workaround not long ago, thanks. I ended up turning the list into a single string of hex codes and removing the #s. This worked like a treat. Thank you – KeTTLe Mar 07 '22 at 09:46
  • You can use [`PIL.ImageColor.getcolor()`](https://pillow.readthedocs.io/en/stable/reference/ImageColor.html#PIL.ImageColor.getcolor) to directly convert "#123456" into an RGB value. i.e. `ImageColor.getcolor("#123456", "RGB")` → `(18, 52, 86)` – martineau Mar 07 '22 at 09:51