Alpha blending and saving imgs without showing off on screen

i’m having a hard time figuring out this, which i though shouldn’t be so complex, and it probably isn’t.

in my application, i need to blend two image objects (an alpha image over a flat one) into one single image object and save the result to a file, but without showing it off on the screen.

the only way i managed to do proper blending was whithin draw(), using the of/opengl ofEnableAlphaBlending method, but it shows off the image on screen, which doesn’t fit my needs.

it’s crucial for it to be a background process, without the user being aware of it. but i really couldn’t think of a way of doing it. what am i missing?

any help is really welcome.

thanks

do the blending manually: allocate a new image, and for each pixel in it, take the equivalent pixels in your two source images and calculate the average values of each component (ie dest = (source_1 + source_2)/2). this also gives you a lot more control over the blending.

hey damian, thanks for the reply. but i guess this method is a problem when one sorce is completely transparent and the other one isn’t, for the final image will be the not-transparent one, but half way transparent (or half way darker), right?

but i liked the idea of doing it so. then, which would be a good method to do the same as the alpha blending, but manually?

hi andregmintz,

about manual blending, I found this tutorial really simple and useful.

http://student.kuleuven.be/~m0216922/CG-…-metic.html

I think I even did some blending modes in of (following this tutorial) some time ago, I can try to dig them if you want.

I’ve not done this, but the following should work (bit hackish solution) :

  1. download zach_gage / theo’s FBO code here
    http://www.openframeworks.cc/forum/view-…-o&start=15

  2. Create a copy of ofImage.h and ofImage.cpp and call it ofImageFBO.h and ofImageFBO.cpp and change all references of ofImage to ofImageFBO.

  3. create an ofImageFBO, render everything to the FBO in ofImageFBO. then use ofImageFBO.save() to save.

Note. If ofImage had an ofTexture* instead of an ofTexture, then we wouldn’t need to duplicate all the ofImage code, and just create a normal ofImage and make the ofTexture* point to the instance of ofFBOTexture. Bit more complex backend, but shouldn’t affect basic users… only give more options to advanced users… dunno what other of’ers thing…

Just realized ofImage.saveImage() doesn’t actually read back from video memory…
So you’d need to use glGetTexImage() to read the texture (in the FBO) back to main memory, then use ofImage (or FreeImage directly).

I’m having a hard time figuring out this, which i though shouldn’t be so complex, and it probably isn’t.

in my application, i need to blend two image objects (an alpha image over a flat one) into one single image object and save the result to a file, but without showing it off on the screen.

This is actually pretty easy - no need for fbos.

  1. Just draw the first image, then the second image.
  2. Have your third image read the pixels from the screen. This is the image that saves to disk.
  3. Draw a black rectangle the size of the screen - this will hide the images from being seen.
  4. Draw the stuff you want the user to see.

With this approach the user will never see the images you are composting.

Hope that helps!
Theo

Nuther possibility still, is to use opencv:

  
cvAddWeighted(img1, alpha, img2, (1-alpha), 0, img_dest);  
  

Of course, your images have to be IplImages, but I made a lightweight wrapper class which you can wrap your ofImages with:

http://forum.openframeworks.cc/t/convert-rgb-colour/1350/6

thanks to all for the solutions. i actually did it with theo’s and it worked pretty well. quite simple. i liked it.

but, just a thought, it would be interesting to make it possible to draw to an image object, but not on the screen. it has many possible uses, avoiding the grabScreen to create new images with the app on the run.

thanks again

This is actually pretty easy - no need for fbos.

  1. Just draw the first image, then the second image.
  2. Have your third image read the pixels from the screen. This is the image that saves to disk.
  3. Draw a black rectangle the size of the screen - this will hide the images from being seen.
  4. Draw the stuff you want the user to see.

doh! nice one :stuck_out_tongue:

try this :slight_smile:

alpha blend image