ユーザーが画像を描画して保存し、後でリロードして描画を続行できるようにする描画アプリケーションを作成しました。基本的に、描画をビットマップとして JNI レイヤーに渡して保存し、同じように前の描画をロードします。
私はOpenCvを使ってpngファイルに読み書きしています。
画像の透明度の点で奇妙なことに気付きました。OpenCvの黒色に対して透明度が計算されているように見えますか? 添付の画像を見てください。透明な線が含まれています。
int 配列をネイティブ コードに渡すことで透明度を修正します。色変換は必要ありません。
Bitmap オブジェクトをネイティブ コードに渡すことで透明度を暗くしました。色変換が必要です。
何が起こっている可能性がありますか?
ネイティブの Bitmap get pixel メソッドを使用して画像を保存します。
if ((error = AndroidBitmap_getInfo(pEnv, jbitmap, &info)) < 0) {
LOGE("AndroidBitmap_getInfo() failed! error:%d",error);
}
if (0 == error)
{
if ((error = AndroidBitmap_lockPixels(pEnv, jbitmap, &pixels)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", error);
}
}
if (0 == error)
{
if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888)
{
LOGI("ANDROID_BITMAP_FORMAT_RGBA_8888");
}
else
{
LOGI("ANDROID_BITMAP_FORMAT %d",info.format);
}
Mat bgra(info.height, info.width, CV_8UC4, pixels);
Mat image;
//bgra.copyTo(image);
// fix pixel order RGBA -> BGRA
cvtColor(bgra, image, COLOR_RGBA2BGRA);
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(3);
// save image
if (!imwrite(filePath, image, compression_params))
{
LOGE("saveImage() -> Error saving image!");
error = -7;
}
// release locked pixels
AndroidBitmap_unlockPixels(pEnv, jbitmap);
}
ネイティブの int ピクセル配列メソッドを使用して画像を保存します。
JNIEXPORT void JNICALL Java_com_vblast_smasher_Smasher_saveImageRaw
(JNIEnv *pEnv, jobject obj, jstring jFilePath, jintArray jbgra, jint options, jint compression)
{
jint* _bgra = pEnv->GetIntArrayElements(jbgra, 0);
const char *filePath = pEnv->GetStringUTFChars(jFilePath, 0);
if (NULL != filePath)
{
Mat image;
Mat bgra(outputHeight, outputWidth, CV_8UC4, (unsigned char *)_bgra);
bgra.copyTo(image);
if (0 == options)
{
// replace existing cache value
mpCache->insert(filePath, image);
}
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(compression);
// save image
if (!imwrite(filePath, image))
{
LOGE("saveImage() -> Error saving image!");
}
}
pEnv->ReleaseIntArrayElements(jbgra, _bgra, 0);
pEnv->ReleaseStringUTFChars(jFilePath, filePath);
}
2012 年 5 月 25 日更新:
もう少し調査した結果、ビットマップからピクセルの int 配列を取得し、それを JNI に直接渡すと、現在行っていることとは対照的に、この問題は発生しないことがわかりました。ビットマップ全体を JNI レイヤーに渡し、ピクセルを取得して、ピクセルをcvtColor
適切に変換するために使用します。正しいピクセル変換を使用していますか?