Фильтры изображений и видео, такие как Snapchat в Android

Я разрабатываю приложение, в котором я хочу, чтобы фильтры применялись так же, как это делает Snapchat. Насколько я понимаю, они используют PagerAdapter, но я не знаю, как они применяют фильтры к изображению или видео, и это не другое изображение с примененный к нему фильтр. Любая идея или фрагмент кода, которые могут сделать то же самое, высоко ценятся как для изображений, так и для видео, а также для их сохранения. Спасибо: Dвот чего я пытаюсь добиться[![][1][1]


person PunK _l_ RuLz    schedule 13.08.2015    source источник
comment
Без понятия, я отказался от этого, но я возьму его снова. Опубликую решение, если получу   -  person PunK _l_ RuLz    schedule 29.04.2016
comment
Какой-либо прогресс? Как насчет масок для лица? Любая подсказка о том, как они записывают видео с наложением? Какие технологии/фреймворки они используют?   -  person GuyZ    schedule 30.06.2016
comment
Snapchat приобрела Looksery, и они сделали то, о чем вы сейчас говорите. Я мог бы сделать фильтр, я думаю, у меня есть решение для этого. Но маски для лица требуют очень глубоких знаний.   -  person PunK _l_ RuLz    schedule 13.07.2016
comment
Привет, @GuyZ, я ответил на вопрос. Можете глянуть, если еще нужно. :) Ура и счастливого кодирования.   -  person PunK _l_ RuLz    schedule 19.07.2016


Ответы (2)


Здесь я делаю наложение двух растровых изображений друг на друга. Степень видимости любого из растровых изображений определяется касанием пользователя. У меня есть перечисление, в котором пользователь прокручивает в основном ВЛЕВО ИЛИ ВПРАВО и НЕТ. В зависимости от того, в каком направлении пользователь прокручивает, к текущему растровому изображению применяется разное растровое изображение.

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    if (mCurrentScrollDirection.ordinal() == ScrollDirection.NONE.ordinal()) {
        if (distanceX > 0) {
            mCurrentScrollDirection = ScrollDirection.LEFT;
        } else {
            mCurrentScrollDirection = ScrollDirection.RIGHT;
        }
    }
    mTouchX = (int) e2.getX();
    overlayBitmaps(mTouchX);
    return false;
}

private void overlayBitmaps(int coordinateX) {

    switch (mCurrentScrollDirection) {
        case NONE: {
            //do nothing here
            break;
        }
        case LEFT: {
            overlayNextBitmap(coordinateX);
            break;
        }
        case RIGHT: {
            overlayPreviousBitmap(coordinateX);
            break;
        }
    }
}

private void overlayPreviousBitmap(int coordinateX) {
    mImageCanvas.save();

    Bitmap OSBitmap = Bitmap.createBitmap(mCurrentBitmap, coordinateX, 0, mCurrentBitmap.getWidth() - coordinateX, mCurrentBitmap.getHeight());
    mImageCanvas.drawBitmap(OSBitmap, coordinateX, 0, null);

    Bitmap FSBitmap = Bitmap.createBitmap(mPreviousBitmap, 0, 0, coordinateX, mCurrentBitmap.getHeight());
    mImageCanvas.drawBitmap(FSBitmap, 0, 0, null);

    mImageCanvas.restore();

    mCapturedImageView.setImageDrawable(new BitmapDrawable(getResources(), mResultBitmap));
}

private void overlayNextBitmap(int coordinateX) {
    mImageCanvas.save();

    Bitmap OSBitmap = Bitmap.createBitmap(mCurrentBitmap, 0, 0, coordinateX, mCurrentBitmap.getHeight());
    mImageCanvas.drawBitmap(OSBitmap, 0, 0, null);

    Bitmap FSBitmap = Bitmap.createBitmap(mNextBitmap, coordinateX, 0, mCurrentBitmap.getWidth() - coordinateX, mCurrentBitmap.getHeight());
    mImageCanvas.drawBitmap(FSBitmap, coordinateX, 0, null);

    mImageCanvas.restore();

    mCapturedImageView.setImageDrawable(new BitmapDrawable(getResources(), mResultBitmap));
}

Это работает довольно хорошо, я просто не тестировал устройства с малым объемом памяти, учитывая, что я не смог найти много :)

Полную справку по коду см. в эта ссылка. Это моя собственная библиотека, в которой вы можете захватывать изображения, применять фильтры и получать обратный вызов вызывающей активности. Это все еще продолжается.

