omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Photos Module - Start Camera from Button

    Pythonista
    4
    26
    21410
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • cvp
      cvp last edited by

      I launch, I see the camera screen, I press the camera button, I hear a click, I press the "use photo" and the script saves the photo

      1 Reply Last reply Reply Quote 0
      • simple
        simple last edited by

        But that's not how the code should work, or did I understand that wrong (explained it wrong)?

        It should first show the ui.view sheet with a button called 'Take Photo'. Then you press that button and the camera launches and then you take the photo.

        cvp 1 Reply Last reply Reply Quote 0
        • JonB
          JonB last edited by

          The posted code worked for me, but one thing you could try in cases like this is to add a ui.delay with a long enough delay to let the camera view fully dismiss.

             # Take Photo Action
              @ui.in_background
              def take_photo_action(self, sender):
                  image = photos.capture_image()
                  def a():
                     photos.save_image(image)
                     self.close()
                  ui.delay(a,.5)
          
          1 Reply Last reply Reply Quote 0
          • cvp
            cvp @simple last edited by

            @simple sorry, I forgot to say that I see first the ui with the "take photo" button and of course I press it.

            1 Reply Last reply Reply Quote 0
            • cvp
              cvp last edited by

              To see the ui sheof t with your "take photo" button, you have first to present the view.

              1 Reply Last reply Reply Quote 0
              • simple
                simple last edited by simple

                If you first see the UI button the code works as it should.

                On my iPhones if I launch the script the camera opens immediately and I don't see the ui.view sheet.

                (Edit: I've been mistaken, I do see the ui.view sheet with the button.. I thought that the black ui.view was the camera and not the ui.view. Still, if I press the button the application crashes.)

                1 Reply Last reply Reply Quote 0
                • cvp
                  cvp last edited by

                  When you say crash, you mind terminate?
                  If I go in the settings set that Pythonista can't use camera, I also have this abnormal end.
                  If I reset on in the settings, I need to remove the app from active tasks to let the script function.

                  1 Reply Last reply Reply Quote 0
                  • simple
                    simple last edited by simple

                    Ok, I got it working.

                    I've reduced the code to a minimum and checked what happens. With this, Pythonista freezes, I have to remove it from the iOS switch and restart the application.

                    import ui
                    import photos
                    
                    class Extracter(ui.View):
                        def __init__(self):
                            print('Executed')
                            photos.capture_image()
                            
                    if __name__=='__main__':
                        view = Extracter()
                    

                    After that I tried to put the photo.capture_image() out of the class, that worked before and still does but is not what I want.

                    import ui
                    import photos
                    
                    photos.capture_image()
                    
                    class Extracter(ui.View):
                        def __init__(self):
                            print('Executed')
                            
                    if __name__=='__main__':
                        view = Extracter()
                    

                    Now after your post @cvp I've double checked that Pythonista has camera permissions. I've disabled it and run the first script, and the camera launched (!) but without a picture. I went back to settings and enabled it again, and now it works.

                    I've tested that on the second iPhone. If you run the script it freezes as before, disable and enable camera permissions again, and it works.

                    1 Reply Last reply Reply Quote 0
                    • cvp
                      cvp last edited by

                      Eureka!!!

                      1 Reply Last reply Reply Quote 0
                      • simple
                        simple last edited by

                        I've now tested a few code snippets and there still seems to be a problem.

                        The same script launched several times sometimes activates the camera and sometimes not. If I got back to the button activated camera it doesn't work no matter what I do.

                        1 Reply Last reply Reply Quote 0
                        • cvp
                          cvp last edited by

                          Sorry, I don't think I could help more.

                          1 Reply Last reply Reply Quote 0
                          • cvp
                            cvp last edited by

                            You could try this code, using objective c to start the camera but it is not yet finished.
                            The code to get the captured picture needs to use delegate methods and is not yet written.
                            It's a little bit too complex for me and I would need some time...
                            But try it, only to see if executing the script several times also generate a crash or not.

                            import ui
                            import console
                            import clipboard
                            from objc_util import *
                            import photos
                            
                            SUIViewController = ObjCClass('SUIViewController')
                            
                            class Extracter(ui.View):
                            	def __init__(self):
                            
                            		# Some UI Elements 
                            		#(...)
                            
                            		# Take Photo Button
                            		self.take_photo = ui.Button(flex = 'LR', title = 'Take Photo')
                            		self.take_photo.action = self.take_photo_action
                            		# Some Button Styles
                            		#(...)
                            		self.add_subview(self.take_photo)
                            
                            	# Take Photo Action
                            	@ui.in_background
                            	def take_photo_action(self, sender):
                            		
                            		# Show camera
                            		picker = ObjCClass('UIImagePickerController').alloc().init()
                            		picker.mame = 'picker'
                            		picker.delegate = self
                            		picker.allowsEditing = False
                            		picker.sourceType = 1 # UIImagePickerControllerSourceTypeCamera
                            		super_view = sender.superview
                            		super_view_pntr = ObjCInstance(super_view)
                            		vc = SUIViewController.viewControllerForView_(super_view_pntr)
                            		vc.presentModalViewController_animated_(picker, True)
                            
                            		# To get the captured photo, we need to work with delegates
                            		# not yet developped
                            
                            		
                            if __name__=='__main__':
                            	view = Extracter()
                            	view.present('sheet')
                            
                            
                            1 Reply Last reply Reply Quote 0
                            • cvp
                              cvp last edited by

                              One step more: delegate written but I'm still lost in converting the UIImage into an image...
                              The photo is taken, the photo is "used" and sent to the script via the delegate function, see the console printing, ...but img not yet available for Python code, I've not yet found why.

                              import ui
                              import console
                              import clipboard
                              from objc_util import *
                              
                              
                              def imagePickerController_didFinishPickingMediaWithInfo_(self,cmd,picker,info):
                              
                              	pick = ObjCInstance(picker)
                              	# Set delegate to nil, and release its memory:
                              	pick.setDelegate_(None)
                              	ObjCInstance(self).release()
                              	# Dismiss the sheet:
                              	pick.dismissViewControllerAnimated_completion_(True, None)
                              	
                              	infos = ObjCInstance(info)
                              	print(infos)
                              	img = infos['UIImagePickerControllerEditedImage']	# UIImage 
                              	#img = infos['UIImagePickerControllerOriginalImage']
                              	print(img)
                              
                              	#img.show()
                              	#photos.save_image(img)
                              	
                              SUIViewController = ObjCClass('SUIViewController')
                              
                              MyPickerDelegate = create_objc_class('MyPickerDelegate',
                              methods=[imagePickerController_didFinishPickingMediaWithInfo_], protocols=['UIImagePickerControllerDelegate'])
                              
                              class Extracter(ui.View):
                              	def __init__(self):
                              
                              		# Take Photo Button
                              		self.take_photo = ui.Button(flex = 'LR', title = 'Take Photo')
                              		self.take_photo.action = self.take_photo_action
                              		self.add_subview(self.take_photo)
                              
                              	# Take Photo Action
                              	#@ui.in_background
                              	@on_main_thread
                              	def take_photo_action(self, sender):
                              		
                              		# Show camera
                              		picker = ObjCClass('UIImagePickerController').alloc().init()
                              		
                              		delegate = MyPickerDelegate.alloc().init()
                              		picker.setDelegate_(delegate)
                              		
                              		picker.allowsEditing = True
                              		picker.sourceType = 1 # UIImagePickerControllerSourceTypeCamera
                              		super_view = sender.superview
                              		super_view_pntr = ObjCInstance(super_view)
                              		vc = SUIViewController.viewControllerForView_(super_view_pntr)
                              		vc.presentModalViewController_animated_(picker, True)
                              	
                              # Protect against import	
                              if __name__ == '__main__':
                              	view = Extracter()
                              	view.present('sheet')
                              
                              1 Reply Last reply Reply Quote 0
                              • simple
                                simple last edited by

                                Thanks for all the help, I am glad there are people like you out there! I will see if your code works, but I assume there is a problem with Pythonista on iOS on certain devices. I've send a friend of mine the file and he was able to run it on his iPad, but on his iPhone (iPhone 6 on iOS 9.3.3) it crashed the application.

                                I will backup all Pythonista modules and scripts installed, remove and reinstall the application fresh, to see if something else causes the crash.

                                1 Reply Last reply Reply Quote 0
                                • cvp
                                  cvp last edited by

                                  Ok, good luck

                                  1 Reply Last reply Reply Quote 0
                                  • cvp
                                    cvp last edited by

                                    Last try
                                    I have not been able to convert an Objective-C UIImage into a Pythonista ui.Image/PIL image, thus I did find this way through a lot of searches, not very nice but it functions and will allow you to test this "start camera - take photo - get image - display image" without using photos module, this perhaps could function on your iPhone 6 and, in this case, it could perhaps help @omz to debug the photos.capture which crashes on your device.
                                    Anyway, I did learn a lot on objective-c, thus I didn't loose my time (I'm retired, thus I've a lot of free time) and I definitely love this app!

                                    import ui
                                    import console
                                    import clipboard
                                    from objc_util import *
                                    import ctypes
                                    from PIL import Image
                                    
                                    
                                    def imagePickerController_didFinishPickingMediaWithInfo_(self,cmd,picker,info):
                                    
                                    	pick = ObjCInstance(picker)
                                    	# Set delegate to nil, and release its memory:
                                    	pick.setDelegate_(None)
                                    	ObjCInstance(self).release()
                                    	# Dismiss the sheet:
                                    	pick.dismissViewControllerAnimated_completion_(True, None)
                                    	
                                    	# Get UIImage
                                    	infos = ObjCInstance(info)
                                    	print(infos)
                                    	img = infos['UIImagePickerControllerEditedImage']	# UIImage 
                                    	# or
                                    	#img = infos['UIImagePickerControllerOriginalImage']
                                    	print(img)
                                    	print(img.ptr)
                                    	
                                    	# I can't convert UIImage into ui.Image 🤕
                                    	
                                    	# Save UIImage to jpg file
                                    	func = c.UIImageJPEGRepresentation
                                    	func.argtypes = [ctypes.c_void_p, ctypes.c_float]
                                    	func.restype = ctypes.c_void_p
                                    	x = ObjCInstance(func(img.ptr, 1.0))
                                    	x.writeToFile_atomically_('test.jpg', True)
                                    
                                    	# Display jpg file
                                    	image = Image.open("test.jpg")
                                    	image.show()
                                    	
                                    SUIViewController = ObjCClass('SUIViewController')
                                    
                                    MyPickerDelegate = create_objc_class('MyPickerDelegate',
                                    methods=[imagePickerController_didFinishPickingMediaWithInfo_], protocols=['UIImagePickerControllerDelegate'])
                                    
                                    class Extracter(ui.View):
                                    	def __init__(self):
                                    
                                    		# Take Photo Button
                                    		self.take_photo = ui.Button(flex = 'LR', title = 'Take Photo')
                                    		self.take_photo.action = self.take_photo_action
                                    		self.add_subview(self.take_photo)
                                    
                                    	# Take Photo Action
                                    	#@ui.in_background
                                    	@on_main_thread
                                    	def take_photo_action(self, sender):
                                    		
                                    		# Show camera
                                    		picker = ObjCClass('UIImagePickerController').alloc().init()
                                    		
                                    		delegate = MyPickerDelegate.alloc().init()
                                    		picker.setDelegate_(delegate)
                                    		
                                    		picker.allowsEditing = True
                                    		picker.sourceType = 1 # UIImagePickerControllerSourceTypeCamera
                                    		super_view = sender.superview
                                    		super_view_pntr = ObjCInstance(super_view)
                                    		vc = SUIViewController.viewControllerForView_(super_view_pntr)
                                    		vc.presentModalViewController_animated_(picker, True)
                                    	
                                    # Protect against import	
                                    if __name__ == '__main__':
                                    	view = Extracter()
                                    	view.present('sheet')
                                    
                                    1 Reply Last reply Reply Quote 1
                                    • First post
                                      Last post
                                    Powered by NodeBB Forums | Contributors