Проблема с цветом вызвана тем, что вы работаете с другим форматом YUV. Формат YUV, который используют рамки камеры, - это YUV NV21. Этот формат (NV21) является стандартным форматом изображения для предварительного просмотра камеры Android. Плоское изображение YUV 4: 2: 0 с 8-битными выборками Y, за которым следует чередующаяся плоскость V / U с 8-битными выборками цветности 2x2 с субдискретизацией.
Если ваши цвета инвертированы, это означает:
- Вы работаете с YUV NV12 (плоскость U - это V, а V - это U).
- Одна из ваших цветовых плоскостей делает что-то странное.
Для правильной работы с libyuv
Я предлагаю вам преобразовать вывод вашей камеры в YUV I420, используя метод transformI420
и отправив формат по параметру:
return libyuv::ConvertToI420(src, srcSize, //src data
dstY, dstWidth, //dst planes
dstU, dstWidth / 2,
dstV, dstWidth / 2,
cropLeft, cropTop, //crop start
srcWidth, srcHeight, //src dimensions
cropRight - cropLeft, cropBottom - cropTop, //dst dimensions
rotationMode,
libyuv::FOURCC_NV21); //libyuv::FOURCC_NV12
После этого преобразования вы сможете правильно работать с libyuv, используя все I420scale
, I420rotate
... и так далее. Ваш метод масштабирования должен выглядеть следующим образом:
JNIEXPORT jint JNICALL
Java_com_aa_project_images_yuv_myJNIcl_scaleI420(JNIEnv *env, jclass type,
jobject srcBufferY,
jobject srcBufferU,
jobject srcBufferV,
jint srcWidth, jint srcHeight,
jobject dstBufferY,
jobject dstBufferU,
jobject dstBufferV,
jint dstWidth, jint dstHeight,
jint filterMode) {
const uint8_t *srcY = static_cast<uint8_t *>(env->GetDirectBufferAddress(srcBufferY));
const uint8_t *srcU = static_cast<uint8_t *>(env->GetDirectBufferAddress(srcBufferU));
const uint8_t *srcV = static_cast<uint8_t *>(env->GetDirectBufferAddress(srcBufferV));
uint8_t *dstY = static_cast<uint8_t *>(env->GetDirectBufferAddress(dstBufferY));
uint8_t *dstU = static_cast<uint8_t *>(env->GetDirectBufferAddress(dstBufferU));
uint8_t *dstV = static_cast<uint8_t *>(env->GetDirectBufferAddress(dstBufferV));
return libyuv::I420Scale(srcY, srcWidth,
srcU, srcWidth / 2,
srcV, srcWidth / 2,
srcWidth, srcHeight,
dstY, dstWidth,
dstU, dstWidth / 2,
dstV, dstWidth / 2,
dstWidth, dstHeight,
static_cast<libyuv::FilterMode>(filterMode));
}
Если вы хотите преобразовать это изображение в JPEG после всего процесса. Вы можете использовать метод I420toNV21
и после этого использовать преобразование Android в YUV в JPEG. Также вы можете использовать libJpegTurbo , которая является дополнительной библиотекой для подобных ситуаций.
Надеюсь, что это вам помогло!