2015-08-13 7 views
9

Ich entwickle eine Anwendung, wo ich die Filter wollen den Weg Snapchat angewendet werden tut, Von dem, was ich verstehen kann, ist, dass sie mit PagerAdapter sind, aber ich weiß nicht, wie sie Filter anwenden über das Bild oder Videos und es ist kein anderes Bild mit Filter angewendet. Jede Idee oder Code-Snippet, die das gleiche tun können, wird für Bilder und Videos sowohl geschätzt als auch gespeichert. Danke: D this is what I am trying to achieve[![][1][1]Bild- und Videofilter wie Snapchat in android

+0

Irgendwelche Nachrichten bis jetzt? – Stepango

+0

Keine Ahnung, ich hatte es aufgegeben, aber ich werde es wieder abholen. Werde eine Lösung posten, wenn ich irgendwelche –

+0

Irgendwelche Fortschritte bekomme? Wie wäre es mit den Gesichtsmasken? Irgendwelche Hinweise darauf, wie sie das Video mit dem Overlay aufnehmen? Die Technologien/Frameworks, die sie verwenden? – GuyZ

Antwort

2

Was mache ich hier wird überlagert zwei Bitmaps übereinander. Wie viel eine der Bitmaps sichtbar sein soll, wird durch die Berührung des Benutzers bestimmt. Ich habe eine Aufzählung, in welche Richtung der Benutzer im Grunde LINKS oder RECHTS scrollen und KEINE. Abhängig davon, in welche Richtung der Benutzer scrollt, wird auf die aktuelle Bitmap eine andere Bitmap angewendet.

@Override 
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
    if (mCurrentScrollDirection.ordinal() == ScrollDirection.NONE.ordinal()) { 
     if (distanceX > 0) { 
      mCurrentScrollDirection = ScrollDirection.LEFT; 
     } else { 
      mCurrentScrollDirection = ScrollDirection.RIGHT; 
     } 
    } 
    mTouchX = (int) e2.getX(); 
    overlayBitmaps(mTouchX); 
    return false; 
} 

private void overlayBitmaps(int coordinateX) { 

    switch (mCurrentScrollDirection) { 
     case NONE: { 
      //do nothing here 
      break; 
     } 
     case LEFT: { 
      overlayNextBitmap(coordinateX); 
      break; 
     } 
     case RIGHT: { 
      overlayPreviousBitmap(coordinateX); 
      break; 
     } 
    } 
} 

private void overlayPreviousBitmap(int coordinateX) { 
    mImageCanvas.save(); 

    Bitmap OSBitmap = Bitmap.createBitmap(mCurrentBitmap, coordinateX, 0, mCurrentBitmap.getWidth() - coordinateX, mCurrentBitmap.getHeight()); 
    mImageCanvas.drawBitmap(OSBitmap, coordinateX, 0, null); 

    Bitmap FSBitmap = Bitmap.createBitmap(mPreviousBitmap, 0, 0, coordinateX, mCurrentBitmap.getHeight()); 
    mImageCanvas.drawBitmap(FSBitmap, 0, 0, null); 

    mImageCanvas.restore(); 

    mCapturedImageView.setImageDrawable(new BitmapDrawable(getResources(), mResultBitmap)); 
} 

private void overlayNextBitmap(int coordinateX) { 
    mImageCanvas.save(); 

    Bitmap OSBitmap = Bitmap.createBitmap(mCurrentBitmap, 0, 0, coordinateX, mCurrentBitmap.getHeight()); 
    mImageCanvas.drawBitmap(OSBitmap, 0, 0, null); 

    Bitmap FSBitmap = Bitmap.createBitmap(mNextBitmap, coordinateX, 0, mCurrentBitmap.getWidth() - coordinateX, mCurrentBitmap.getHeight()); 
    mImageCanvas.drawBitmap(FSBitmap, coordinateX, 0, null); 

    mImageCanvas.restore(); 

    mCapturedImageView.setImageDrawable(new BitmapDrawable(getResources(), mResultBitmap)); 
} 

Das funktioniert ganz gut, ich habe auf Low-Memory-Geräte einfach nicht getestet bedenkt, dass ich nicht viele :)

Für vollständige Codereferenzprüfung this Link herausfinden konnte. Es ist meine eigene Bibliothek, in der Sie Bilder aufnehmen, Filter anwenden und einen Rückruf zu den aufrufenden Aktivitäten erhalten können. Es ist immer noch in Arbeit.

+0

Dieses Snippet hilft mir viel .. Danke und Prost – Kuls

+0

Sie sind herzlich willkommen :) glücklich zu helfen: D –

0

Eine alternative Lösung:

Rendern Sie das Bild auf eine SurfaceTexture. Verwenden Sie dieses SurfaceTexture als OpenGL-Textureingabe "GL_OES_EGL_image_external" in einen OpenGL-Fragment-Shader. Zeichne ein Full-Screen-Quad mit diesem Fragment-Shader auf ein sekundäres SurfaceTexture. Rendern Sie die sekundäre SurfaceTexture in eine TextureView.

Das erste Teil zu arbeiten ist der schwierige Teil. Sobald Sie damit fertig sind, können Sie verschiedene Shader auf Bilder anwenden, aber nicht zwischen ihnen wechseln, wie im Bild gezeigt. Um ein weiches Austauschen zwischen Bildern hinzuzufügen, rendern Sie zwei unterschiedliche Fragment-Shader auf der sekundären SurfaceTexture und verwenden Sie GL_SCISSOR, um den Bildschirm abhängig von einem Offset-Wert in zwei Hälften zu zerlegen.

Der Hauptvorteil dieser Methode ist, dass sie deutlich weniger Speicher benötigt. Die Bitmap kann einmal geladen werden und nachdem sie einmal auf der SurfaceTexture gerendert wurde, kann sie verworfen werden.

Ein zweiter Vorteil dieser Methode ist, dass kompliziertere Filter angewendet werden können, und dass Sie mit ein wenig zusätzlicher Arbeit auch Videos rendern können.

Wenn Sie Interesse an einer Implementierung dieser Technik (einschließlich Video-Filterung) haben, finden Sie in der Kfilter Bibliothek für Foto-und Video-Filterung/Verarbeitung.

+0

Es ist eine gute Vorgehensweise, ich werde dies für Videofilter versuchen –

+0

Lassen Sie mich wissen, wie Sie gehen, ich bin an Rückmeldungen interessiert für diese Bibliothek. –