New Blendings Modes for Java2D

Java2D contains one of my favorite Java SE classes, java.awt.AlphaComposite. You can set an alpha composite on a Graphics2D context to blend a draw primitive with the current graphics. I have written a small tool that helps you understand how these composites work:

Webstart now!

Alpha Composites

You can also download the source of this tool.

AlphaComposite is very useful, and I have used it quite a lot in Aerith for instance, but it does not do everything I want. I spend a lot of time in Photoshop creating mockups of my UIs and I often use the various blending modes you can set on layers. Those blending modes are great to create advanced lighting effects for instance. And if you ever work with a graphics designer, you might have to implement a Photoshop mockup that uses these blending modes. Tired of always having to find work arounds, I finally wrote a Java implementation of those blending modes and a small tool to test them:

Webstart now!

Blend Composites

You can also download the source of this tool. The source contains a classe called BlendComposite that contains 32 new Composite implementations for Java2D (even though Normal is the equivalent of AlphaComposite.Src):

  • Normal
  • Average
  • Multiply
  • Screen
  • Darken
  • Lighten
  • Overlay
  • HardLight
  • SoftLight
  • Difference
  • Negation
  • Exclusion
  • ColorDodge
  • InverseColorDodge
  • SoftDodge
  • ColorBurn
  • InverseColorBurn
  • SoftBurn
  • Reflect
  • Glow
  • Freeze
  • Heat
  • Add
  • Subtract
  • Stamp
  • Red
  • Green
  • Blue
  • Hue
  • Saturation
  • Color
  • Luminosity

BlendComposite works exactly as AlphaComposite. I simply duplicated the API. Here is an example of blending two pictures with the Overlay mode:

g2.drawImage(imageA, 0, 0, null);
g2.setComposite(BlendComposite.Overlay.derive(0.75f);
g2.drawImage(imageB, 0, 0, null);

There are a few caveats though. First, I only implemented the operations for primites stored as integers. That means you have to make sure you draw images that store their pixels as INT_RGB or INT_ARGB (making your pictures compatible will work.) Next, these implementations are not very fast, do not try real-time drawing with them. Finally, the SoftLight blending is not implemented yet and the HSL modes are not perfect when you blend a grayscale primitive. If you want to help, feel free to send me patches.

Those composites work much better with Java SE 6; I have noticed speed improvements of x3 to x4 when compared to J2SE 5.0. A while ago, the JVM team announced they improved HotSpot's management for arrays and from what I have seen with this example, they did a great job!

The source code is released under BSD license.

4 Responses to “New Blendings Modes for Java2D”

  1. Harmen says:

    Hi, this is a very impressive stack of blending modes. I want to use the overlay and lighten mode for an applet. However, as you have noted, the implementation is not lightning fast. Do you have any hints where to look for speeding up things? I want to work on this.

  2. Maciek says:

    Hi, I just wanted to tell you how thankful I’m for your post on AlphaComposite. I literally spend hours of searching some tips on how to make progress-bar with only a Graphics2D lib (ie without Swing library), and finally stumbled upon your blog. All I needed was XOR effect for the percent rate string to render in negative color when covered by the bar. Thank you so much