Reputation: 43
I am trying to make a library related to RGB pixel data, but cannot seem to save the image data correctly.
That is my output image. This is my code:
pixelmanager.py
from PIL import Image
import numpy as np
class MakeImgFromPixelRGB:
def createIMG(PixelArray: list, ImgName: str, SaveImgAsFile: bool):
# Convert the pixels into an array using numpy
array = np.array(PixelArray, dtype=np.uint8)
if SaveImgAsFile == True:
new_image = Image.fromarray(array)
new_image.save(ImgName)
class getPixelsFromIMG:
def __init__(self, ImagePath):
im = Image.open(ImagePath, 'r')
width, height = im.size
pixel_values = list(im.getdata())
self.output = pixel_values
test.py
import pixelmanager
a = pixelmanager.getPixelsFromIMG(ImagePath="download.jpg")
pixelmanager.MakeImgFromPixelRGB.createIMG(a.output, "output.png", True)
with open("output.txt", "w") as f:
for s in a.output:
f.write(str(s) + "," + "\n")
I have tried to de-scale the image in paint.net and also tried to mess with the uint size.
Upvotes: 2
Views: 98
Reputation: 43
Mark Setchell was ALMOST correct. His code did help me get an image, but it was repeated 4 times in one.
Mark's line of code had a switchup (with h as height and w as width):
array = np.array(PixelArray, dtype=np.uint8).reshape(h,w,3)
This is my line of code:
array = np.array(PixelArray, dtype=np.uint8).reshape(w, h, 3)
Upvotes: 1
Reputation: 207798
Treating images as Python lists of pixels is not generally the best idea, because it is slow and error-prone. In general, you want to use PIL's functions which are coded in C
and deal with PIL Image
types, or Numpy or OpenCV which are highly vectorised/optimised and deal with Numpy arrays.
Anyway, if you really, really want to deal with lists (which you don't), you need to remember that when you call Image.getdata()
against a JPEG you will get a flat list of RGB tuples. So, if your image is 640x480 pixels, and you do this:
im = Image.open('image.jpg')
px = list(im.getdata())
you will get a list with 307,200 entries, each one an RGB tuple. BUT your list no longer knows the height and width of the image. So, when you subsequently do:
array = np.array(PixelArray, dtype=np.uint8)
your array is now shaped (307200,3) instead of (480,640,3) - sooooo, you get a long line of pixels in your output image.
If you are insistent on using lists, you will need to retain the height and with of the original image, so you can do:
array = np.array(PixelArray, dtype=np.uint8).reshape(h,w,3)
Note that you should also remember the image's mode, i.e. whether it was RGB or RGBA, or P, or PA, or L, or LA, or HSV etc. And note that will also make your tuples of length 1, 2, 3 or 4 instead of always assuming 3. Later on, you will also realise you may have to deal with 16/32/64 bits/sample images so you will need to remember that too, in addition to the above.
Upvotes: 4