Эффекты изображения с вращением и щепоткой для увеличения с помощью GLSurfaceView Android

Я разрабатывал приложение для применения эффектов / поворота / пинча для увеличения изображения на изображении. Я загрузил демо-приложение из https://github.com/Grishu/ImageEffects .

Он работает хорошо, теперь мои проблемы / вопросы:

  1. Примените несколько эффектов к изображениям со значением изменения хода (например, сначала примените эффект яркости, и результат этого применит другой эффект, скажем, «контраст».)

    – проблема: эффект кода всегда применяется на исходном изображении. Поэтому изменение кода для применения эффекта на конечном изображении,

    if(isApplyEffectOnOriginalImage){//call first time only mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]); }else{ mEffect.apply(mTextures[1], mImageWidth, mImageHeight, mTextures[1]); } 

    Теперь, если применить эффект яркости при изменении хода в первый раз, он отлично работает. Но если я применяю тот же или другой (контрастный) эффект, теперь я думаю, что эффект изменения прогресса применяется к mTextures [1] и результирующему набору в mTextures [1], так что можно создать временные mTextures [2] для хранения mTextures [ 1], и когда пользователь меняет значение эффекта выполнения на mTextures [2] и устанавливает результат на mTextures [1], например, происходит в условии if.

  2. Как применить пинч для увеличения изображения

  3. Проблема с вращением: я вращал изображение под углом 90 градусов по часовой стрелке, просто установив значения (90, 180, 270 и т. Д.), Но проблема заключается в том, что при повороте изображения с 90 до 180 рендеринг изображений неправильный. видеть

A) 0 угол изображения

0 угол изображения

B) 90-кратное изображение

90 угловых изображений

C) 180-кратное изображение

180 угловых изображений

Я модифицировал демонстрационный проект Гришу: вот экранная запись , затем объяснение:

(Изображение повернуто, с тремя применяемыми эффектами – флип горизонтальный, кросспроцесс, рыбий глаз)

1) Для применения эффекта на результат ваше предложение работает нормально. Я не совсем понимаю, что вы подразумеваете под эффектом изменения прогресса ». Вы хотите настроить параметры эффекта?

2) Чтобы иметь жесты, вы должны расширить GLSurfaceView и реализовать GestureDetector.OnGestureListener и / или ScaleGestureDetector.OnScaleGestureListener зависимости от ваших потребностей. См. TouchGLView здесь: Источник или фрагмент ниже:

 private class TouchGLView extends GLSurfaceView implements GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener { private TextureRenderer mRenderer; private GestureDetector mTapDetector; private ScaleGestureDetector mScaleDetector; private float mLastSpan = 0; TouchGLView(Context c) { super(c); // Use Android's built-in gesture detectors to detect // which touch event the user is doing. mTapDetector = new GestureDetector(c, this); mTapDetector.setIsLongpressEnabled(false); mScaleDetector = new ScaleGestureDetector(c, this); // Create an OpenGL ES 2.0 context. setEGLContextClientVersion(2); mRenderer = new TextureRenderer(c); setRenderer(mRenderer); } @Override public boolean onTouchEvent(final MotionEvent e) { // Forward touch events to the gesture detectors. mScaleDetector.onTouchEvent(e); mTapDetector.onTouchEvent(e); return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, final float dx, final float dy) { // Forward the drag event to the renderer. queueEvent(new Runnable() { public void run() { mRenderer.drag(dx, dy); }}); return true; } @Override public boolean onScale(ScaleGestureDetector detector) { // Forward the scale event to the renderer. final float amount = detector.getCurrentSpan() - mLastSpan; queueEvent(new Runnable() { public void run() { mRenderer.zoom(amount); }}); mLastSpan = detector.getCurrentSpan(); return true; } ... } 

3) Вы можете поворачивать изображение, изменяя координаты вершин и принимая во внимание видовые экраны. Кроме того, вы можете применять разные повороты. Вы можете вращать (и масштабировать) сам вид (координаты вершин) (который не влияет на исходный буфер текстур), или вы можете вращать пиксели в буфере текстуры (что легко для 90 °, 180 ° и т. Д.), А затем обновлять Координаты вершин в соответствии с новой шириной / высотой изображения.

Вот пример манипуляции с вершинными коордами:

 private void computeOutputVertices() { if (mPosVertices != null) { float imgAspectRatio = mTexWidth / (float)mTexHeight; float viewAspectRatio = mViewWidth / (float)mViewHeight; float x0, y0, x1, y1; // Set initial vertex coords based in texture aspect if (imgAspectRatio > 1.0f) { x0 = -1.0f ; y0 = -1.0f / imgAspectRatio; x1 = 1.0f ; y1 = 1.0f / imgAspectRatio; } else { x0 = -1.0f *imgAspectRatio; y0 = -1.0f; x1 = 1.0f *imgAspectRatio; y1 = 1.0f; } float[] coords = new float[] { x0, y0, x1, y0, x0, y1, x1, y1 }; // Scale coordinates with mZoom for (int i = 0; i < 8; i++) { coords[i] *= mZoom; } // Rotate coordinates with mRot float cosa = (float)Math.cos(mRot); float sina = (float)Math.sin(mRot); float x,y; for (int i = 0; i < 8; i+=2) { x = coords[i]; y = coords[i+1]; coords[i] = cosa*x-sina*y; coords[i+1] = sina*x+cosa*y; } // Finally scale again to match screen aspect if (viewAspectRatio > 1.0f) { for (int i = 0; i < 8; i+=2) { coords[i] = coords[i]/viewAspectRatio; } } else { for (int i = 1; i < 8; i+=2) { coords[i] = coords[i]*viewAspectRatio; } } mPosVertices.put(coords).position(0); } } 

Я предлагаю вам погрузиться в матрицы OpenGL и использовать все эти преобразования, используя их.

Я изменил класс TextureRenderer для реализации GLSurfaceView.Renderer и изменил renderMode на RENDERMODE_CONTINUOUSLY .

Наконец, источник модифицированной демонстрации находится здесь .