Threads in processing.py?

Is it possible to use thread() in processing.py? I’m trying to asynchronously and dynamically load large images without interfering with the framerate or draw loop

I didn’t see any mention of thread() in the processing.py docs, I’m hoping there’s something similar

Thanks!

Even though thread(): thread() / Reference / Processing.org
Isn’t listed in Python Mode’s own reference: Reference
AFAIK, it’s working alright on it nonetheless: :partying_face:

def setup():
    thread('threaded')
    exit()


def threaded():
    print 'Worked!'

Processing already provides requestImage() for such demanding situation: :wink:

5 Likes

Oh amazing, will give the threads and requestImage() a try then. Thanks for the help!

requestImage() is already threaded. You don’t need both. :wink:

I’ve given both requestImage() and thread() a go - requestImage() seems to be working well for me, but I’m having a bit of confusion over why thread() is drastically slowing down my framerate (when being used to process an offscreen pGraphics)

I made a little test script, where I’m using a thread which is triggered by a mouse click. The thread updates a global pGraphics object by applying a pretty heavy blur, with a new blur value for each click.

The part that is confusing to me is that even though I’m doing this heavy lifting on a separate thread, it still crashes my framerate on each new blur.

I think my code should run with a copy and paste, if anyone is down to give it a go - I’m using the site lorempixel to get a placeholder 1000px by 1000px image, rather than local image files

pg = None
imgtest = requestImage('http://lorempixel.com/1000/1000',"jpg")
img_loaded = False
click_thread_running = False

frameRates = []

def setup():
    size(1000,1000,P2D)
    background(255,255,255)
    fill(0)
    textSize(18)
    textAlign(CENTER)

def draw():
    global img_loaded
    
    # First check that initial thread requestImage has loaded
    if img_loaded != True:
        if imgtest.width > 0:
            img_loaded = True
            thread('click_thread')
        pass
    else:
        background(255,255,255)
        if pg and not click_thread_running:
            pushMatrix()
            translate(mouseX - pg.pixelWidth/2, mouseY - pg.pixelHeight/2)
            image(pg,0,0)
            popMatrix()
        else:
            draw_loader()
        update_framerate_monitor()

def mousePressed():
    if not click_thread_running:
        thread('click_thread')

# this does some hefty blur processing on a large pGraphics in a separate thread
# ... but causes the framerate to go down?
def click_thread():
    global pg
    global click_thread_running
    
    click_thread_running = True

    if !pg:
        pg = createGraphics(1500,1500)
        pg.smooth(8)
    pg.beginDraw()
    pg.background(100,200,37)
    pg.image(imgtest,40,40)
    new_blur_val = int(25+random(15))
    pg.filter(BLUR, new_blur_val)
    fill(0)
    pg.text("Blur Value: {}\nClick to apply a new blur to this global pg via a thread".format(new_blur_val), 750,780)
    pg.endDraw()
    click_thread_running = False

# Just to monitor framerate
def update_framerate_monitor():
    global frameRates
    if frameCount % 10 == 0:
        frameRates.append(int(frameRate))
        if len(frameRates) > 60:
            frameRates.pop(0)
    pushMatrix()
    translate(80,10)
    fill(255)
    rect(0,0,80,80)
    translate(10,10)
    noFill()
    beginShape()
    for i,rate in enumerate(frameRates):
        vertex(i+1,60-rate)
    endShape()
    popMatrix()
    fill(0)
    text(frameRate,30,30)

def draw_loader():
    pushMatrix()
    translate(width/2,height/2)
    fill(255)
    stroke(0)
    pushMatrix()
    translate(100.0*cos(frameCount/10.),100.0*sin(frameCount/10.))
    rect(0,0,5,5)
    popMatrix()
    fill(0)
    text('Large image blur processing on a thread...',0,0)
    popMatrix()
    

Thanks! I will give that a try too