views:

998

answers:

2

I have a Bitmap object and want to render it to a Canvas object with varying levels of translucency (i.e. make the whole bitmap partially see through). For example, I have sprites in a game (that are drawn over the top of a bitmap background) that I want to fade out from being opaque to being invisible. Can I do this without having to resort to OpenGL?

A: 

Reviewing the Android doc (which looks based on JSE with a completely alternative GUI), the following will get you a alpha-channel supporting image:

Bitmap bmp=createBitmap(100,100,Bitmap.Config.ARGB_8888);

As long as the source bitmap is alpha supporting, you should be able to paint it onto another bitmap and have it's alpha values honored.

To fade it out, you will need to repeatedly paint the image with some suitable delay (but event driven from a timer, not in a loop, unless Android's rendering system is very different from other Javas) manipulating the alpha channel for each pixel on each successive paint.

// Make image more transparent by 50%
int[] pxls=new int[100*100];
bmp.getPixels(pxls,0,100,0,0,100,100);
for(int xa=0,len=pxl.length; xa<len; xa++) {
    int alp=(pxls[xa] & 0xFF000000);
    alp<<1;
    pxls[xa]=(alp | (pxls[xa] & 0x00FFFFFF);
    }
bmp.setPixels(pxls,0,100,0,0,100,100);

Caveat 1: I wrote this code in-situ from the JavaDoc; it has not been compiled or tested.

Caveat 2: If the hardware device color resolution does not support an alpha-channel (commonly known as 32 bit color), painting of any images to the underlying graphics system may simply ignore the alpha-channel). But any compositing you do before then on a back-buffer image should be respected. The point being you may have to use double-buffered painting to do alpha blending while being immune to the underlying device capabilities/config.

Software Monkey
Thanks for the code. I know about this method but looping over a few smallish sprites like this every frame will destroy my framerate. I've written code like this before and it is seriously slow looping over and manipulating single pixels. There must be an easier way because several GUI elements have quick fading effects.
wordyword
+1  A: 

You should be able to define a tween animation and apply that animation to an imageView. The XML resource would be similar to the following (named fade_animation.xml):

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
   android:interpolator="@android:anim/linear_interpolator"
   android:fromAlpha="1.0"
   android:toAlpha="0.0"
   android:duration="100" />

then you would load and apply this animation to your custom imageView when ready:

ImageView sprite = (ImageView) findViewById(R.id.sprite);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.fade_animation);
sprite.startAnimation(animation);

There are other options too. If you are using bitmaps and you don't want to do an animation, then you can manually decrease the alpha value of each frame, somewhat like this:

paint.setAlpha(100);
canvas.drawBitmap(spriteImage, left, top, paint);

Did you try any of these options?

YGL