Photos module
@resserone13 create a photo in camera roll via
import photos
import os
pil_image = photos.capture_image() # returns a PIL Image
path = 'new.jpg'
pil_image.save(path, format='JPEG')
photos.create_image_asset(path)
os.remove(path)
Photos module
@ccc when I take a pic with the capture_image() how do I name it so I can pass it to create_image_asset() then send it via a mime email.
Photos module
Can some demonstrate all the methods and function of the photos module? I'm have trouble using create_image_asset(). I want to take a photo and save it to a perticular album. After that I want the photo sent via email and then deleted for the album.
Containers for photos, with scroll, drag&drop between them
@cvp just to let you know here is my code.
It wont run because the rest of the code is missing, but it gives you the idea
def save(self):
# make a hi resolution copy of back & images, then save it in camera roll
xo, yo, w, h = self.page.back.frame
c = self.page.back.background_color
targetWidth = 4*1024
s = targetWidth / w
w, h = w*s, h*s
page = ui.View( frame=(0,0,w,h), background_color=c)
views = []
for thumb in self.thumbs:
x,y,w,h = thumb.frame
x,y,w,h = (x-xo)*s, (y-yo)*s, w*s, h*s
v = ui.View( frame=(x,y,w,h) )
x,y,w,h = thumb.iv.frame
x,y,w,h = x*s, y*s, w*s, h*s
img = thumb.getImage(thumb.asset)
iv = ui.ImageView(frame=(x,y,w,h), image=img)
v.add_subview(iv)
page.add_subview(v)
views.append(v)
# save page image in pythonista
getTopView().add_subview(page)
#page.bring_to_front()
#if True: return
path = 'temp.jpg'
with ui.ImageContext(page.width, page.height) as ctx:
page.draw_snapshot()
ui_image = ctx.get_image()
pil = Image.open(io.BytesIO(ui_image.to_png()))
pil.save(path , quality=99)
# save page image in albums
asset = photos.create_image_asset(path)
os.remove(path)
getTopView().remove_subview(page)
views = False
console.hud_alert('saved')
looks like i must add the view to the screen to get the draw snapshot to work.
using appex to modify a photo creation date directly
@average install piexif.py
from here
and try this script
from datetime import datetime
import dialogs
from objc_util import ObjCInstance
import os
import photos
import piexif # https://github.com/hMatoba/Piexif/tree/master/piexif
def exif_as_str(exif_val):
exif_str = str(exif_val)
if len(exif_str) >= 3:
if exif_str[:2] == "b'" and exif_str[-1] == "'":
exif_str = exif_str[2:-1]
return exif_str
def main():
# select photo
asset = photos.pick_asset()
# get its path
path = str(ObjCInstance(asset).pathForOriginalFile())
#print(path)
# get photo exifs
exif_info = piexif.load(path)
exif_str = exif_as_str(exif_info['Exif'][piexif.ExifIFD.DateTimeOriginal])
#print('photo taken date/time',exif_str)
# get new taken date-time
new_date = dialogs.datetime_dialog(title=str(exif_str))
dt_str = datetime.strftime(new_date,'%Y:%m:%d %H:%M:%S')
# update exif of taken datetime
exif_info['Exif'][piexif.ExifIFD.DateTimeOriginal] = dt_str
exif_str = exif_as_str(exif_info['Exif'][piexif.ExifIFD.DateTimeOriginal])
#print('modified photo taken date/time',exif_str)
# create new photo with modified taken date-time
exif_bytes = piexif.dump(exif_info)
new_path = 'temp.jpg'
piexif.insert(exif_bytes,path,new_file=new_path)
photos.create_image_asset(new_path)
os.remove(new_path)
#--- protect for import
if __name__ == '__main__':
main()
If any error, please forgive me and don't forget I'm in holidays In Bourgogne (🍷=>bugs)
Pythonista crashes trying to save merged photo
@jm2466 this
# 1) convert PIL Image to ui.Image
console.hud_alert('convert PIL Image into ui.Image')
with io.BytesIO() as bIO:
new_im.save(bIO, 'PNG')
ui_image = ui.Image.from_data(bIO.getvalue())
del bIO
# 2) Create a PHAsset from an ui.Image (not from a PIL Image)
console.hud_alert('Create a PHAsset from an ui.Image')
lib = PHPhotoLibrary.sharedPhotoLibrary()
def change_block():
req = PHAssetChangeRequest.creationRequestForAssetFromImage_(ui_image)
def perform_changes():
lib.performChangesAndWait_error_(change_block, None)
t = threading.Thread(target=perform_changes)
t.start()
t.join()
is about (😀) 1000 x slower than
path = 'temp.jpg'
new_im.save(path , quality=95)
photos.create_image_asset(path)
os.remove(path)
Pythonista crashes trying to save merged photo
@jm2466 I'm in holiday, thus perhaps not able to correctly understand all (🍷🍷) but why did you not use
photos.create_image_asset(path)
instead of
photos.save_image(Image.open(path))
Pythonista crashes trying to save merged photo
@jm2466 the problem comes (I guess) from 'too much memory' in appex mode.
Try this script in normal mode and see also how we have to save a new photo now (no more photos.save_image, at least in the help of the beta)
Obviously, like @ccc adviced, you could delete each image as soon it has been pasted.
import appex
import console
from PIL import Image
from PIL.ExifTags import TAGS
import photos
import os
import ui
# standard get exif code - needed for image size
def get_exif(fn):
ret = {}
i = Image.open(fn)
info = i._getexif()
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
return ret
class MyView(ui.View):
def __init__(self):
self.frame = (0,0,500,500)
if not appex.is_running_extension():
assets = photos.get_assets()
assets = photos.pick_asset(assets=assets,multi=True)
images = []
for asset in assets:
images.append(asset.get_image())
else:
images = appex.get_images(image_type='pil')
print(f'len(images) = {len(images)})')
#console.hud_alert(str(len(images)))
# get the widths/heights of the images
widths, heights = zip(*(i.size for i in images))
# this is stacking vertically so the width is the max width of all the pics
max_width = max(widths)
# since stacking vertically the height is the total heights of the pics
total_height = sum(heights)
print(f'total height = {total_height}')
#console.hud_alert(str(total_height))
print(f'max width = {max_width}')
#console.hud_alert(str(max_width))
# create a new blank image in the required size
console.hud_alert(str(4*max_width*total_height))
#return
new_im = Image.new('RGBA', (max_width, total_height))
print(f'new_im.size = {new_im.size}')
console.hud_alert(str(new_im.size))
# now assemble the merged pic
# y_offset controls the pixel location of where each image is added
# to the new image - to add each end-to-end
# starting at the top which is y = 0
y_offset = 0
# loop through all passed images
for im in images:
# paste in the image at the left edge (x=0) and current offset for y
new_im.paste(im, (0,y_offset))
print(f'y_offset = {y_offset}')
console.hud_alert(str(y_offset))
# increase the offset by the height of current pic
y_offset += im.size[1]
# save the new image to the camera roll
new_im.show()
#photos.save_image(new_im)
path = 'temp.jpg'
new_im.save(path , quality=95)
photos.create_image_asset(path)
os.remove(path)
def main():
v = MyView()
v.present('sheet')
if __name__ == '__main__':
main()
Create and save Live Photo to Camera Roll
@riePat I have downloaded an heic.mov from an iPhone 6s and imported In Pythonista.
I have copied it to camera roll via FileBrowser and the .mov is visible in Photos app.
But you are right this does not work...
photos.create_image_asset('iphone6s_4k.mov')
But I suppose that if FileBrowser can do it, there is a way...