2014-09-10 8 views
7

Ich war die Entwicklung einer Anwendung Effekte/Rotation/pinch anzuwenden in-out-Funktionalität auf das Bild um es zu vergrößern. Ich habe Demo-Anwendung von https://github.com/Grishu/ImageEffects heruntergeladen.Bildeffekte mit Drehung und Prise zu vergrößern GLSurfaceView Android mit

Es funktioniert gut, jetzt meine Probleme/Fragen sind wie folgt:

  1. Wenden Sie mehrere Effekte auf Bilder mit dem Fortschritt Änderungswert (zB Erste Helligkeit Wirkung und Ergebnis dieser Anwendung gelten andere Wirkung sagen, „Kontrast“ .)

    - problem: im code effekt immer auf originalbild anwenden. So in Code ändern, um Effekt anwenden auf Endbild wie,

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

    Wenn nun Helligkeit Effekt anwenden auf Fortschritt erstes Mal ändern, es funktioniert. Aber wenn ich den gleichen oder ein anderen (Kontrast) Effekt anwenden, jetzt denke ich, auf Wirkung Fortschritt Änderung auf mTextures gelten [1] und das Ergebnis in mTextures [1] gesetzt, so ist es möglich, temporäres mTextures [2] erstellen mTextures speichern [ 1] und wenn der Benutzer den Fortschrittswert ändert, den Effekt auf mTextures [2] anwenden und das Ergebnis auf mTextures [1] setzen, wie es in der if-Bedingung geschieht.

  2. Wie pinch anzuwenden auf den Bilder vergrößern

  3. Rotation Ausgabe: I Bild im Winkel von 90 ° im Uhrzeigersinn gedreht hat, nur durch Werte (90.180.270, etc.) einstellen, aber das Problem ist, wenn sie von 90 Bild-Rotations bis 180, Bildwiedergabe ist nicht richtig. siehe

A) 0 Winkelbild

0 angle image

B) 90 Winkelbild

90 angle image

C) 180 Winkelbild

180 angle image

Antwort

5

Ich habe Grishu des Demo-Projekt geändert: here's a Screen Recording, dann eine Erklärung:

(Bild gedreht wird, mit drei Effekt angewendet - Flip horizontal, crossprocess, Fisheye)

1) Um den Effekt auf das Ergebnis anzuwenden, funktioniert Ihr Vorschlag gut. Ich verstehe nicht wirklich, was du meinst, Fortschrittsänderungseffekt ''. Möchten Sie die Parameter des Effekts einstellen?

2) Gesten haben Sie GLSurfaceView erweitern und implementieren sollten GestureDetector.OnGestureListener und/oder ScaleGestureDetector.OnScaleGestureListener je nach Ihren Bedürfnissen. Siehe TouchGLView hier: Source oder das Snippet unten:

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) Das Bild kann durch Modifizieren des Scheitelpunktes drehen kann, koordiniert und Ansichtsfenster zu berücksichtigen. Sie können auch verschiedene Rotationen anwenden. Sie können die Ansicht (Vertexkoordinaten) selbst drehen (und zoomen) (was den ursprünglichen Texturpuffer nicht beeinflusst) oder Sie können Pixel im Texturpuffer drehen (was einfach für 90 °, 180 ° usw. ist) und dann Aktualisieren Sie Ihre Scheitelpunktkoordinaten, um sie an die neue Bildbreite/-höhe anzupassen.

Hier ist ein Beispiel mit dem Vertex coords zur Manipulation:

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

Ich schlage vor, Sie in OpenGL-Matrizen zu tauchen und all diese Transformationen tun mit ihnen.

Ich habe TextureRenderer Klasse geändert, um GLSurfaceView.Renderer zu implementieren, und änderte renderMode zu RENDERMODE_CONTINUOUSLY.

Schließlich ist die source for the modified demo is here.

+0

Zunächst einmal vielen Dank für die Antwort 1) ist es möglich, Auswirkungen auf Seekbars Fortschrittsänderung anzuwenden? als erste Datei, wenn ich den Effekt von "mTextures [0]" auf "mTextures [1]" und rander textureId "mTextures [1]" anwende. Nach dem Apply-Effekt zuerst, wenn Sie den zweiten Effekt anwenden, sagen Sie "CONTRAST" auf der Fortschrittsanzeige des Seekbars, dann gilt der Effekt von "mTextures [1]" bis "mTextures [1]" und render textureId "mTextures [1]". Sie werden feststellen, dass das Bild schwarz wird. –

+0

Ich denke, wenn ich "mTextures [1]" als frische Textur wiederverwende. wird mein Problem gelöst, weiß aber nicht, wie ich es wiederverwenden soll. 2) Pinch to Zoom: funktioniert gut, aber das Problem mit Bildlauf. irgendeine Idee? 3) Rotation: funktioniert gut. ist es möglich, Rotation mit eingebautem Rationierungseffekt bei (90,180,270, ...) im Uhrzeigersinn anzuwenden. –

+0

Guys Rotation und Zoom funktioniert gut, aber Drag funktioniert nicht ... wie zu lösen. –