Image transparency (alpha) via tint() is very slow.

Hi. I'm trying to adjust the alpha channel for images loaded using loadImage(). However, when I do so, FPS drops from 60FPS to 3FPS with just 4 images on screen.

Code I'm using is approximately: var path = "assets/video_placeholder.jpg" var imgHandler = loadImage(path); tint(255, 126); image(imgHandler, 200, 200, 450, 450);

Is this expected? Other than using DOM to load images and applying CSS to control opacity, is there any better way to give transparency to images?

thx!

Answers

  • edited December 2016

    https://forum.Processing.org/two/discussion/15473/readme-how-to-format-code-and-text

    In order to bypass the slowness in draw(), how about create pre-tint() image clones in setup() via createGraphics()? *-:)

    http://p5ide.HerokuApp.com/editor#?sketch=583f9826a6da6a0400c6e28c

    /**
     * Tinted Clone Image (v1.0.3)
     * GoToLoop (2016-Dec-01)
     *
     * forum.Processing.org/two/discussion/19438/
     * image-transparency-alpha-via-tint-is-very-slow#Item_1
     *
     * p5ide.HerokuApp.com/view/583f9826a6da6a0400c6e28c
     */
    
    "use strict";
    
    const HTTP = 'http:/',
          SITE = '/upload.Wikimedia.org/wikipedia/en/a/a4/',
          FILE = 'Super_Blanka.png',
          URL  = HTTP + SITE + FILE;
    
    let img, transp, bg;
    
    function preload() {
      img = loadImage(URL);
    }
    
    function setup() {
      createCanvas(img.width<<1, img.height);
      noLoop();
      imageMode(CORNER);
    
      const pg = createGraphics(img.width, img.height);
    
      pg.imageMode(CORNER);
      pg.tint(0xff, 0x80);
      pg.image(img, 0, 0);
    
      transp = pg.get();
      bg = color('lightgray');
    }
    
    function draw() {
      background(bg);
      image(img, 0, 0);
      image(transp, width>>1, 0);
    }
    
  • @GoToLoop Why did you right shift the width on line 42?

  • edited December 2016

    In order to divide it by 2, and place the transparent p5.Image on the right side of the canvas, @Lord_of_the_Galaxy! :ar!

  • @GoToLoop Yeah I got that, but why not just divide by 2? It would certainly not change performance by any appreciable amount.

  • edited December 2016

    In JS, bit operators also truncate the result to become a 32-bit integer value. =P~

  • Hi @GoToLoop. I gave your method a try, but it's still quite slow to render unfortunately. I couldn't replicate your method exactly b/c I'm loading the images dynamically - but i think i got it working in the same way that you advise. See anything here that would impact speed?

    Where render is called from draw():

    Minion.prototype.assetloaded = function() {
        console.log("assets loaded: " + this.path);
        this.pg = createGraphics(200,200);
        this.pg.imageMode(CORNER);
        this.pg.tint(0xff, 0x80);
        this.pg.image(this.imgHandler, 0, 0);
        this.transp = this.pg.get();
    }
    function Minion(type, x, y, path, size, opacity) {
      this.imgHandler = loadImage(path,this.assetloaded.bind(this));
      this.render = function() {
        if (this.transp){
          image(this.transp, 20, 20);
        }
      }
    }
    
  • Oh, I just noticed something peculiar. The frame rate seems to be back up to 60FPS. It's just the click/drag behavior that I've got on these images that is slow/jerky. Hm, strange right? To have a fast frame rate and a slowly performing click and drag?

  • edited December 2016

    See anything here that would impact speed?

    Well, tint() always impacts speed! My example explicit creates a pre-tint() BEFORE draw() begins! L-)

  • Oh, I was thinking that just getting tint() out of the draw() loop would be beneficial (my example above only runs tint() the first time the object is instantiated - which only happens 4 times in the example i'm working on). You're saying that the key is actually rendering it before draw() entirely huh?

Sign In or Register to comment.