Я хочу применить эффект серого к изображению, используя NDK.
Для этого я много гуглил, но нашел тот же результат, который возвращает изображение в некоторой степени как негатив (это то, во что я верю).
Что я хочу ::
Например ::
У меня есть это оригинальное изображение
После применения эффекта оттенков серого это должно быть так:
Что я пробовал ::
Я хочу добиться этой функциональности с помощью NDK, чтобы я создал одну функцию в файле .cpp
JNIEXPORT void JNICALL Java_com_example_ndksampleproject_MainActivity_jniConvertToGray(JNIEnv * env, jobject obj, jobject bitmapcolor,jobject bitmapgray)
{
AndroidBitmapInfo infocolor;
void* pixelscolor;
AndroidBitmapInfo infogray;
void* pixelsgray;
int ret;
int y;
int x;
LOGI("convertToGray");
if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infogray)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infocolor.width,infocolor.height,infocolor.stride,infocolor.format,infocolor.flags);
if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
return;
}
LOGI("gray image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infogray.width,infogray.height,infogray.stride,infogray.format,infogray.flags);
if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) {
LOGE("Bitmap format is not A_8 !");
return;
}
if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsgray)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
LOGI("unlocking pixels height = %d",infocolor.height);
// modify pixels with image processing algorithm
for (y=0;y<infocolor.height;y++) {
argb * line = (argb *) pixelscolor;
uint8_t * grayline = (uint8_t *) pixelsgray;
for (x=0;x<infocolor.width;x++) {
grayline[x] = 0.3 * line[x].red + 0.59 * line[x].green + 0.11*line[x].blue;
}
pixelscolor = (char *)pixelscolor + infocolor.stride;
pixelsgray = (char *) pixelsgray + infogray.stride;
}
LOGI("unlocking pixels");
AndroidBitmap_unlockPixels(env, bitmapcolor);
AndroidBitmap_unlockPixels(env, bitmapgray);
}
Вышеупомянутая функция возвращает мне результат, как это:
Этот эффект выглядит как что-то вроде негатива изображения.
Дайте мне знать, если вам нужно что-нибудь с моей стороны ..
Пожалуйста, помогите мне решить эту проблему, так как я застрял в этом в течение многих часов.
Спасибо заранее…
РЕДАКТИРОВАТЬ ::
Предложение floppy12 ::
for (y=0;y<infocolor.height;y++) {
argb * line = (argb *) pixelscolor;
uint8_t * grayline = (uint8_t *) pixelsgray;
for (x=0;x<infocolor.width;x++) {
grayline[x] = (255-0.3 * line[x].red) + (255-0.59 * line[x].green) + (255-0.11*line[x].blue)/3;
}
pixelscolor = (char *)pixelscolor + infocolor.stride;
pixelsgray = (char *) pixelsgray + infogray.stride;
}
Выход ::
РЕДАКТИРОВАТЬ 2 ::
Я сделал простую модификацию изображения, и оно возвращает мне то, что я хотел, но изображение потеряло свою яркость.
Это изменения, которые я сделал в нативной функции ..
for (y=0;y<infocolor.height;y++) {
argb * line = (argb *) pixelscolor;
uint8_t * grayline = (uint8_t *) pixelsgray;
for (x=0;x<infocolor.width;x++) {
grayline[x] = ((255-0.3 * line[x].red) + (255-0.59 * line[x].green) + (255-0.11*line[x].blue))/3;
}
pixelscolor = (char *)pixelscolor + infocolor.stride;
pixelsgray = (char *) pixelsgray + infogray.stride;
}
Результат (изображение отображается в градациях серого, но теряет яркость):
Чтобы получить изображение в оттенках серого, каждый пиксель должен иметь одинаковое количество красного, зеленого и синего
Возможно, используйте красный компонент и примените его к зеленому и синему в ваших вычислениях серой линии
или используйте формулу (R + G + B) / 3 = серый
Отрицательные изображения обычно получаются путем сдвига каждого компонента:
NegR = 255 — серыйR
и так далее
Таким образом, вы можете попытаться вычислить grayscal [x] = (255 — 0,3 * line [x]) + …
Изменить для яркости:
Чтобы получить лучшую яркость, попробуйте добавить фиксированное значение к вычислению в градациях серого:
G += Bness;
Здесь кажется, что Bness должен быть отрицательным, если вы переходите от 255 (черный) к 0 (белый) по какой-то странной причине. Вы хотите установить нижний предел, чтобы значение 0 не превышало 0, а затем попробуйте:
G = max(0, G+Bness);
Я рекомендую что-то вроде Bness = -25
Изменить яркость реализации:
// Declare a global variable for your brightness - outside your class
static uint8_t bness = -25;
// In your grayscale computation function
for y...
for x...
grayscale[x] = ( (255-0.3*line[x].red) + ..... ) /3 ;
int16_t gBright = grayscale[x] + bness;
grayscale[x] = MAX( 0, gBright );
Других решений пока нет …