3

I am currently porting an application from iOS into Android and I have ran into some difficulties when it comes to image processing.

I have a filter class that is comprised of ImageOverlays and ColorOverlays which are applied in a specific order to a given base Bitmap. Each ColorOverlays has an RGB color value, a BlendModeId, and an alpha value. Each ImageOverlay has an image Bitmap, a BlendModeId, and an alpha/intensity value.

My main problem is that I need to support the following blend modes taken from iOS:

  1. CGBlendModeNormal
  2. CGBlendModeMultiply
  3. CGBlendModeScreen
  4. CGBlendModeOverlay
  5. CGBlendModeDarken
  6. CGBlendModeLighten
  7. CGBlendModeColorDodge

Some of these have corresponding PorterDuff.Mode types in Android while others do not. What's worse, some of the modes that do exist were introduced in recent versions of Android and I need to run on API level 8.

Trying to build the modes from scratch is extremely inefficient.

Additionally, even with the modes that do exist in API8, I was unable to find methods that blend 2 images but that allow you to specify the intensity of the mask (the alpha value from ImageOverlay). Similarly with ColorOverlays.

The iOS functions I am trying to replicate in Android are

CGContextSetBlendMode(...)
CGContextSetFillColorWithColor(...)
CGContextFillRect(...) - This one is easy
CGContextSetAlpha(...)

I have started looking at small third party libraries that support these blend modes and alpha operations. The most promising one was poelocesar's lib-magick which is supposedly a port of ImageMagick.

While lib-magick did offer most of the desired blend modes (called CompositeOperator) I was unable to find a way to set intensity values or to do a color fill with a blend mode.

I'm sure somebody has had this problem before. Any help would be appreciated. BTW, Project specifications forbid me from going into OpenGLES.

zienkikk
  • 2,404
  • 1
  • 21
  • 28

2 Answers2

2

It turned out that implementing it in the jni wasn't nearly as painful as previously expected. The following link had all the details.

How does photoshop blend two images together?

Community
  • 1
  • 1
zienkikk
  • 2,404
  • 1
  • 21
  • 28
2

Even though I helped you via e-mail, I thought I'd post to your question too in case someone wanted some more explanation :-)

2.2 is API level 8, which supports the "libjnigraphics" library in the NDK, which gives you access to the pixel buffer for bitmap objects. You can do these blends manually - they are pretty simple math calculations and can be done really quickly.

Check out this site for Android JNI bitmap information.

It's really simple, just create a JNI method blend() with any parameters you need (either the color values or possibly another bitmap object to blend together), lock the pixel buffer for that bitmap, do the calculation needed, and unlock the bitmap. Link

Care needs to be taken on the format of the bitmap in memory, though, as the shifting/calculation for 565 will be different than 8888. Keep that in mind if it doesn't look exactly correct!

Community
  • 1
  • 1
ZachM
  • 893
  • 2
  • 8
  • 22