I have a video stream and like to apply a chroma key effect on it. I tried this GPU library but it is even slower as my own code:
public class ChromaKey {
int[] pix;
Bitmap bm;
int picw, pich;
int index, cur_pix, red2, green2, blue2;
public Bitmap replaceIntervalColor(Bitmap bitmap,int red, int green, int blue)
{
if (bitmap != null)
{
picw = bitmap.getWidth();
pich = bitmap.getHeight();
if (pix == null)
{
pix = new int[picw * pich];
}
bitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);
double distance;
for (int y = 0; y < pich; y++) {
for (int x = 0; x < picw ; x++) {
index = y * picw + x;
cur_pix = pix[index];
red2 = (int)((cur_pix & 0x00FF0000) >>> 16); // Color.red(cur_pix);
green2 = (int)((cur_pix & 0x0000FF00) >>> 8); //Color.green(cur_pix);
blue2 = (int)(cur_pix & 0x000000FF); //Color.blue(cur_pix);
// faster Math.sqrt
// Source: http://stackoverflow.com/a/13264441/956397
/* distance = Math.sqrt(
(red2 - red) * (red2 - red)
+ (green2 - green) * (green2 - green)
+ (blue2 - blue) * (blue2 - blue)
); */
distance = Double.longBitsToDouble(((Double.doubleToRawLongBits( (red2 - red) * (red2 - red)
+ (green2 - green) * (green2 - green)
+ (blue2 - blue) * (blue2 - blue) ) >> 32) + 1072632448 ) << 31);
if (distance < 190)
{
pix[index] = Color.TRANSPARENT;
}
}
}
if (bm == null)
{
bm = Bitmap.createBitmap(picw, pich, Bitmap.Config.ARGB_4444);
}
bm.setPixels(pix, 0, picw, 0, 0, picw, pich);
return bm;
}
return null;
}
}
How can I improve the performance of this code?
I already moved all object creation out to reuse memory but it is still so slow on a high end tablet.
Suggest you to move this operation to native library (C/C++). You can pass whole Bitmap object to native library function and modify content of Bitmap without copy pixels back and forth. Even optimization in assembler can be applied.
Or more simpler try to optimize your code.