sDrop in Python mode

edited April 2016 in Python Mode

Gist: https://gist.github.com/medecau/22cec5853a5f7285ee2f97363bca096c

It took me a bit to get sDrop to work in Python mode. I created this thread so others may take advantage of this.

Comments

  • edited April 2016

    Hi @medecau. The sDrop issue you had is exactly the same for OscP5 and others:
    https://forum.Processing.org/two/discussion/15995/receive-osc

    That is, in Python Mode callbacks from 3rd party libraries fail.
    In your case dropEvent(). For OscP5, it's oscEvent().

    As a workaround, we can define some listening subclass and define the target callback therein.
    Then invoke some method which adds an instance of that subclass as the library's listener.

    The Python Mode's developer has already patched fixes for such issue for many other libraries already.
    In such a way we don't need to create some listener subclass anymore.
    And we can finally go back to define the callback directly in our sketches.
    However, there are still many libraries w/o that patch such as sDrop & OscP5 and others.

    If you wish, you can request a patch for sDrop too going here:
    https://GitHub.com/jdf/Processing.py-Bugs/issues/157

    Anyways, I've tweaked your listening workaround in order to resize the canvas w/ the same dimensions as the loaded image. Check it out: :bz

    """
     ' sDrop Image Listening (v2.0.1)
     ' by  Medecau (2016-Apr-29)
     ' mod GoToLoop
     '
     ' Forum.Processing.org/two/discussion/16339/sdrop-in-python-mode
     ' Gist.GitHub.com/medecau/22cec5853a5f7285ee2f97363bca096c
    """
    
    add_library('Drop')
    
    def setup():
        size(500, 500)
        noLoop()
        background(int(random(0x1000000)))
    
        global img
        img = None
    
        SDrop(this).addDropListener(MyDropImageListener())
    
    
    def draw(): img and img.width == width and background(img)
    
    
    class MyDropImageListener(DropListener):
        @ staticmethod
        def dropEvent(d, DELAY=10, MAX_DELAY=tuple(range(150))):
            if not d.isImage(): return
    
            global img
            img = d.loadImage()
    
            for i in MAX_DELAY:
                if img.loaded: break
                delay(DELAY)
    
            if img.width > 4:
                frame.setSize(img.width, img.height)
                redraw()
    
  • Thanks for your reply @GoToLoop.

    My example code is extremely simple. Note that I didn't even bother resizing the image. Those things distract from the purpose of the example code and this post. To show how to get sDrop to work in Processing under Python mode.

    Hopefully users can get creative and add other tweaks after that.

    Regarding fixes and why things are the way they are I'd rather discuss those on a different thread. Ping me if interested.

  • edited April 2016

    My example code is extremely simple.

    My example is indeed more advanced. But many folks would be interested in how to fit the canvas to the image. That's why I've posted an alternative solution as well. :-\"

    Although your example is simple, yet it's got some redundancies like importing sDrop 2 times. Just add_library('Drop') is enough. ;;)

    You can also axe out global variable drop. It's only used within setup() after all.

    A bigger canvas and some centralization of the PImage would be gr8 too: O:-)
    set(width - img.width >> 1, height - img.height >> 1, img)

    Here's my 2nd attempt on it. Now keeping everything as simple as possible + centralization: :D

    add_library('Drop')
    
    img = None
    
    def setup():
        size(1200, 700)
        frameRate(1)
        SDrop(this).addDropListener(DropyListener())
    
    
    def draw():
        background(int(random(0x1000000)))
        img and set(width - img.width >> 1, height - img.height >> 1, img)
    
    
    class DropyListener(DropListener):
        @ staticmethod
        def dropEvent(e):
            global img
            if e.isImage(): img = e.loadImage()
    
  • edited April 2016

    Note that I didn't even bother resizing the image.

    • Actually in order to resize() the loaded PImage would be as complex as my 1st tweak. @-)
    • B/c DropEvent's own loadImage() method happens in another Thread.
    • Therefore we dunno when the PImage got loaded.
    • And if we attempt to resize() w/o delay(), we'd be just resizing an empty 4x4 PImage!
    • In a wrong time, it could even crash the sketch! :-SS
  • edited April 2018

    Just found a another way to simplify my tweaked attempt: filePath():
    http://Diskordier.net/drop/reference/drop/DropEvent.html#filePath--

    That is, rather than invoking DropEvent's own loadImage() which happens in another Thread:
    http://Diskordier.net/drop/reference/drop/DropEvent.html#loadImage--
    Get instead dropped File's path w/ DropEvent's filePath() & go w/ PApplet's loadImage()! *-:)

    """
     ' sDrop Image Listening (v2.2)
     ' by  Medecau (2016-Apr-29)
     ' mod GoToLoop
     '
     ' Forum.Processing.org/two/discussion/16339/sdrop-in-python-mode#Item_5
     ' Gist.GitHub.com/medecau/22cec5853a5f7285ee2f97363bca096c
    """
    
    add_library('Drop')
    
    def setup():
        size(500, 500)
        noLoop()
        background(int(random(0x1000000)))
    
        global img
        img = None
    
        SDrop(this).addDropListener(MyDropImageListener())
    
    
    def draw(): img and img.width == width and background(img)
    
    
    class MyDropImageListener(DropListener):
        @staticmethod
        def dropEvent(d):
            if not d.isImage(): return
    
            global img
            img = loadImage(d.filePath())
    
            if img.width > 0:
                this.surface.setSize(img.width, img.height)
                redraw()
    
Sign In or Register to comment.