Saya mencoba menggambar tampilan khusus di Android, dengan metode canvas.drawBitmap()
. Namun, saya menemukan saluran alfa akan hilang jika saya melakukan ini dalam kode JNI asli dan latar belakangnya berwarna hitam. Singkatnya, kasusnya adalah:
- Panggil Java
bitmap.setPixels()
dan atur warna piksel bitmap di NDK ketika latar belakang putih, kedua bitmap ditampilkan dengan benar - Panggil java
bitmap.setPixels()
dan setel warna piksel bitmap di NDK ketika latar belakang hitam, hanya bitmap yang digambar oleh java API yang ditampilkan dengan benar, bitmap yang digambar dengan NDK kehilangan saluran alfa
Pertanyaannya kenapa pada background putih hasilnya OK tapi pada background hitam tidak OK? Apakah saya melewatkan sesuatu atau melakukannya dengan cara yang salah?
File XML tata letak:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/black"
android:orientation="horizontal"
android:padding="16dp" >
<com.example.android.TestView
android:id="@+id/testview1"
android:layout_width="320px"
android:layout_height="320px"
android:layout_margin="16dp" />
<com.example.android.TestView
android:id="@+id/testview2"
android:layout_width="320px"
android:layout_height="320px"
android:layout_margin="16dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="horizontal"
android:padding="16dp" >
<com.example.android.TestView
android:id="@+id/testview3"
android:layout_width="320px"
android:layout_height="320px"
android:layout_margin="16dp" />
<com.example.android.TestView
android:id="@+id/testview4"
android:layout_width="320px"
android:layout_height="320px"
android:layout_margin="16dp" />
</LinearLayout>
</LinearLayout>
MainActivity.java :
package com.example.android;
import com.example.android.R;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TestView tv2 = (TestView) findViewById(R.id.testview2);
TestView tv4 = (TestView) findViewById(R.id.testview4);
tv2.setDrawFromNative();
tv4.setDrawFromNative();
}
}
TestView.java :
package com.example.android;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
public class TestView extends View {
private Bitmap mBitmap;
private boolean mDrawFromNative;
private static final int WIDTH = 320;
private static final int HEIGHT = 320;
static {
System.loadLibrary("bitmaptest");
}
private native void nativeDrawBitmap(Object bitmap);
private static void javaDrawBitmap(Bitmap bitmap) {
int pixels[] = new int[WIDTH * HEIGHT];
for (int i = 0; i < pixels.length; i++) {
pixels[i] = 0x88FF0000;
}
bitmap.setPixels(pixels, 0, WIDTH, 0, 0, WIDTH, HEIGHT);
}
public TestView(Context context, AttributeSet attrs) {
super(context, attrs);
mBitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
}
public void setDrawFromNative() {
mDrawFromNative = true;
}
@Override
protected void onDraw(Canvas canvas) {
if(mDrawFromNative) {
nativeDrawBitmap(mBitmap);
} else {
javaDrawBitmap(mBitmap);
}
canvas.drawBitmap(mBitmap, 0, 0, null);
}
}
TestNative.cpp:
#include <jni.h>
#include <android/bitmap.h>
#include <android/Log.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOG_TAG "BMPTEST"
extern "C" {
void Java_com_example_android_TestView_nativeDrawBitmap(JNIEnv* env, jobject thiz, jobject bitmap) {
AndroidBitmapInfo info;
void* dst_pixels;
int ret;
if((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
if ((ret = AndroidBitmap_lockPixels(env, bitmap, &dst_pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
return;
}
unsigned int *dst = (unsigned int *)dst_pixels;
for(int i=0; i< info.width * info.height; i++) {
*(dst+i) = (0x88<<24 | 0xff | 0x00<<8 | 0x00<<16); //(ARGB->ABGR)
}
AndroidBitmap_unlockPixels(env, bitmap);
}
}
Android.mk untuk kode asli:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libbitmaptest
LOCAL_SRC_FILES := \
TestNative.cpp
LOCAL_LDLIBS += -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
ScreenShot hasil:
0x0000ff11
) - person Michael   schedule 07.01.2015