2014-09-10 21 views
7

Stavo sviluppando un'applicazione per applicare effetti/rotazione/pizzico alla funzionalità di zoom in-out sull'immagine. Ho scaricato un'applicazione demo da https://github.com/Grishu/ImageEffects.Effetti immagine con rotazione e pizzico per zoom utilizzando GLSurfaceView Android

Funziona bene, ora i miei problemi/domande sono le seguenti:

  1. applicare effetti sulle immagini con modificare il valore di avanzamento (ad esempio applicare prima effetto luminosità e il risultato di questa applicare un altro effetto dice "contrasto" .)

    - problema: nell'effetto del codice si applicano sempre sull'immagine originale. Quindi, cambiare il codice per applicare l'effetto immagine finale su come,

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

    Ora, se applicare l'effetto di luminosità sul progresso cambiare prima volta funziona benissimo. Ma se applico lo stesso effetto o altro (contrasto), ora penso che l'effetto di cambiamento del progresso si applichi a mTextures [1] e result set in mTextures [1], quindi è possibile creare mTextures [2] temporanee per memorizzare mTextures [ 1] inizialmente e quando l'utente modifica il valore di avanzamento applica l'effetto su mTextures [2] e imposta il risultato su mTextures [1] come accade in condizione if.

  2. Come applicare pinch to zoom sulle immagini

  3. problema

    rotazione: sono stato a rotazione dell'immagine a un angolo di 90 in senso orario, semplicemente impostando valori (90.180.270, etc.), ma il problema è quando si ruota un'immagine da 90 a 180, il rendering delle immagini non è corretto. vedere

A) immagine 0 angolo

0 angle image

B) immagine 90 angolo

90 angle image

C) immagine 180 Angolo

180 angle image

risposta

5

Ho modificato il progetto di Grishu demo: here's a Screen Recording, quindi qualche spiegazione:

(immagine ruotata, con tre effetto applicato - capovolgere orizzontale, crossprocess, fisheye)

1) Per applicare l'effetto sul risultato, il tuo suggerimento funziona correttamente. Non capisco cosa intendi per "progresso cambia effetto". Vuoi sintonizzare i parametri dell'effetto?

2) Per i gesti è necessario estendere lo GLSurfaceView e implementare GestureDetector.OnGestureListener e/o ScaleGestureDetector.OnScaleGestureListener in base alle proprie esigenze. Vedere TouchGLView qui: Source, o il frammento di seguito:

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) È possibile ruotare l'immagine modificando vertice coordina e tenendo conto finestre. Inoltre, è possibile applicare diverse rotazioni. È possibile ruotare (e ingrandire) la vista (coordinate del vertice) stessa (che non influisce sul buffer di texture originale) oppure è possibile ruotare i pixel nel buffer texture (che è facile per 90 °, 180 °, ecc.) E quindi aggiorna le coordinate del tuo vertice per abbinare la nuova larghezza/altezza dell'immagine.

Ecco un esempio per la manipolazione con le coordinate dei vertici:

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); 
    } 
} 

suggerisco di immergersi in matrici OpenGL e fare tutte queste trasformazioni che li utilizzano.

Ho modificato la classe TextureRenderer per implementare GLSurfaceView.Renderer e modificato la modalità di rendering su RENDERMODE_CONTINUOUSLY.

Infine, il source for the modified demo is here.

+0

Prima di tutto grazie per la risposta 1) è possibile applicare l'effetto sul cambio di avanzamento della barra di ricerca? come funziona la prima volta quando applico l'effetto da "mTextures [0]" a "mTextures [1]" e rander textureId "mTextures [1]". dopo applicare l'effetto la prima volta, se si applica il secondo effetto dire "CONTRAST" sul cambio di avanzamento della barra di ricerca, l'effetto si applica da "mTextures [1]" a "mTextures [1]" e render textureId "mTextures [1]". noterai che l'immagine sarà oscurata. –

+0

Penso che riutilizzi "mTextures [1]" come texture fresca. risolverò il mio problema, ma non so come riutilizzarlo. 2) Pizzica per ingrandire: funziona bene, ma il problema con l'immagine a scorrimento. qualche idea? 3) Rotazione: funziona bene. è possibile applicare la rotazione usando la build in effetto di razione a (90,180,270, ...) in senso orario. –

+0

La rotazione e lo zoom dei ragazzi funzionano bene ma Drag non funziona ... come risolvere. –