photos
— Photo Library Access on iOS#
The photos
module allows you to access media that is stored in the iOS photo library.
You can also add new images to the library, modify existing content in-place, and delete items.
Note
The first time you use any of the functions that access your photos, a system-provided permission dialog will be shown. If you deny access, most functions will act as if your photo library was empty. If you change your mind later, you can allow access to your photos from the Privacy section in the Settings app. The permission dialog in the app will only be shown once.
Getting Started#
To start working with media in your photo library, you usually need at least one Asset
object. You can fetch all assets from the library using the get_assets()
function, as shown below:
# Get the last photo, and show it in the console
import photos
all_assets = photos.get_assets()
last_asset = all_assets[-1]
img = last_asset.get_image()
img.show()
Assets only contain metadata, so to get an actual image, you’ll have to use the Asset.get_image()
function, as shown in the example above. The image is returned as a PIL.Image.Image
object. If you want a ui.Image
instead, use Asset.get_ui_image()
.
Assets are organized in collections, which are represented as AssetCollection
objects. Collections can be regular albums or smart albums that automatically contain assets with certain properties.
One of those smart albums is the “screenshots” album, and you can retrieve it easily using the get_screenshots_album()
function. The following snippet shows how to retrieve the oldest screenshot and delete it from the library (after showing a confirmation dialog):
# Get the oldest screenshot image, and delete it from the library
import photos
album = photos.get_screenshots_album()
screenshots = album.assets
if not screenshots:
print('You have no screenshots in your library.')
else:
oldest = screenshots[0]
if oldest.can_delete:
# This will automatically show a confirmation dialog:
oldest.delete()
else:
print('Oldest screenshot is not deletable')
You can also modify the content of a photo in the library by replacing it with an edited image.
The following snippet fetches the last asset in the “recently added” album, converts it to grayscale, and then replaces the image. The edit can be reverted in the Photos app, or using the Asset.revert()
method.:
# Get the last photo, and convert it to grayscale, saving the edit in-place
import photos
album = photos.get_recently_added_album()
last = album.assets[-1]
if last.can_edit_content:
img = last.get_image()
grayscale_img = img.convert('L')
grayscale_img.save('.edit.jpg', quality=90)
last.edit_content('.edit.jpg')
else:
print('The asset is not editable')
The previous examples all fetched assets by index, but you can also just show a dialog to let the user pick an asset from a grid of thumbnails. The pick_asset()
function takes a list of assets (or an AssetCollection
) and returns the asset that was selected. It also allows multiple selection. If you call it without parameters, the “Recently Added” album is shown.:
# Show an image picker dialog (allowing multiple selection) and print the result
import photos
assets = photos.pick_asset(title='Pick some assets', multi=True)
print(assets)
Functions#
- photos.capture_image(camera='rear')#
Show a standard camera interface and return the captured image (a
PIL.Image.Image
object).If the device has no camera or if the camera interface is cancelled, None is returned.
You can pass
'front'
as the camera argument to start with the selfie camera (the user can always switch the camera manually).
- photos.get_assets(media_type='image', include_hidden=False)#
Fetch and return a list of all assets in the library with the given media type (
'image'
or'video'
). By default, assets that are marked as hidden are excluded.
- photos.get_asset_with_local_id(local_id)#
Fetch and return the asset with the given local identifier (the
Asset.local_id
attribute) from the library. If no asset with this identifier exists, an IOError is raised.
- photos.get_albums()#
Return a list of all regular albums in the photo library. The return value is a list of
AssetCollection
objects.
- photos.get_smart_albums()#
Return a list of all smart albums in the photo library. The return value is a list of
AssetCollection
objects.
- photos.get_moments()#
Return a list of all “moments” in the photo library. Moments are collections of assets that are automatically grouped by date/location. The return value is a list of
AssetCollection
objects.
- photos.get_favorites_album()#
Return the smart album that contains all assets that are marked as favorites. The return value is an
AssetCollection
object.
- photos.get_recently_added_album()#
Return the smart album that contains all assets that were recently added to the library. The return value is an
AssetCollection
object.
- photos.get_selfies_album()#
Return the smart album that contains all assets that were taken with the front camera. The return value is an
AssetCollection
object.
- photos.get_screenshots_album()#
Return the smart album that contains all assets that were created with the screenshot function. The return value is an
AssetCollection
object.
- photos.batch_delete(assets)#
Delete multiple assets from the photo library. assets must be a sequence of
Asset
objects. If one or more of the assets are not deletable, an IOError is raised, and no assets will be deleted. You can check if an asset can be deleted using theAsset.can_delete
attribute.
- photos.batch_revert(assets)#
Revert multiple assets to their original state (removing all edits). If one or more of the assets are not editable, an IOError is raised, and no assets are reverted. You can check if an asset is editable using the
Asset.can_edit_content
attribute.
- photos.create_album(title)#
Create and return a new album in the photo library, using the given title. The return value is an
AssetCollection
object that represents the new album.
- photos.create_image_asset(image_path)#
Create and return a new image asset using the given image file (e.g. a JPEG or PNG image). The return value is an
Asset
object that represents the added image.
- photos.pick_asset(assets=None, title='', multi=False)#
Show dialog with a grid of thumbnails for the given assets. assets can either be a sequence/list of
Asset
objects, or a singleAssetCollection
.If multi is True, the user can select multiple assets. Otherwise, the dialog is dismissed after one asset has been selected. The return value is either a single
Asset
object (if multi is False), or a list ofAsset
objects (if multi is True). If the asset picker is cancelled, None is returned.
Asset Class#
- class photos.Asset#
The
Asset
class represents a single media item in the photo library, i.e. an image or a video.Asset
objects cannot be initialized directly – you have to fetch them from the library usingget_assets()
or by accessing theAssetCollection.assets
property of an album or smart album.An
Asset
object only contains metadata. To get actual image data, use theAsset.get_image()
andget_image_data()
methods.To add a new image asset to the photo library, use the
create_image_asset()
function, providing the path to an image file that you’ve saved to disk previously.
Asset Methods#
- Asset.get_image(original=False)#
Fetch the asset’s image data, and return it as a
PIL.Image.Image
object.By default, the most recent version of the image is returned; pass original=True to get the image without any adjustments/edits.
- Asset.get_image_data(original=False)#
Fetch the asset’s image data, and return it as a
io.BytesIO
object. You can useio.BytesIO.getvalue()
to get the image data as a byte string.By default, the most recent version of the image is returned; pass original=True to get the image without any adjustments/edits.
If you only need the image for saving it as a file, this is more efficient than
Asset.get_image()
. The returnedio.BytesIO
has an additional uti attribute that can be used to determine the file type of the image data.
- Asset.get_ui_image(size=None, crop=False)#
Fetch the asset’s image data, and return it as a
ui.Image
object, e.g. to display it in a user interface. By passing a size (a pair of width/height), a smaller version of the image can be requested (passing None requests the largest version available).The crop parameter determines the resizing behavior when the aspect ratio of the image doesn’t match the size parameter. Pass True to get an image with the exact size given – this can be useful for generating thumbnail images, for example.
- Asset.edit_content(jpeg_path)#
Replace the asset’s image content with the given JPEG file.
If the asset is not editable, an IOError will be raised. You can check if an asset is editable using the
Asset.can_edit_content
attribute.Note that the image file must be in JPEG format. Other image formats are not supported for editing content (though you can create new assets from PNG/GIF files using
create_image_asset()
).The system will show a dialog to confirm the edit.
- Asset.delete()#
Delete the asset from the photo library.
If the asset is not deletable, an IOError will be raised. You can check if an asset is deletable using the
Asset.can_delete
attribute.The system will show a dialog to confirm the deletion.
If you want to delete multiple assets without showing a confirmation dialog for each one, use the
batch_delete()
function.
- Asset.revert()#
Revert the asset to its original state.
If the asset is not editable, an IOError will be raised. You can check if an asset is editable using the
Asset.can_edit_content
attribute.The system will show a dialog to confirm the edit.
If you want to revert multiple assets without showing a confirmation dialog for each one, use the
batch_revert()
function.
Asset Properties#
- Asset.local_id#
(read-only, string) A unique identifier of this asset on the current device.
- Asset.pixel_width#
(read-only, number) The width of the asset in pixels.
- Asset.pixel_height#
(read-only, number) The height of the asset in pixels.
- Asset.media_type#
(read-only, string) The asset’s media type (
'image'
or'video'
).
- Asset.media_subtypes#
(read-only, list of strings) The asset’s media subtypes (e.g.
'photo_screenshot'
,'photo_hdr'
…).
- Asset.creation_date#
(read-write, datetime) The asset’s creation date. Only writable if
Asset.can_edit_properties
is True.
- Asset.modification_date#
(read-write, datetime) The asset’s modification date.
(read-write, boolean) Whether the asset is hidden in the library. Only writable if
can_edit_properties
is True.
- Asset.favorite#
(read-write, boolean) Whether the asset is marked as a favorite. Only writable if
can_edit_properties
is True.
- Asset.duration#
(read-only, number) The duration of a video asset in seconds (always zero for still images).
- Asset.location#
(read-write, dict) The geo-location where the photo/video was taken, as a dict with at least
'latitude'
and'longitude'
keys (and optionally'altitude'
). Only writable ifcan_edit_properties
is True.
- Asset.can_edit_content#
(read-only, boolean) Whether the asset’s content can be modified (e.g. using
Asset.revert()
orAsset.edit_content()
).
- Asset.can_edit_properties#
(read-only, boolean) Whether the asset’s metadata can be modified (
Asset.favorite
,Asset.hidden
,Asset.creation_date
,Asset.location
).
- Asset.can_delete#
(read-only, boolean) Whether the asset can be deleted using
Asset.delete()
.
AssetCollection Class#
- class photos.AssetCollection#
AssetCollection
objects represent a collection in the photo library, i.e. an album or smart album. “Moments” (photos that are automatically grouped by date/location) are also represented asAssetCollection
objects.You cannot initialize an
AssetCollection
directly. Instead, use theget_albums()
,get_smart_albums()
, andget_moments()
functions to fetch collections from the photo library. You can also access some special smart albums conveniently, for example viaget_screenshots_album()
,get_recently_added_album()
, orget_selfies_album()
.To create a new album in the photo library, use the
create_album()
function. You can then add assets to it usingAssetCollection.add_assets()
(or remove them usingAssetCollection.remove_assets()
).
AssetCollection Methods#
- AssetCollection.delete()#
Delete the asset collection from the photo library. The contained assets are not deleted.
If the asset collection is not deletable, an IOError will be raised. You can check if an asset collection is deletable using the
AssetCollection.can_delete
attribute.
- AssetCollection.add_assets(assets)#
Add a list of
Asset
objects to the album represented by this object.Not all asset collections allow adding assets. You can check this using the
AssetCollection.can_add_assets
attribute.
- AssetCollection.remove_assets(assets)#
Remove a list of
Asset
objects from the album represented by this object.Not all asset collections allow removing assets. You can check this using the
AssetCollection.can_remove_assets
attribute.
AssetCollection Properties#
- AssetCollection.assets#
(read-only, list of
Asset
objects) The assets that the collection contains. Note that modifying the list directly has no effect on the collection in the photo library. UseAssetCollection.add_assets()
andAssetCollection.remove_assets()
to add or remove assets.
- AssetCollection.local_id#
(read-only, string) A unique identifier of this asset collection on the current device.
- AssetCollection.title#
(read-write, string) The (potentially localized) title of the asset collection. Only writable if
AssetCollection.can_rename
is True.
- AssetCollection.type#
(read-only, string) The type of the asset collection (
'album'
,'smart_album'
or'moment'
).
- AssetCollection.subtype#
(read-only, string) The subtype of the asset collection (e.g.
'favorites'
,'recently_added'
…).
- AssetCollection.start_date#
(read-only, datetime) The earliest creation date among all assets in the asset collection.
- AssetCollection.end_date#
(read-only, datetime) The latest creation date among all assets in the asset collection.
- AssetCollection.can_delete#
(read-only, boolean) Whether the asset collection can be deleted.
- AssetCollection.can_add_assets#
(read-only, boolean) Whether the asset collection allows adding assets using
AssetCollection.add_assets()
.
- AssetCollection.can_remove_assets#
(read-only, boolean) Whether the asset collection allows adding assets using
AssetCollection.remove_assets()
.
Deprecated Functions#
The following functions are still available for backwards compatibility, but using them in new code is not recommended.
get_count()
– Return the number of images in the camera roll.get_image(image_index=-1, original=True, raw_data=False)
– Return one of the images in the camera roll. Useget_assets()
instead.get_metadata(image_index=-1)
– Return EXIF and other metadata of an image in the camera roll as a dictionary. Use the metadata properties ofAsset
instead.get_thumbnail(image_index=-1)
– Return a small thumbnail image of an image in the camera roll. The thumbnail will have equal width and height, regardless of the aspect ratio of the original image. UseAsset.get_ui_image()
instead.pick_image(show_albums=False, include_metadata=False, original=True, raw_data=False, multi=False)
– Show a standard image picker UI and return the image that was picked. Usepick_asset()
instead.save_image(image)
– Save aPIL
image orui.Image
to the camera roll. Usecreate_image_asset()
instead.