def main(): console.clear() #p = photos.pick_image(show_albums=True, include_metadata=True, original=True, raw_data=False, multi=True) # Build dictionary filename: index fn_index = {} for ip in range(photos.get_count()): m = photos.get_metadata(ip) #print m fn = m.get('filename') fn_index[fn] = (ip, '') # - type = 1: album # - subtype = 2: regular album result = PHAssetCollection.fetchAssetCollectionsWithType_subtype_options_( 1, 2, None) #print result for i in range(result.count()): coll = result.objectAtIndex_(i) album = str(coll.localizedTitle()) assets = PHAsset.fetchAssetsInAssetCollection_options_(coll, None) for j in range(assets.count()): a = assets.objectAtIndex_(j) fn = str(a.valueForKey_('filename')) tuple = fn_index[fn] ip = tuple[0] fn_index[fn] = (ip, album) # print filename -> album,index print(fn_index)
def __init__(self, width, height): self.frame = (0, 0, width, height) self.iwidth = 200.0 self.iheight = 150.0 framesize = 5 iw = self.iwidth - 2 * framesize ih = self.iheight - 2 * framesize ratio = ih / iw self.img = [] self.imgcount = photos.get_count() if self.imgcount < 100: console.hud_alert( 'Please wait while {} photos are loading...'.format( self.imgcount)) else: console.hud_alert('Please wait while 100 photos are loading...') self.imgcount = 100 for i in range(self.imgcount): img = ui.Image.from_data(photos.get_image(i, raw_data=True)) w, h = img.size rat = h / w x_ratio = 1.0 y_ratio = 1.0 x = framesize y = framesize if rat > ratio: #portrait x = ((iw - ih * rat) / 2) + framesize x_ratio = ih * rat / iw else: #landscape y = ((ih - iw * rat) / 2) + framesize y_ratio = iw * rat / ih with ui.ImageContext(self.iwidth, self.iheight) as ctx: img.draw(x, y, iw * x_ratio, ih * y_ratio) self.img.append(ctx.get_image())
def main(): console.clear() #p = photos.pick_image(show_albums=True, include_metadata=True, original=True, raw_data=False, multi=True) # Build dictionary filename: index fn_index = {} for ip in range(photos.get_count()): m = photos.get_metadata(ip) #print m fn = m.get('filename') fn_index[fn] = (ip,'') # - type = 1: album # - subtype = 2: regular album result = PHAssetCollection.fetchAssetCollectionsWithType_subtype_options_(1,2, None) #print result for i in range(result.count()): coll = result.objectAtIndex_(i) album = str(coll.localizedTitle()) assets = PHAsset.fetchAssetsInAssetCollection_options_(coll, None) for j in range(assets.count()): a = assets.objectAtIndex_(j) fn = str(a.valueForKey_('filename')) tuple = fn_index[fn] ip = tuple[0] fn_index[fn] = (ip,album) # print filename -> album,index print fn_index
def main(): if not photos.get_count(): print('Sorry no access or no pictures.') return image = photos.pick_image() if not image: print('No image selected. Good bye!') return resize = False quality = 95 width, height = image.size megapixels = round(width * height / 1000000.0, 1) image_mode = image.mode print(pic_info_menu_fmt.format(**{ 'width' : width, 'height' : height, 'megapixels' : megapixels, 'image_mode' : image_mode })) option = int(raw_input('Resolution: ')) if option not in (0, 1, 2, 3, 5): print('Cancel: {} is not valid input.'.format(option)) return if option == 0: quality /= 100.0 elif option == 1: image_mode, quality = pic_para(image_mode) elif option == 2: print('\nChanging the ratio causes picture deformation!') width2 = int(raw_input('Width: ')) ratio = width / (height * 1.0) suggestion = width2 / ratio height2 = int(raw_input('Height [Enter = {:.0f}]:'.format(suggestion)) or suggestion) if (width2 == width and height2 == height): resize = False else: resize = True width = width2 height = height2 image_mode, quality = pic_para(image_mode) elif option == 3: resolution3megapixel = (2048, 1536) resize = not (width in resolution3megapixel and height in resolution3megapixel) if resize: if width >= height: # Landscape or Square width, height = resolution3megapixel # Landscape else: height, width = resolution3megapixel # Portrait image_mode, quality = pic_para(image_mode) elif option == 5: resolution5megapixel = (2592, 1936) resize = not (width in resolution5megapixel and height in resolution5megapixel) if resize: if width >= height: # Landscape or Square width, height = resolution5megapixel # Landscape else: height, width = resolution5megapixel # Portrait image_mode, quality = pic_para(image_mode) pic_save(image, image_mode, width, height, quality, resize)
def __init__(self, width, height): self.frame = (0, 0, width, height) self.iwidth = 200.0 self.iheight = 200.0 framesize = 10 iw = self.iwidth - 2 * framesize ih = self.iheight - 2 * framesize ratio = ih / iw self.img = [] self.imgcount = min(photos.get_count(), 100) console.hud_alert( "Please wait while {} photos are loading...".format(self.imgcount) ) for i in range(self.imgcount): s = photos.get_metadata(i) if s["filename"][-3:] == "MOV": # skip movies self.img.append(None) continue img = ui.Image.from_data(photos.get_image(i, raw_data=True)) w, h = img.size rat = h / w x_ratio = 1.0 y_ratio = 1.0 x = framesize y = framesize if ratio < 1: # landscape canvas if rat <= ratio: # full width y = ((ih - iw * rat) / 2) + framesize y_ratio = iw * rat / ih else: # full height x = ((iw - ih / rat) / 2) + framesize x_ratio = ih / rat / iw elif ratio > 1: # portrait canvas if rat > ratio: # full height x = ((iw - ih / rat) / 2) + framesize x_ratio = ih / rat / iw else: # full width y = ((ih - iw * rat) / 2) + framesize y_ratio = iw * rat / ih else: # cubic canvas if rat < 1: # full width y = ((ih - iw * rat) / 2) + framesize y_ratio = iw * rat / ih elif rat > 1: # full height x = ((iw - ih / rat) / 2) + framesize x_ratio = ih / rat / iw else: # cubic pass # x_ratio = y_ratio = 1.0 with ui.ImageContext(self.iwidth, self.iheight) as ctx: img.draw(x, y, iw * x_ratio, ih * y_ratio) self.img.append(ctx.get_image())
def select_photos(): console.clear() back = MyView(frame=(0, 0, 500, 500)) back.present('sheet') todels = photos.pick_image(include_metadata=True, original=True, raw_data=False, multi=True) # todels = list of tuples # [(image,metadata),(image,metadata),...] # Build dictionary filename: index fn_index = {} for ip in range(photos.get_count()): m = photos.get_metadata(ip) fn = m.get('filename') fn_index[fn] = ip # that could be a problem if two photos have the same filename, what happens if you download the same file (fi from Dropbox) more than once. # pick_image seems to display "camera roll" which seems to be all photos in sequence like # - type = 2: smartalbum # - subtype = 209: smartalbumlibrary result = PHAssetCollection.fetchAssetCollectionsWithType_subtype_options_( 2, 209, None) coll = result.firstObject() assets = PHAsset.fetchAssetsInAssetCollection_options_(coll, None) # create array of assets to be deleted a_del = [] for todel in todels: fn = todel[1].get('filename') ia = fn_index[fn] # file name -> index a = assets.objectAtIndex_(ia) resources = PHAssetResource.assetResourcesForAsset(a) filename = resources[0].originalFilename a_del.append(a) lib = PHPhotoLibrary.sharedPhotoLibrary() def change_block(): # standard delete will ask a confirmation by specifying the number of photos to be deleted but by showing only one req = PHAssetChangeRequest.deleteAssets_(a_del) def perform_changes(): lib.performChangesAndWait_error_(change_block, None) t = threading.Thread(target=perform_changes) t.start() t.join()
def __init__(self, width, height): self.frame = (0,0,width,height) self.iwidth = 200.0 self.iheight = 200.0 framesize = 10 iw = self.iwidth - 2 * framesize ih = self.iheight - 2 * framesize ratio = ih / iw self.img = [] self.imgcount = min(photos.get_count(), 100) console.hud_alert('Please wait while {} photos are loading...'.format(self.imgcount)) for i in xrange(self.imgcount): s = photos.get_metadata(i) if s['filename'][-3:] == 'MOV': #skip movies self.img.append(None) continue img = ui.Image.from_data(photos.get_image(i,raw_data=True)) w, h = img.size rat = h / w x_ratio = 1.0 y_ratio = 1.0 x = framesize y = framesize if ratio < 1: #landscape canvas if rat <= ratio: #full width y = ((ih - iw * rat) / 2) + framesize y_ratio = iw * rat / ih else: #full height x = ((iw - ih / rat) / 2) + framesize x_ratio = ih / rat / iw elif ratio > 1: #portrait canvas if rat > ratio: #full height x = ((iw - ih / rat) / 2) + framesize x_ratio = ih / rat / iw else: #full width y = ((ih - iw * rat) / 2) + framesize y_ratio = iw * rat / ih else: #cubic canvas if rat < 1: #full width y = ((ih - iw * rat) / 2) + framesize y_ratio = iw * rat / ih elif rat > 1: #full height x = ((iw - ih / rat) / 2) + framesize x_ratio = ih / rat / iw else: #cubic pass #x_ratio = y_ratio = 1.0 with ui.ImageContext(self.iwidth, self.iheight) as ctx: img.draw(x,y,iw * x_ratio,ih * y_ratio) self.img.append(ctx.get_image())
y = row * self.iheight self.img[i].draw(x, y, self.iwidth, self.iheight) i += 1 def layout(self): pass def touch_began(self, touch): pass class MiniPhotoView(ui.View): def __init__(self): self.view = ui.View(background_color='lightyellow') self.view.name = 'MiniPhotoView' scrollview1 = ui.ScrollView() scrollview1.name = 'scrollview1' scrollview1.flex = 'WH' scrollview1.content_size = (2000, 2000) self.view.add_subview(scrollview1) self.view.present('full_screen') self.sv1 = self.view['scrollview1'] width, height = self.sv1.content_size self.sv1.add_subview(MyPictureView(width, height)) if photos.get_count(): MiniPhotoView() else: print('Sorry no access or no pictures.')
import photos import scene class PhotoText(scene.Scene): def __init__(self): scene.Scene.__init__(self) self.img2 = photos.pick_image() self.img = self.img2.convert('RGBA') #fix for current scene.load_pil_image() if self.img: self.picsize = scene.Size(*self.img.size) scene.run(self) else: print('Good bye!') def setup(self): self.layer = scene.Layer(self.bounds) self.layer.image = scene.load_pil_image(self.img) self.add_layer(self.layer) def draw(self): scene.background(0,0,0) self.root_layer.update(self.dt) self.root_layer.draw() scene.fill(1,1,1) # watch+battery -> white background scene.rect(0, self.bounds.h, self.bounds.w, 20) # watch+battery if photos.get_count(): PhotoText() else: print('Sorry no access or no pictures.')
print '\nPhotos with no DateTimeOriginal tag in their metadata and will need categorizing manually:' print '\n'.join(no_exif) if no_resize: print '\nPhotos that did not get resized because either you chose not to resize, or they were smaller than the minumum size of 1600x1200:' print '\n'.join(no_resize) if no_gps: print '\nPhotos that did not get geo-tagged because there was no gps info in the photo\'s metadata:' print '\n'.join(no_gps) if __name__ == '__main__': console.clear() # Make sure photos are available... if photos.get_count() != 0: ''' Here we are picking photos from the camera roll which, in Pythonista, allows us access to extra media data in photo's metafile. Because raw data is set to true, the image is a string representing the image object, not the object itself. ''' choose = photos.pick_image(show_albums=True, multi=True, original=True, raw_data=True, include_metadata=True) else:
import photos, random, scene, sys photo_count = photos.get_count() fmt = '{} photos in your camera roll...' print(fmt.format(photo_count)) if not photo_count: sys.exit( 'Pythonista does not have access to the camera roll or the camera roll is empty.' ) def get_random_photo( ): # returns the name (a string) of a random photo from the camera role return scene.load_pil_image( photos.get_fullscreen_image(random.randint(0, photo_count))) class MyScene(scene.Scene): def __init__(self): scene.run(self) def setup(self): self.photo_layer = scene.Layer(self.bounds) self.add_layer(self.photo_layer) self.frame_count = 0 def draw(self): scene.background(0, 0, 0) self.root_layer.update(self.dt) self.root_layer.draw()
def get_img_index(filename): c = photos.get_count() for i in range(c): m = photos.get_metadata(i) if m.get('filename') == filename: return i
def select_photos(): console.clear() back = MyView(frame=(0, 0, 500, 500)) back.present('sheet') todels = photos.pick_image(include_metadata=True, original=True, raw_data=False, multi=True) # todels = list of tuples # [(image,metadata),(image,metadata),...] # Build dictionary filename: index fn_index = {} for ip in range(photos.get_count()): m = photos.get_metadata(ip) fn = m.get('filename') fn_index[fn] = ip # that could be a problem if two photos have the same filename, what happens if you download the same file (fi from Dropbox) more than once. # pick_image seems to display "camera roll" which seems to be all photos in sequence like # - type = 2: smartalbum # - subtype = 209: smartalbumlibrary result = PHAssetCollection.fetchAssetCollectionsWithType_subtype_options_( 2, 209, None) coll = result.firstObject() assets = PHAsset.fetchAssetsInAssetCollection_options_(coll, None) # create array of assets to be deleted a_del = []
def get_index(filename): c = photos.get_count() for i in range(c): m = photos.get_metadata(i) if m.get('filename') == filename: return i
def main(): if not photos.get_count(): print('Sorry no access or no pictures.') return image2 = photos.pick_image() image = image2.convert('RGBA') #fix for current scene.load_pil_image() if not image: print('No image selected. Good bye!') return resize = False quality = 95 width, height = image.size megapixels = round(width * height / 1000000.0, 1) image_mode = image.mode print(pic_info_menu_fmt.format(**{ 'width' : width, 'height' : height, 'megapixels' : megapixels, 'image_mode' : image_mode })) option = int(raw_input('Resolution: ')) if option not in (0, 1, 2, 3, 5): print('Cancel: {} is not valid input.'.format(option)) return if option == 0: quality /= 100.0 elif option == 1: image_mode, quality = pic_para(image_mode) elif option == 2: print('\nChanging the ratio causes picture deformation!') width2 = int(raw_input('Width: ')) ratio = width / (height * 1.0) suggestion = width2 / ratio height2 = int(raw_input('Height [Enter = {:.0f}]:'.format(suggestion)) or suggestion) if (width2 == width and height2 == height): resize = False else: resize = True width = width2 height = height2 image_mode, quality = pic_para(image_mode) elif option == 3: resolution3megapixel = (2048, 1536) resize = not (width in resolution3megapixel and height in resolution3megapixel) if resize: if width >= height: # Landscape or Square width, height = resolution3megapixel # Landscape else: height, width = resolution3megapixel # Portrait image_mode, quality = pic_para(image_mode) elif option == 5: resolution5megapixel = (2592, 1936) resize = not (width in resolution5megapixel and height in resolution5megapixel) if resize: if width >= height: # Landscape or Square width, height = resolution5megapixel # Landscape else: height, width = resolution5megapixel # Portrait image_mode, quality = pic_para(image_mode) pic_save(image, image_mode, width, height, quality, resize)
# coding: utf-8 # https://forum.omz-software.com/topic/2915/delete-photos-from-camera-roll/3 from objc_util import * import threading import photos NSBundle.bundleWithPath_('/System/Library/Frameworks/Photos.framework').load() PHAssetCollection = ObjCClass('PHAssetCollection') PHAsset = ObjCClass('PHAsset') PHPhotoLibrary = ObjCClass('PHPhotoLibrary') PHAssetChangeRequest = ObjCClass('PHAssetChangeRequest') if not photos.is_authorized(): # This shows the photo access permission dialog as a side-effect: photos.get_count() def delete_last_photo(): result = PHAssetCollection.fetchAssetCollectionsWithType_subtype_options_(2, 206, None) coll = result.firstObject() assets = PHAsset.fetchAssetsInAssetCollection_options_(coll, None) a = assets.lastObject() lib = PHPhotoLibrary.sharedPhotoLibrary() def change_block(): req = PHAssetChangeRequest.deleteAssets_([a]) def perform_changes(): lib.performChangesAndWait_error_(change_block, None) t = threading.Thread(target=perform_changes) t.start() t.join()
import photos, random, scene, sys photo_count = photos.get_count() fmt = '{} photos in your camera roll...' print(fmt.format(photo_count)) if not photo_count: sys.exit('Pythonista does not have access to the camera roll or the camera roll is empty.') def get_random_photo(): # returns the name (a string) of a random photo from the camera role return scene.load_pil_image(photos.get_fullscreen_image(random.randint(0, photo_count))) class MyScene(scene.Scene): def __init__(self): scene.run(self) def setup(self): self.photo_layer = scene.Layer(self.bounds) self.add_layer(self.photo_layer) self.frame_count = 0 def draw(self): scene.background(0, 0, 0) self.root_layer.update(self.dt) self.root_layer.draw() if not self.frame_count % 180: # once every three seconds if self.photo_layer.image: # unload old image to save RAM scene.unload_image(self.photo_layer.image) self.photo_layer.image = get_random_photo() self.frame_count += 1