難しくはありませんでした。
ピクセルを操作するためにNDK(パフォーマンスのため)を使用しました。ブレンディングモードに関するこの情報は非常に役立ちました。フォトショップは2つの画像をどのようにブレンドしますか?
私の最終的な解決策は次のとおりです。
#define ChannelBlend_ColorBurn(A, B) ((uint8_t) ((B == 0) ? B : max(0, (255 - ((255 -
#define ChannelBlend_Alpha(A, B, O) ((uint8_t) (O * A + (1 - O) * B))
#define ChannelBlend_AlphaF(A, B, F, O) (ChannelBlend_Alpha(F(A, B), A, O))
typedef struct {
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t alpha;
} rgba;
// Blend
JNIEXPORT void
JNICALL Java_com_package_Filter_jniBlend(JNIEnv* env, jobject obj, jobject bitmapA,
jobject bitmapB, jobject bitmapOut, jint mode) {
// Properties
AndroidBitmapInfo infoA;
void* pixelsA;
AndroidBitmapInfo infoB;
void* pixelsB;
AndroidBitmapInfo infoOut;
void* pixelsOut;
int ret;
// Get image info
if ((ret = AndroidBitmap_getInfo(env, bitmapA, &infoA)) < 0 ||
(ret = AndroidBitmap_getInfo(env, bitmapB, &infoB)) < 0 ||
(ret = AndroidBitmap_getInfo(env, bitmapOut, &infoOut)) < 0) {
return;
}
// Check image
if (infoA.format != ANDROID_BITMAP_FORMAT_RGBA_8888 ||
infoB.format != ANDROID_BITMAP_FORMAT_RGBA_8888 ||
infoOut.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
return;
}
// Lock all images
if ((ret = AndroidBitmap_lockPixels(env, bitmapA, &pixelsA)) < 0 ||
(ret = AndroidBitmap_lockPixels(env, bitmapB, &pixelsB)) < 0 ||
(ret = AndroidBitmap_lockPixels(env, bitmapOut, &pixelsOut)) < 0) {
LOGE("Error! %d", ret);
}
int h = infoA.height;
int w = infoA.width;
int wh = w * h;
int n;
rgba* inputA = (rgba*) pixelsA;
rgba* inputB = (rgba*) pixelsB;
rgba* output = (rgba*) pixelsOut;
rgba pA, pB;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
n = y * w + x;
pA = inputA[n];
pB = inputB[n];
float alpha = (float) pB.alpha / 255.0;
output[n].red = ChannelBlend_AlphaF(pA.red, pB.red, ChannelBlend_ColorBurn, alpha);
output[n].green = ChannelBlend_AlphaF(pA.green, pB.green, ChannelBlend_ColorBurn, alpha);
output[n].blue = ChannelBlend_AlphaF(pA.blue, pB.blue, ChannelBlend_ColorBurn, alpha);
}
}
// Unlocks everything
AndroidBitmap_unlockPixels(env, bitmapA);
AndroidBitmap_unlockPixels(env, bitmapB);
AndroidBitmap_unlockPixels(env, bitmapOut);
}
パフォーマンスを改善するためのちょっとした注意:単一ピクセルの方程式を作成した後、次回は方程式なしでより速くアクセスするために、ある種のキャッシュに値を格納するのが良いでしょう。