2015-08-13 16 views
9

Sto sviluppando un'applicazione in cui voglio che i filtri vengano applicati come fa lo snapchat, Da quello che posso capire è che stanno usando PagerAdapter ma non so come stiano applicando i filtri sopra l'immagine o video e non è un'altra immagine con filtro applicato ad esso. Qualsiasi idea o frammento di codice che possa fare lo stesso è molto apprezzata per immagini e video e anche per il loro salvataggio. Grazie: D this is what I am trying to achieve[![][1][1]Filtri immagine e video come snapchat in Android

+0

Qualche notizia finora? – Stepango

+0

Nessun indizio, avevo rinunciato a questo, ma lo riprenderò di nuovo. Pubblicherà una soluzione se ottengo qualsiasi –

+0

Qualche progresso? Che ne dici delle maschere per il viso? Qualche indizio su come registrano il video con l'overlay? Le tecnologie/strutture che usano? – GuyZ

risposta

2

Quello che sto facendo qui è sovrapporre due bitmap l'uno sull'altro. Quanto uno dei bitmap dovrebbe essere visibile viene determinato utilizzando il tocco dell'utente. Ho un enume per quale direzione l'utente sta scorrendo sostanzialmente SINISTRA O DESTRA e NESSUNO. A seconda della direzione in cui l'utente scorre bitmap diversi viene applicata alla bitmap corrente.

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

Questo funziona abbastanza bene, solo che non sono testati su dispositivi a bassa memoria considerando non sono riuscito a trovare molti :)

Per un completo controllo di riferimento codice this collegamento fuori. È la mia libreria in cui è possibile catturare immagini applicare filtri e richiamare l'attività di chiamata. È ancora in corso.

+0

Questo frammento mi aiuta molto .. Grazie e saluti – Kuls

+0

Siete i benvenuti :) felice di aiutare: D –

0

Una soluzione alternativa:

rendono l'immagine su un SurfaceTexture. Usa SurfaceTexture come un input di trama "GL_OES_EGL_image_external" di OpenGL in uno shader di frammenti OpenGL. Disegna un quad a schermo intero usando questo framment shader su SurfaceTexture secondario. Renderizza SurfaceTexture secondario in TextureView.

Ottenere questa prima parte di lavoro è la parte difficile. Una volta che hai funzionato, sarai in grado di applicare diversi shader alle immagini, ma non passare da una all'altra come mostrato nell'immagine. Per aggiungere uno scambio uniforme tra le immagini, eseguire il rendering di due diversi shader di frammenti sul SurfaceTexture secondario, utilizzando GL_SCISSOR per dividere lo schermo a metà in base a un valore di offset.

Il vantaggio principale di questo metodo è che utilizzerà una quantità di memoria notevolmente inferiore. La bitmap può essere caricata una volta e dopo essere stata sottoposta a rendering su SurfaceTexture una volta, può essere scartata.

Un vantaggio secondario di questo metodo è che possono essere applicati filtri più complicati e che con un po 'di lavoro extra, sarà possibile anche il rendering dei video.

Se sei interessato a vedere un'implementazione di questa tecnica (che include anche il filtro video), controlla la libreria Kfilter per il filtro e l'elaborazione di foto e video.

+0

È un buon approccio, proverò questo per il filtro video –

+0

Fammi sapere come si va, sono interessato al feedback per questa libreria. –