When using some of the PorterDuff modes in the Android SDK incorrect
alpha values are produced. For example the following:
Bitmap bitmap = Bitmap.createBitmap(100, 100,
Bitmap.Config.ARGB_8888);
bitmap.eraseColor(0xff000000); // Black with alpha 255
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(0x80000000, PorterDuff.Mode.SRC_OVER); // Black with
alpha 128
results in 0xfe000000 so an alpha value of 254 instead of 255
After some digging in the source code I traced it back to incorrect
use of SkAlpha255To256 defined in
platform/external/skia.git/include/core/SkColorPriv.h
34 static inline unsigned SkAlpha255To256(U8CPU alpha) {
35 SkASSERT(SkToU8(alpha) == alpha);
36 return alpha + (alpha >> 7);
37 }
It is frequently used in the PorterDuff blending functions, below is
SRC_OVER from:
platform/external/skia.git/src/core/SkXfermode.cpp
347 // kSrcOver_Mode, //!< [Sa + (1 - Sa)*Da, Sc + (1 - Sa)*Dc]
348 static SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) {
349 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 -
SkGetPackedA32(src)));
350 }
Running the above numbers for alpha it produces 128 + (255 * 127) >> 8
= 254. Doing it without the shift optimization returns 128 + (255 *
127) / 255 = 255.
Fro some of these functions (not all) it would be better to use a
SkAlpha255To256 defined as
static inline unsigned SkAlpha255To256(U8CPU alpha) {
SkASSERT(SkToU8(alpha) == alpha);
return alpha + 1;
}
which is not 100% accurate either but you can still use the shift
trick and it does produce correct result when alpha is 0 and when
alpha is 255. Any thoughts?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"android-framework" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-framework?hl=en
-~----------~----~----~----~------~----~------~--~---