Python Libraries and Concepts used for Jupyter and Files/Directories
Introduction to displaying images in Jupyter notebook
IPython
Support visualization of data in Jupyter notebooks. Visualization is specific to View, for the web visualization needs to be converted to HTML.
pathlib
File paths are different on Windows versus Mac and Linux. This can cause problems in a project as you work and deploy on different Operating Systems (OS's), pathlib is a solution to this problem.
- What are commands you use in terminal to access files?
- What are the command you use in Windows terminal to access files?
- What are some of the major differences?
Provide what you observed, struggled with, or leaned while playing with this code.
- Why is path a big deal when working with images?
- How does the meta data source and label relate to Unit 5 topics?
- Look up IPython, describe why this is interesting in Jupyter Notebooks for both Pandas and Images?
from IPython.display import Image, display
from pathlib import Path
def image_data(path=Path("../images"), images=None):
if images is None:
images = [
{'source': "Peter Carolin", 'label': "Clouds Impression", 'file': "logo.png"},
]
for image in images:
image['filename'] = path / image['file']
return images
def image_display(images):
for image in images:
display(Image(filename=image['filename']))
if __name__ == "__main__":
default_images = image_data()
image_display(default_images)
from IPython.display import HTML, display
from pathlib import Path
from PIL import Image, ImageDraw
from io import BytesIO
import base64
import numpy as np
class Image_Data:
def __init__(self, source, label, file, path, baseWidth=320):
self._source = source
self._label = label
self._file = file
self._filename = path / file
self._baseWidth = baseWidth
self._img = Image.open(self._filename)
self._format = self._img.format
self._mode = self._img.mode
self._originalSize = self.img.size
self.scale_image()
self.write_metadata()
self._html = self.image_to_html(self._img)
self._html_grey = self.image_to_html_grey()
self._html_dark = self.image_to_html_dark()
@property
def source(self):
return self._source
@property
def label(self):
return self._label
@property
def file(self):
return self._file
@property
def filename(self):
return self._filename
@property
def img(self):
return self._img
@property
def format(self):
return self._format
@property
def mode(self):
return self._mode
@property
def originalSize(self):
return self._originalSize
@property
def size(self):
return self._img.size
@property
def html(self):
return self._html
@property
def html_grey(self):
return self._html_grey
@property
def html_dark(self):
return self._html_dark
def scale_image(self):
scalePercent = (self._baseWidth/float(self._img.size[0]))
scaleHeight = int((float(self._img.size[1])*float(scalePercent)))
scale = (self._baseWidth, scaleHeight)
self._img = self._img.resize(scale)
def image_to_html(self, img):
with BytesIO() as buffer:
img.save(buffer, self._format)
return '<img src="data:image/png;base64,%s">' % base64.b64encode(buffer.getvalue()).decode()
def write_metadata(self):
draw_image = ImageDraw.Draw(self.img)
draw_image.text((10, 10), "Source: " + self.source, fill=(10, 10, 10, 128))
draw_image.text((10, 20), "Label: " + self.label, fill=(10, 10, 10, 128))
draw_image.text((10, 30), "Path: " + str(self.filename), fill=(10, 10, 10, 128))
def image_to_html_grey(self):
img_grey = self._img
numpy = np.array(self._img.getdata())
grey_data = []
for pixel in numpy:
average = (pixel[0] + pixel[1] + pixel[2]) // 3
if len(pixel) > 3:
grey_data.append((average, average, average, pixel[3]))
else:
grey_data.append((average, average, average))
img_grey.putdata(grey_data)
return self.image_to_html(img_grey)
def image_to_html_dark(self):
img_dark = self._img
numpy = np.array(self._img.getdata())
dark_data = []
for pixel in numpy:
average = (pixel[0] + pixel[1] + pixel[2]) // 9
if len(pixel) > 3:
dark_data.append((average, average, average, pixel[3]))
else:
dark_data.append((average, average, average))
img_dark.putdata(dark_data)
return self.image_to_html(img_dark)
class Draw_Image:
def __init__(self, mode: str, size: tuple, color: tuple):
self._new_image = Image.new(mode, size, color)
self._img = ImageDraw.Draw(self.new_image)
@property
def img(self):
return self._img
@property
def new_image(self):
return self._new_image
@property
def html(self):
return self._html
def draw_rectangle(self, xy: list, fill: tuple, outline: tuple, width: int):
self.img.rectangle(xy, fill, outline, width)
def image_to_html(self):
with BytesIO() as buffer:
self.new_image.save(buffer, format='PNG')
return '<img src="data:image/png;base64,%s">' % base64.b64encode(buffer.getvalue()).decode()
def image_data(path=Path("../images/"), images=None):
if images is None:
images = [
{'source': "Jamal", 'label': "Smiley Face", 'file': "smiley-face.jpg"},
{'source': "Jamal", 'label': "Jamal", 'file': "jamal.jpg"},
{'source': "Jamal", 'label': "Mort", 'file': "mort.jpg"},
]
return path, images
def image_objects():
id_Objects = []
path, images = image_data()
for image in images:
id_Objects.append(Image_Data(source=image['source'],
label=image['label'],
file=image['file'],
path=path,
))
return id_Objects
def drawn_image_objects():
drawn_objects = []
drawn_image1 = Draw_Image("RGBA", (400, 400), (15, 252, 3))
drawn_image1.draw_rectangle(xy=[50, 50, 150, 150], fill=(8, 8, 8), outline=1, width=1)
drawn_image1.draw_rectangle(xy=[350, 50, 250, 150], fill=(235, 23, 34), outline=1, width=1)
drawn_image1.draw_rectangle(xy=[50, 350, 350, 300], fill=(250, 245, 245), outline=1, width=1)
drawn_image2 = Draw_Image("RGBA", (400, 400), (191, 10, 176))
drawn_image2.draw_rectangle(xy=[50, 50, 150, 150], fill=(8, 8, 8), outline=1, width=1)
drawn_image2.draw_rectangle(xy=[350, 50, 250, 150], fill=(235, 23, 34), outline=1, width=1)
drawn_image2.draw_rectangle(xy=[50, 350, 350, 300], fill=(250, 245, 245), outline=1, width=1)
drawn_objects.append(drawn_image1)
drawn_objects.append(drawn_image2)
return drawn_objects
if __name__ == "__main__":
for ido in image_objects():
print("-- original image --")
display(HTML(ido.html))
print("--- grey image ---")
display(HTML(ido.html_grey))
print("--- darkened image ---")
display(HTML(ido.html_dark))
for drawn_image in drawn_image_objects():
print("--- drawn image ---")
display(HTML(drawn_image.image_to_html()))
print()
Hacks
Early Seed award
- Add this Blog to you own Blogging site.
- In the Blog add a Happy Face image.
- Have Happy Face Image open when Tech Talk starts, don't tell anyone. Show to Teacher.
AP Prep
- In the Blog add notes and observations on each code cell that request an answer.
- In blog add College Board practice problems for 2.3
- Choose 2 images, one that will more likely result in lossy data compression and one that is more likely to result in lossless data compression. Explain.
Project Addition
- If your project has images in it, try to implement an image change that has a purpose. (Ex. An item that has been sold out could become gray scale)
Pick a programming paradigm and solve some of the following ...
- Numpy, manipulating pixels. As opposed to Grey Scale treatment, pick a couple of other types like red scale, dark scale, or blue scale. We want you to be manipulating pixels in the image.
- Binary and Hexadecimal reports. Convert and produce pixels in binary and Hexadecimal and display.
- Compression and Sizing of images. Look for insights into compression Lossy and Lossless. Look at PIL library and see if there are other things that can be done.
- There are many effects you can do as well with PIL. Blur the image or write Meta Data on screen, aka Title, Author and Image size.