Ранее мы уже рассказывали больше о рендеринге и обработке видео. В этой статье мы хотим поговорить о изображениях. По сравнению с видео изображения действительно относительно просты. Мы знаем, что видео по существу состоит из кадров «изображений». их все понимают. Видео уже есть, нужно еще узнать о картинках? Рендеринг изображений имеет сходство с видео, но также имеет свои уникальные особенности.
Рендеринг видео обычно представляет собой рендеринг в реальном времени.,Используйте SurfaceView или TextureView.,ImageView обычно используется для рендеринга.,Путь может быть установлен,Вы также можете установить растровое изображение,Плюс холст и краска,Я непобедим,Может достигать множественных и разнообразных эффектов。ImageViewДействительно ли он непобедим??
Из приведенного выше чата мы узнали, что у ImageView есть две проблемы с обработкой изображений:
Как связаны изображения рендеринга ImageView и рендеринг за кадром? OpenGL имеет концепцию внеэкранного рендеринга, который, как следует из названия, представляет собой внеэкранный рендеринг, то есть открытие нового буфера для операций за пределами текущего экранного буфера. Внеэкранный рендеринг происходит на уровне графического процессора, будет создан новый буфер рендеринга и OpenGL Конвейер многопроходного рендеринга, переключение графического контекста приведет к дополнительным накладным расходам, увеличению GPU рабочая нагрузка. На самом деле, судя по описанию,Просто знай, как выйти из экранарендеринг Это больше влияет на производительность。
Противоположностью закадрового рендеринга является живой рендеринг.,Или текущий рендеринг экрана,ЦП вычисляет кадр и другие атрибуты,Отправьте рассчитанный контент в графический процессор для рендеринга.,После завершения графического рендеринга он будет помещен в буфер кадра экрана.,Затем контроллер будет переходить в область кэша экрана, чтобы время от времени считывать полезный контент рендеринга.,таким образом отображается. Как реализовать рендеринг в картинках в реальном времени? Конечно, это SurfaceView,Так как это рендеринг в реальном времени,Должна быть концепция холста,В предыдущей статье очень четко было указаноSurfaceViewСуть полотна。Если вы не уверены, вы можете прочитать предыдущую статью.:Подключите внешнюю среду рендеринга к плееру。
По нашему мнению, SurfaceView обычно больше связан с коллекцией видео или камер, и его относительно редко используют для рендеринга изображений. Но для обеспечения рендеринга изображений в реальном времени SurfaceView действительно является очень хорошим носителем.
Создать среду EGL
int EGLCore::Init(EGLContext shared_context, int egl_version) {
if (egl_version == 0) {
egl_version = 2;
}
EGLint num_configs;
const EGLint attributes[] = {
EGL_BUFFER_SIZE, 32,
EGL_ALPHA_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_NONE
};
if ((display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) {
LOGE("eglGetDisplay() returned error %d", eglGetError());
return Error::OPENGL_DISPLAY_ERROR;
}
if (!eglInitialize(display_, 0, 0)) {
LOGE("eglInitialize() returned error %d", eglGetError());
return Error::OPENGL_INITIALIZE_ERROR;
}
if (!eglChooseConfig(display_, attributes, &config_, 1, &num_configs)) {
LOGE("eglChooseConfig() returned error %d", eglGetError());
Release();
return Error::OPENGL_CONFIG_ERROR;
}
EGLint eglContextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, static_cast<EGLint>(egl_version), EGL_NONE };
context_ = eglCreateContext(display_, config_, shared_context, eglContextAttributes);
if (context_ == nullptr) {
LOGE("eglCreateContext() returned error %d", eglGetError());
Release();
return Error::OPENGL_CREATE_CONTEXT_ERROR;
}
return 0;
}
Поверхность для NativeWindow, сборка EGLSurface
JNIEnv *env = nullptr;
int ret = get_env(&env);
if (env != nullptr) {
native_window_ = ANativeWindow_fromSurface(env, surface);
}
if (ret == JNI_EDETACHED) {
detach_env();
}
EGLSurface EGLCore::CreateWindowSurface(ANativeWindow *window) {
EGLSurface surface = EGL_NO_SURFACE;
EGLint format;
if (window == nullptr) {
LOGE("%s window is null.", __func__);
return surface;
}
if (!eglGetConfigAttrib(display_, config_, EGL_NATIVE_VISUAL_ID, &format)) {
LOGE("%s eglGetConfigAttrib() returned error %d", __func__, eglGetError());
Release();
return surface;
}
ANativeWindow_setBuffersGeometry(window, 0, 0, format);
if (!(surface = eglCreateWindowSurface(display_, config_, window, nullptr))) {
LOGE("%s eglCreateWindowSurface() returned error %d", __func__, eglGetError());
}
return surface;
}
Рендеринг текстуры изображения
if (render_screen_ == nullptr) {
render_screen_ = new effect::OpenGL();
}
render_screen_->SetOutput(surface_width_, surface_height_);
render_screen_->ProcessImage(process_id);
if (!egl_core_->SwapBuffers(egl_surface_)) {
LOGE("eglSwapBuffers error: %d surface: %d", eglGetError(), (egl_surface_ == EGL_NO_SURFACE));
}
Process_id окончательного рендеринга выше — это текстура, привязанная к FBO.
Что мы можем сделать, визуализируя изображения? Мы можем добиться самых разных эффектов.
Например, некоторые эффекты маски видео, эффекты фильтров и эффекты настройки цвета. Давайте рассмотрим простой эффект маски видео.
Благодаря этой статье вы сможете сделать выводы из одного примера и создать еще несколько интересных эффектов.