我正在开发一个应用效果/旋转/捏缩以缩放图像功能的应用程序。我已经从https://github.com/Grishu/ImageEffects下载了演示应用程序。

它运作良好,现在我的问题/问题如下:

  • 在具有进度变化值的图像上应用多种效果(例如,首先应用亮度效果,并且此结果应用另一种效果,例如“对比度”。)

    -问题:代码效果中的始终应用于原始图像。因此,更改代码以将效果应用于最终图像,例如,
    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条件一样。
  • 如何应用捏以放大图像
  • 旋转问题:我只是通过设置值(90、180、270等)将图像顺时针旋转90度,但是问题是当将图像从90旋转到180时,图像渲染不正确。

  • A)0角影像

    B)90度影像

    C)180度影像

    最佳答案

    我已经修改了Grishu的演示项目: here's a Screen Recording ,然后进行一些解释:

    (图像旋转,并应用了三种效果-水平翻转,交叉处理, fish 眼)

    1)为了对结果施加效果,您的建议可以正常工作。我真的不明白你所说的``进步改变效果''是什么意思。您要调整效果的参数吗?

    2)要进行手势操作,您应该扩展GLSurfaceView并根据需要实现GestureDetector.OnGestureListener和/或ScaleGestureDetector.OnScaleGestureListener。请在此处查看TouchGLView:Source或以下代码段:

    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)您可以通过修改顶点坐标并考虑视口(viewport)来旋转图像。
    另外,您可以应用不同的旋转。您可以旋转(和缩放) View (顶点坐标)本身(不影响原始纹理缓冲区),也可以旋转纹理缓冲区中的像素(易于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

    最后是source for the modified demo is here

    07-24 09:49
    查看更多