You'll recall that we import
a library using the import keyword.
So just import PIL, and we run this.
Documentation is a big help in learning a library.
There exists standards that make this process easier.
For example, most of the libraries let you
check their version using the version attribute.
So we go PIL.
and then double underscore.
So this is called dander version dander.
We see the version of the one that I'm using is 4.2.1.
You might be using a different version
because we might have upgraded it.
Let's figure out how to open an image with Pillow.
Python provides some built-in functions to help us
understand the functions and
objects which are available in libraries.
For instance, the help function
when called on any object,
returns the objects built-in documentation.
Let's try it with our new library and module, PIL.
So help PIL and this renders nicely in line
a bit of help file that actually comes from
the documentation of the source code itself.
This shows us that there's a host of
classes available to us in the module,
as well as version information and even the file
called dander init dander.py,
which has the source code for the module itself.
We can look up the source code for this
in the Jupyter console if we wanted to.
These documentation standards make it easy to
poke around an unexplored a library.
Python also has a function called dir,
which will list the contents of an object.
This is especially useful with modules where you
might want to see which classes you might interact with.
Let's list the details of the PIL module.
So dir PIL, and we can see
here a list comes back with a bunch of strings.
Most of these are intended to be internal functions.
So they've got dander before and dander after,
and that's just double underscore,
that's a fancy way in Python that they say.
We see that there's a couple that,
do not have a dander and
are expected to be used more generally.
At the top of this list,
there's something called Image.
This sounds like it could be interesting for us.
So let's import it directly,
and run the help command on it.
So from PIL we'll Import image, then help Image.
Running help on the Image tells us that
this object is the Image class wrapper.
We see from the top level documentation
about the image object that
there's hardly ever any reason
to call the image constructor directly,
and they suggest that we use
the open function and that's what
we should be using to get images.
Let's call help on the open function
to see what it's all about.
Remember that since we want to
pass in the function reference,
and not run the function itself,
we don't put parentheses behind the function name.
So help Image.open, we're passing
an object but that object is
actually a reference to the function.
So it looks like Image.open is
a function that loads an image from a file,
and returns an instance of the image class.
Let's give it a try.
In the read_only directory there's
an image I've provided which is
from our Master's of Information
program recruitment flyer.
Let's try and load that now.
So file we'll make it a string,
read_only directory and then
MSI_recruitment.gif and we'll call
image.open and pass it this path to the file.
That should return to us an image object,
which we're going to put it into the image variable.
Let's just print out this image.
So we see it printed a
PIL.GifImagePlugin.GifImageFile and it gives
us some other information there.
So we see that this returns to us
a kind of PIL.GifImagePlugin.GifImageFile.
At first this might seem a bit confusing,
because we were told by
the docs that we should be expecting
a PIL.Image.Image object back.
But this is actually just object inheritance working.
In fact, the object returned is
both an Image and a GifImageFile.
We can use the Python inspect module to see this,
as the getmro function will return a list of all
of the classes that are being
inherited by a given object.
Let's give it a try. So we'll import inspect.
Now this is not a third party library,
it comes with Python.
Then we'll write a function.
We'll just print the type of the image.
So a type will tell us the type of the image,
but we want to convert that to a string.
But then we're going to call inspect.getmro
and pass it the type
of the image and see
what that inheritance chain looks like.
So we'd see the result is
a tuple that's returned to us which is actually
all of the different objects that are
being inherited from here with
GifImagePlugin at the very
usually bottom we would call this of the inheritance,
the most specific version
up to an ImageFile up to an Image,
and then finally up to an object.
Now that we're comfortable with the object,
how do we view the image?
It turns out that the image object has a show function.
You can find this by looking at
the properties of the object if you wanted to,
using the dir function.
So we'll call image.show,
and that didn't seem to have the intended effect.
The problem is the image is stored
remotely on Coursera's server,
but show tries to show it locally to you.
So if the Coursera server software it was running
on someone's workstation in Mountain View California,
where Coursera has its offices,
then you just popped up
a picture of our recruitment materials.
Thanks for that. Instead though,
we want to render the image in the Jupyter notebook.
It turns out Jupyter has
a function which can help with this.
So from IPython.display,
we'll talk a little bit more about that,
but IPython was one of
the early terms for Jupyter and it started as
just an interactive Python interpreter
before moving into a much larger project.
We want to import the display function,
and then let's call display and pass it the image.
Okay. So there we see our inline display of
happy Masters of Science in Information students.
For those who would like to understand
this in more detail,
the Jupyter environment is running a special wrapper
across the Python interpreter called IPython.
IPython allows the kernel back end to
communicate with the browser front end
among other things.
The IPython package has a display function,
which can take objects and use
custom formatters in order to render them to the screen.
There's a lot of different formatters provided including
ones which know how to handle
image types and different image types,
and that's what we're using here.
That's a quick overview of how to read
and display images using pillow.
In the next lecture, we're going to jump
in a bit more into
detail to understand how to
use pillow to manipulate images.