person PunK _l_ RuLz    schedule 19.07.2016
comment
Этот фрагмент мне очень помогает .. Спасибо и Удачи - person Kuls; 12.08.2016
comment
Я новичок в Android, мне очень понравился ваш код, и у меня есть простой вопрос, что мне делать, если я хочу добавить более трех фильтров, существующих в вашем проекте, например, если я хочу добавить 5 фильтров. что я должен изменить в вашем коде, я думаю, что вы знаете ответ, не могли бы вы помочь мне, пожалуйста. благодарю вас. - person naima; 18.02.2019
comment
Добавьте тип фильтров, которые вы хотите добавить, в «Фильтры» файла «BitmapFilters». Предоставьте их реализацию Bitmap, и все будет хорошо. - person PunK _l_ RuLz; 19.02.2019
comment
спасибо @PunK l RuLz за ваш ответ, именно это я и сделал в BitmapFilters, но я полностью запутался в классе camera1fragment, особенно в loadImageTask, также в overlayPreviousBitmap и overlayNextBitmap также в shuffleBitmap, не могли бы вы предоставить для меня все модификации, которые я должен сделать в классе camera1fragment, ваш ответ мне очень поможет, большое спасибо. - person naima; 19.02.2019
comment
Я не уверен, с чем вы смущены, но напишите по электронной почте, и я с радостью вам помогу. - person PunK _l_ RuLz; 21.02.2019
comment
Я еще не нашел решения @PunK l RuLz, чего я хочу добиться, очень просто, я просто хочу добавить фильтры, вместо 3 фильтров, которые существуют в этом проекте, я хочу 6 фильтров. не могли бы вы изменить проект и поделиться им со мной на GitHub. я действительно застрял с этой проблемой, пожалуйста, помогите! а это мой gmail: [email protected] - person naima; 27.02.2019
comment
Конечно. Дай мне немного времени. Я помогу тебе. - person PunK _l_ RuLz; 28.02.2019
comment
@PunK_l_RuLz Когда я использую ваш код для добавления фильтров к изображениям, выбранным из галереи, я получаю ошибки 'int android.graphics.Bitmap.getWidth()' on a null object reference Как это решить? - person raghhav; 02.10.2019
comment
Код не предназначен для обработки изображений из Галереи. А NPE возникает из-за того, что «Растровое изображение» либо не создается, либо уничтожается. - person PunK _l_ RuLz; 09.10.2019
comment
Привет @PunK_l_RuLz. Я понял, как обращаться с NPE. Теперь я хочу добавить больше фильтров. Я добавил типы фильтров в BitmapFilters, а также предоставил реализацию Bitmap. Но это не работает. Как это решить? - person raghhav; 12.10.2019
comment
Прошу прощения за поздний ответ, с чем вы столкнулись? Создайте улучшение в репозитории, если вы все еще сталкиваетесь с той же проблемой. - person PunK _l_ RuLz; 18.10.2019
comment
Было бы полезно, если бы вы предоставили инструкции по добавлению дополнительных фильтров. Я создал новый фильтр. Как добавить его в активность? - person raghhav; 19.10.2019

Альтернативное решение:

Визуализируйте изображение на SurfaceTexture. Используйте эту SurfaceTexture в качестве ввода текстуры OpenGL "GL_OES_EGL_image_external" в фрагментный шейдер OpenGL. Нарисуйте полноэкранный четырехугольник с помощью этого фрагментного шейдера на вторичной текстуре поверхности. Визуализируйте вторичную SurfaceTexture в TextureView.

Заставить эту первую часть работать — сложная часть. Как только вы это заработаете, вы сможете применять разные шейдеры к изображениям, но не переключаться между ними, как показано на рисунке. Чтобы добавить плавное переключение между изображениями, визуализируйте два разных фрагментных шейдера на вторичной SurfaceTexture, используя GL_SCISSOR, чтобы разделить экран пополам в зависимости от значения смещения.

Основное преимущество этого метода заключается в том, что он будет использовать значительно меньше памяти. Растровое изображение может быть загружено один раз, и после однократного рендеринга на SurfaceTexture может быть отброшено.

Вторичным преимуществом этого метода является то, что можно применять более сложные фильтры, и что, немного поработав, вы также сможете рендерить видео.

Если вам интересно увидеть реализацию этой техники (включая фильтрацию видео), ознакомьтесь с Библиотека Kfilter для фильтрации/обработки фото и видео.

person isaac.udy    schedule 25.01.2018
comment
Дайте мне знать, как вы идете, мне интересны отзывы об этой библиотеке. - person isaac.udy; 04.02.2018