Android, используя Bitmap (NDK + альфа-байты): я что-то пропустил? - PullRequest
1 голос
/ 08 ноября 2011

Я из мира Qt и портирую приложение на Android.Я немного сбит с толку, я несколько дней бьюсь головой о чем-то, что должно быть настолько тривиальным, что я не могу понять, почему оно не работает.

Немного предыстории: у меня есть движок C ++, который я использую через NDKи JNI.Этот движок создает некоторые растровые изображения и передает их стороне Java, сторона Java должна отображать их в представлении и позволить пользователю взаимодействовать с ними (перетаскивать и т. Д.).

Движок работает правильно, потому что я его используюпод Qt с полным успехом.Это рабочий процесс:

1 - Java загружает большое растровое изображение из файла пользовательских данных (механизм C ++ ожидает, что он будет в формате ARGB, но это сжатые данные JPG)

Bitmap.Config fmt = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, size).copy( fmt , false);

2 - инициализировать движок C ++, передавая растровое изображение.Движок C ++ «разбивает» растровое изображение на меньшие плитки.Для тайла он строит довольно сложную альфа-маску и сохраняет ее в первом байте растрового изображения (байт "a").Эта альфа-маска использует только два значения: 0xFF для непрозрачного и 0x00 для прозрачного.

init_C_engine( this.fullImage );

3 - Затем сторона Java выделяет все растровые изображения тайлов, я делаю это в два шага, потому что перед init я не знаю, какой размербудут плиткиДвижок будет заполнять массивы tile_width и tile_height:

Bitmap.Config fmt = Bitmap.Config.ARGB_8888;
for (int t = 0; t < this.puzzle_size; t++ ){
    tile_data[ t ] = Bitmap.createBitmap(  tile_width[t],  tile_height[t],   fmt);

4 - Последний шаг внутри движка C ++ - все растровые изображения тайлов заполнены:

for ( int n = 0; n < nBitmaps; n++ )
{
        jobject bitmap = env->GetObjectArrayElement( bitmaps, n );
        AndroidBitmap_getInfo(env, bitmap, &info);
        AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void **>(&pixels));
        game->getTileBitmap( n, (unsigned char*)pixels );
        AndroidBitmap_unlockPixels(env, bitmap);
        env->SetObjectArrayElement( bitmaps, n, bitmap );
    }   
}

Теперь в моем пользовательскомView:

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLACK);
    for ( int tile = 0; tile < board.nTiles; tile++ ){
            canvas.drawBitmap( tile_data[tile],
                               tile_x[tile],
                               tile_y[tile], paint);
        }
}

Я ожидаю, что на моем View я вижу свои плитки с прозрачными областями.вместо этого я получаю странное поведение, так что на черном фоне я вижу, что ВСЯ плитка, такая как альфа-байты, все установлена ​​в непрозрачную, но когда я перемещаю плитки одну из верхней части другой, «прозрачные» области объединяются вкаким-то странным образом, например, цвета "xor" редактируются или умножаются каким-то образом!Когда я перемещаю одну плитку на другую, я вижу области, в которых альфа-байты установлены прозрачными, но цвета искажаются, а не прозрачны!

В основном я ожидаю, что пиксели, для которых альфа установлен в 0, отображаются прозрачными... я посмотрел в интернете, но не смог найти ничего полезного, чтобы выручить меня ...

У кого-нибудь есть идеи?Все будет оценено!спасибо.

1 Ответ

0 голосов
/ 08 ноября 2011

Разве вы не должны использовать индекс t вместо tile внутри цикла for внутри onDraw? Как это:

canvas.drawBitmap(tile_data[t], tile_x[t], tile_y[t], paint);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...