Images Mini-Lesson:

  • Grey Scale
    • use code from 2.2
    • research how it relates to binary
    • update code so user can access images from browser (doesn't have to download image)
from IPython.display import HTML, display
from pathlib import Path  # https://medium.com/@ageitgey/python-3-quick-tip-the-easy-way-to-deal-with-file-paths-on-windows-mac-and-linux-11a072b58d5f
from PIL import Image as pilImage # as pilImage is used to avoid conflicts
from io import BytesIO
import base64
import numpy as np

# prepares a series of images
def image_data(path=Path("images/"), images=None):  # path of static images is defaulted
    if images is None:  # default image
        images = [
            {'source': "Internet", 'label': "Green Square", 'file': "green-square-16.png"},
        ]
    for image in images:
        # File to open
        image['filename'] = path / image['file']  # file with path
    return images

# Large image scaled to baseWidth of 320
def scale_image(img):
    baseWidth = 320
    scalePercent = (baseWidth/float(img.size[0]))
    scaleHeight = int((float(img.size[1])*float(scalePercent)))
    scale = (baseWidth, scaleHeight)
    return img.resize(scale)

# PIL image converted to base64
def image_to_base64(img, format):
    with BytesIO() as buffer:
        img.save(buffer, format)
        return base64.b64encode(buffer.getvalue()).decode()

# Set Properties of Image, Scale, and convert to Base64
def image_management(image):  # path of static images is defaulted        
    # Image open return PIL image object
    img = pilImage.open(image['filename'])
    
    # Python Image Library operations
    image['format'] = img.format
    image['mode'] = img.mode
    image['size'] = img.size
    # Scale the Image
    img = scale_image(img)
    image['pil'] = img
    image['scaled_size'] = img.size
    # Scaled HTML
    image['html'] = '<img src="data:image/png;base64,%s">' % image_to_base64(image['pil'], image['format'])
    
# Create Grey Scale Base64 representation of Image
def image_management_add_html_grey(image):
    # Image open return PIL image object
    img = image['pil']
    format = image['format']
    
    img_data = img.getdata()  # Reference https://www.geeksforgeeks.org/python-pil-image-getdata/
    image['data'] = np.array(img_data) # PIL image to numpy array
    image['gray_data'] = [] # key/value for data converted to gray scale

    # 'data' is a list of RGB data, the list is traversed and hex and binary lists are calculated and formatted
    for pixel in image['data']:
        # create gray scale of image, ref: https://www.geeksforgeeks.org/convert-a-numpy-array-to-an-image/
        average = (pixel[0] + pixel[1] + pixel[2]) // 3  # average pixel values and use // for integer division
        if len(pixel) > 3:
            image['gray_data'].append((average, average, average, pixel[3])) # PNG format
        else:
            image['gray_data'].append((average, average, average))
        # end for loop for pixels
        
    img.putdata(image['gray_data'])
    image['html_grey'] = '<img src="data:image/png;base64,%s">' % image_to_base64(img, format)


# Jupyter Notebook Visualization of Images
if __name__ == "__main__":
    # Use numpy to concatenate two arrays
    images = image_data()
    
    # Display meta data, scaled view, and grey scale for each image
    for image in images:
        image_management(image)
        print("---- meta data -----")
        print(image['label'])
        print(image['source'])
        print(image['format'])
        print(image['mode'])
        print("Original size: ", image['size'])
        print("Scaled size: ", image['scaled_size'])
        
        print("-- original image --")
        display(HTML(image['html'])) 
        
        print("--- grey image ----")
        image_management_add_html_grey(image)
        display(HTML(image['html_grey'])) 
    print()
---- meta data -----
Green Square
Internet
PNG
RGBA
Original size:  (16, 16)
Scaled size:  (320, 320)
-- original image --
--- grey image ----

How this Code utilizes binary:

  • I asked Chat GPT and this is what it said:
  • "This code does not utilize binary directly, but it uses base64 encoding to represent the PIL image data in a format that can be displayed in HTML. The image_to_base64() function converts the PIL image data to a base64-encoded string, which is then used to embed the image in an HTML tag. The base64-encoded string is essentially a binary representation of the image data that can be transmitted over the web. The resulting image is displayed using the display() function from IPython.display, which renders the HTML in the Jupyter Notebook environment."

Other Binary Image Ideas:

  • Pixel Art: random or image?
    • used binary to display the pixel as either "on" (white) or "off" (black)
  • QR code?
    • retail uses QR codes to make idenitfying easier
    • pixel is either "on" or "off" like the pixel art
from random import randint
from PIL import Image
from IPython.display import Image as ImgDisplay

# create a new image with a black background
img = Image.new('1', (500, 500), 0)

# create a pixel access object for the image
pixels = img.load()

# set random pixel values
for i in range(img.size[0]):
    for j in range(img.size[1]):
        pixels[i, j] = randint(0, 1)

# save the image as a PNG file
img.save('random_pixel_art.png')

# display the image in the notebook
ImgDisplay(filename='random_pixel_art.png')
from PIL import Image
from IPython.display import Image as ImgDisplay

# load the image
img = Image.open('/home/alexac54767/vscode/Alexa-Fastpage/images/thumbs up.jpg')
img.show()


# reduce the number of colors to a limited palette
img = img.quantize(colors=10)

# convert the image to a pixel art representation
img = img.convert(mode='1', dither=None)


# save the pixel art as a PNG file
img.save('pixel_art.png')
ImgDisplay(filename='pixel_art.png')