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.


    UI gaussian blur

    Pythonista
    6
    17
    9209
    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.
    • Phuket2
      Phuket2 @omz last edited by

      @omz , ok thanks.
      Should it work if you already have a custom class that inherits from ui.View, then you change it to inherit from BlurView instead

      1 Reply Last reply Reply Quote 1
      • omz
        omz last edited by

        @Phuket2 Should be possible, but you must make sure to call BlurView.__init__ in your custom subclass.

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

          @omz I have been playing around with UIBlurView and UIVibrancyEffect, but have not been able to get the UIVibrancyEffect to work (text does not show up). Any suggestions on how to get it to work? I'm away from my iPad right now and can post some code later, if needed. But, my code is based on the following Objective-C code:

          // Blur effect
          UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
          UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
          [blurEffectView setFrame:self.view.bounds];
          [self.view addSubview:blurEffectView];
          
          // Vibrancy effect
          UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];
          UIVisualEffectView *vibrancyEffectView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect];
          [vibrancyEffectView setFrame:self.view.bounds];
          
          // Label for vibrant text
          UILabel *vibrantLabel = [[UILabel alloc] init];
          [vibrantLabel setText:@"Vibrant"];
          [vibrantLabel setFont:[UIFont systemFontOfSize:72.0f]];
          [vibrantLabel sizeToFit];
          [vibrantLabel setCenter: self.view.center];
          
          // Add label to the vibrancy view
          [[vibrancyEffectView contentView] addSubview:vibrantLabel];
          
          // Add the vibrancy view to the blur view
          [[blurEffectView contentView] addSubview:vibrancyEffectView];
          

          Thanks,
          B

          1 Reply Last reply Reply Quote 1
          • omz
            omz last edited by

            @blmacbeth Here's an extended version of BlurView that includes support for vibrancy effects. The main function shows a little demo.

            # coding: utf-8
            
            import ui
            from objc_util import *
            
            class BlurView (ui.View):
            	def __init__(self, style=1, *args, **kwargs):
            		ui.View.__init__(self, **kwargs)
            		self._style = style
            		self.effect_view = None
            		self.setup_effect_view()
            	
            	@on_main_thread
            	def setup_effect_view(self):
            		if self.effect_view is not None:
            			self.effect_view.removeFromSuperview()
            		UIVisualEffectView = ObjCClass('UIVisualEffectView')
            		UIVibrancyEffect = ObjCClass('UIVibrancyEffect')
            		UIBlurEffect = ObjCClass('UIBlurEffect')
            		UILabel = ObjCClass('UILabel')
            		frame = (self.bounds[:2], self.bounds[2:])
            		self.effect_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease()
            		effect = UIBlurEffect.effectWithStyle_(self._style)
            		self.effect_view.effect = effect
            		self.effect_view.setAutoresizingMask_(18)
            		ObjCInstance(self).addSubview_(self.effect_view)
            		vibrancy_effect = UIVibrancyEffect.effectForBlurEffect_(effect)
            		self.vibrancy_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease()
            		self.vibrancy_view.effect = vibrancy_effect
            		self.effect_view.contentView().addSubview_(self.vibrancy_view)
            		
            	@property
            	def style(self):
            		return self._style
            	
            	@style.setter
            	def style(self, value):
            		if value != self._style:
            			self._style = value
            			self.setup_effect_view()
            	
            	@on_main_thread
            	def add_vibrant_label(self, label):
            		self.vibrancy_view.contentView().addSubview_(ObjCInstance(label))
            
            def main():
            	image_view = ui.ImageView(frame=(0, 0, 320, 320))
            	image_view.image = ui.Image.named('test:Mandrill')
            	blur_view = BlurView(style=2, frame=image_view.bounds.inset(40, 40))
            	image_view.add_subview(blur_view)
            	label = ui.Label(frame=blur_view.bounds)
            	label.text = 'Hello World'
            	label.font = ('HelveticaNeue', 40)
            	label.alignment = ui.ALIGN_CENTER
            	blur_view.add_vibrant_label(label)
            	image_view.present('sheet')
            
            main()
            
            1 Reply Last reply Reply Quote 2
            • blmacbeth
              blmacbeth last edited by

              @omz You're the man! Thanks for that.

              1 Reply Last reply Reply Quote 1
              • blmacbeth
                blmacbeth last edited by

                Noticed some bugs in the above code, so here are my fixes to make it work (in Pythonista3, at least).

                # coding: utf-8
                
                import ui
                from objc_util import *
                
                class BlurView (ui.View):
                    def __init__(self, style=1, *args, **kwargs):
                        ui.View.__init__(self, **kwargs)
                        self._style = style
                        self.effect_view = None
                        self.setup_effect_view()
                    
                    @on_main_thread
                    def setup_effect_view(self):
                        if self.effect_view is not None:
                            self.effect_view.removeFromSuperview()
                        UIVisualEffectView = ObjCClass('UIVisualEffectView')
                        UIVibrancyEffect = ObjCClass('UIVibrancyEffect')
                        UIBlurEffect = ObjCClass('UIBlurEffect')
                        UILabel = ObjCClass('UILabel')
                        # Brooks patch for Rect not having a 'slice' 
                        bounds = self.bounds.as_tuple()
                        frame = (bounds[:2], bounds[2:])
                        self.effect_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease()
                        effect = UIBlurEffect.effectWithStyle_(self._style)
                        self.effect_view.effect = effect
                        self.effect_view.setAutoresizingMask_(18)
                        ObjCInstance(self).addSubview_(self.effect_view)
                        vibrancy_effect = UIVibrancyEffect.effectForBlurEffect_(effect)
                        self.vibrancy_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease()
                        self.vibrancy_view.effect = vibrancy_effect
                        self.effect_view.contentView().addSubview_(self.vibrancy_view)
                        
                    @property
                    def style(self):
                        return self._style
                    
                    @style.setter
                    def style(self, value):
                        if value != self._style:
                            self._style = value
                            self.setup_effect_view()
                    
                    # Brooks fix @on_mains_thread to @on_main_thread
                    @on_main_thread
                    def add_vibrant_label(self, label):
                        self.vibrancy_view.contentView().addSubview_(ObjCInstance(label))
                
                def main():
                    image_view = ui.ImageView(frame=(0, 0, 320, 320))
                    image_view.image = ui.Image.named('test:Mandrill')
                    blur_view = BlurView(style=2, frame=image_view.bounds.inset(40, 40))
                    image_view.add_subview(blur_view)
                    label = ui.Label(frame=blur_view.bounds)
                    label.text = 'Hello World'
                    label.font = ('HelveticaNeue', 40)
                    label.alignment = ui.ALIGN_CENTER
                    blur_view.add_vibrant_label(label)
                    image_view.present('sheet')
                
                main()
                

                The biggest problem was that the ui.Rect() object does not have the ability to use slices. This was fixed with the ui.Rect().as_tuple() function. The second problem was just a typo.

                B

                1 Reply Last reply Reply Quote 1
                • rb
                  rb last edited by

                  How could you apply the vibrancy effect to work with a rectangular region rather than a label? I read there is a fill method and a separator method but not sure how you would implement.

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

                    @rb What do you call a rectangular region? A label could be seen as a rectangular region if you don't set its text.

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

                      Ah ok - so what is the difference then between fill and label?I just thought label would be isolated to text - but it I’ll try that!

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

                        @rb the blur_view it-self is a rectangular region, thus no need of label at all

                        def main():
                            image_view = ui.ImageView(frame=(0, 0, 320, 320))
                            image_view.image = ui.Image.named('test:Mandrill')
                            blur_view = BlurView(style=16, frame=image_view.bounds.inset(40, 40))
                            image_view.add_subview(blur_view)
                            #label = ui.Label(frame=blur_view.bounds)
                            #label.text = 'Hello World'
                            #label.font = ('HelveticaNeue', 40)
                            #label.alignment = ui.ALIGN_CENTER
                            #blur_view.add_vibrant_label(label)
                            image_view.present('sheet')
                        
                        1 Reply Last reply Reply Quote 0
                        • rb
                          rb last edited by

                          No I mentioned vibrancy- ie I want bg to be blurred but a central rectangle to be not blurred and more vibrant.

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

                            @rb ok, sorry, misunderstood

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post
                            Powered by NodeBB Forums | Contributors