2017-03-25 8 views
0

画像にフィルタリングを追加しようとしていますが、GLSurfaceView を使用してエフェクトを実行時に変更すると表示されますが、エフェクト間でレンダリングすると、GLSurfaceViewがエフェクトをレンダリングするには遅すぎる

ここ

私のコードがある...

public class EffictActivity extends AppCompatActivity implements GLSurfaceView.Renderer{ 
    private RecyclerView recList; 
    int mCurrentEffect; 
    private GLSurfaceView mEffectView; 
    private int[] mTextures = new int[2]; 
    private EffectContext mEffectContext; 
    private Effect mEffect; 
    Bitmap bm; 
    private TextureRenderer mTexRenderer = new TextureRenderer(); 
    private int mImageWidth; 
    EGL10 egl; 
    private int mImageHeight; 
    Button saveImage; 
    private boolean mInitialized = false; 
    private volatile boolean saveFrame; 
    ProgressDialog mDialog; 
    public void setCurrentEffect(int effect) { 
     mCurrentEffect = effect; 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_effict); 
     saveImage = (Button) findViewById(R.id.effectSave) ; 
     mEffectView = (GLSurfaceView) findViewById(R.id.effectsview); 
     mEffectView.setEGLContextClientVersion(2); 
     mEffectView.setRenderer(this); 
     mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 
     mCurrentEffect = 0; 
     mDialog = Utils.SetProgressBar(mDialog, this); 
     new CountDownTimer(3000 ,1000) { 
      @Override 
      public void onTick(long millisUntilFinished) { 
       mDialog.show(); 
      } 

      @Override 
      public void onFinish() { 
       mDialog.dismiss(); 
      } 
     }.start(); 
     LinearLayoutManager layoutManager 
       = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); 

     recList = (RecyclerView) findViewById(R.id.rc_filter); 
     recList.setHasFixedSize(true); 
     recList.setLayoutManager(layoutManager); 

     FilterAdapterFactory filterAdapter = new FilterAdapterFactory(this); 
     recList.setAdapter(filterAdapter); 

     recList.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() { 
      @Override 
      public void onItemClick(View view, int position) { 
       setCurrentEffect(position); 
       mEffectView.requestRender(); 
      } 
     })); 
     saveImage.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       //    if (mInterstitialAd.isLoaded()) { 
//     mInterstitialAd.show(); 
//    } 
       SaveImage(bm); 

      } 

     }); 

    } 
    private void loadTextures() { 
     // Generate textures 
     GLES20.glGenTextures(2, mTextures, 0); 
     String root = Environment.getExternalStorageDirectory().toString(); 
     Bitmap bitmap = BitmapFactory.decodeFile(root + "/HijabPhoto/" + getIntent().getStringExtra("path")); 
     mImageWidth = bitmap.getWidth(); 
     mImageHeight = bitmap.getHeight(); 
     mTexRenderer.updateTextureSize(mImageWidth, mImageHeight); 
     // Upload to texture 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]); 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 
     // Set texture parameters 
     GLToolbox.initTexParams(); 
     bitmap.recycle(); 
    } 

    private void initEffect() { 
     EffectFactory effectFactory = mEffectContext.getFactory(); 
     if (mEffect != null) { 
      mEffect.release(); 
     } 
     /** 
     * Initialize the correct effect based on the selected menu/action item 
     */ 
     switch (mCurrentEffect) { 

      case 0: 
       break; 

      case 1: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_AUTOFIX); 
       mEffect.setParameter("scale", 0.5f); 
       break; 

      case 2: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_BLACKWHITE); 
       mEffect.setParameter("black", .1f); 
       mEffect.setParameter("white", .7f); 
       break; 

      case 3: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_BRIGHTNESS); 
       mEffect.setParameter("brightness", 2.0f); 
       break; 

      case 4: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_CONTRAST); 
       mEffect.setParameter("contrast", 1.4f); 
       break; 

      case 5: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_CROSSPROCESS); 
       break; 

      case 6: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_DOCUMENTARY); 
       break; 

      case 7: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_DUOTONE); 
       mEffect.setParameter("first_color", Color.YELLOW); 
       mEffect.setParameter("second_color", Color.DKGRAY); 
       break; 

      case 8: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FILLLIGHT); 
       mEffect.setParameter("strength", .8f); 
       break; 

      case 9: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FISHEYE); 
       mEffect.setParameter("scale", .5f); 
       break; 

      case 10: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP); 
       mEffect.setParameter("vertical", true); 
       break; 

      case 11: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP); 
       mEffect.setParameter("horizontal", true); 
       break; 

      case 12: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_GRAIN); 
       mEffect.setParameter("strength", 1.0f); 
       break; 

      case 13: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_GRAYSCALE); 
       break; 

      case 14: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_LOMOISH); 
       break; 

      case 15: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_NEGATIVE); 
       break; 

      case 16: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_POSTERIZE); 
       break; 

      case 17: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_ROTATE); 
       mEffect.setParameter("angle", 180); 
       break; 

      case 18: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SATURATE); 
       mEffect.setParameter("scale", .5f); 
       break; 

      case 19: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SEPIA); 
       break; 

      case 20: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SHARPEN); 
       break; 

      case 21: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_TEMPERATURE); 
       mEffect.setParameter("scale", .9f); 
       break; 

      case 22: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_TINT); 
       mEffect.setParameter("tint", Color.MAGENTA); 
       break; 

      case 23: 
       mEffect = effectFactory.createEffect(EffectFactory.EFFECT_VIGNETTE); 
       mEffect.setParameter("scale", .5f); 
       break; 

      default: 
       break; 

     } 
    } 

    private void applyEffect() { 
     mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]); 
    } 

    private void renderResult() { 
     if (mCurrentEffect != 0) { 
      // if no effect is chosen, just render the original bitmap 
      mTexRenderer.renderTexture(mTextures[1]); 
     } else { 
      saveFrame=true; 
      // render the result of applyEffect() 
      mTexRenderer.renderTexture(mTextures[0]); 
     } 
    } 


    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 

    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     if (mTexRenderer != null) { 
      mTexRenderer.updateViewSize(width, height); 
     } 

    } 

    @Override 
    public void onDrawFrame(GL10 gl) { 

     egl = (EGL10) EGLContext.getEGL(); 
     gl = (GL10)egl.eglGetCurrentContext().getGL(); 
     if (!mInitialized) { 
      // Only need to do this once 
      mEffectContext = EffectContext.createWithCurrentGlContext(); 
      mTexRenderer.init(); 
      loadTextures(); 
      mInitialized = true; 
     } 
     if (mCurrentEffect != 0) { 
      // if an effect is chosen initialize it and apply it to the texture 
      initEffect(); 
      applyEffect(); 
     } 
     renderResult(); 
     bm = createBitmapFromGLSurface(0 ,0, mImageWidth , mImageHeight , gl); 
     SaveImage(bm); 
    } 



    private void SaveImage(Bitmap finalBitmap) { 
     String root = Environment.getExternalStorageDirectory().toString(); 
     File myDir = new File(root + "/HijabPhoto"); 
     myDir.mkdirs(); 
     String fileName = getIntent().getStringExtra("path"); 
     File file = new File(myDir, fileName); 
     if (file.exists()) file.delete(); 
     try { 
      FileOutputStream out = new FileOutputStream(file); 
      finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out); 
      Toast.makeText(EffictActivity.this, getString(R.string.imageSavedSuccrss), Toast.LENGTH_SHORT).show(); 
      Log.w("FILE PATH===", file.getPath().toString()); 
      String path = file.getPath().toString(); 
      addImageToGallery(path, EffictActivity.this); 
      out.flush(); 
      out.close(); 
//   if (mInterstitialAd.isLoaded()) { 
//    mInterstitialAd.show(); 
//   } 
      Intent sharin = new Intent(EffictActivity.this,ShareActivity.class); 
      sharin.putExtra("path",fileName); 
      Log.w("file path",""+file.getPath().toString()); 
      startActivity(sharin); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    public static void addImageToGallery(final String filePath, final Context context) { 
     ContentValues values = new ContentValues(); 
     values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis()); 
     values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); 
     values.put(MediaStore.MediaColumns.DATA, filePath); 
     context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
    } 

    private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl) 
      throws OutOfMemoryError { 
     int bitmapBuffer[] = new int[w * h]; 
     int bitmapSource[] = new int[w * h]; 
     IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer); 
     intBuffer.position(0); 

     try { 
      gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer); 
      int offset1, offset2; 
      for (int i = 0; i < h; i++) { 
       offset1 = i * w; 
       offset2 = (h - i - 1) * w; 
       for (int j = 0; j < w; j++) { 
        int texturePixel = bitmapBuffer[offset1 + j]; 
        int blue = (texturePixel >> 16) & 0xff; 
        int red = (texturePixel << 16) & 0x00ff0000; 
        int pixel = (texturePixel & 0xff00ff00) | red | blue; 
        bitmapSource[offset2 + j] = pixel; 
       } 
      } 
     } catch (GLException e) { 
      return null; 
     } 

     return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888); 
    } 


} 

任意の助けてください...

+0

onSurfaceCreated()メソッドは空で、すべての作業はonDrawFrame()メソッドにあります。最良の選択肢はglReadPixels()であり、GLスレッドから離れて処理するために別のスレッドにデータを送信することです。 – WLGfx

+0

コードでこれを行う方法を教えてください。 –

答えて

1

はあまりにも遅いメモリとonDrawFrame方法で行うとしても、外部ストレージへのアクセスがあります。

  • あなたはシェーダーとテクスチャを(それが問題の少なくともだ)作成している
  • あなたはその後、
  • そして、最も遅い部分にデータをコピーするたびに、新しいビットマップを作成している、あなたそれを外部ディレクトリに保存しています。

これは問題です。

+0

テクスチャを保存する方法を見つけようとしましたが、どこか他の場所でonDrawFrameを見つけようとしましたが、何も見つからない場合は、解決方法を教えてください。 –

+0

私はそれを解決するonDrawFrameから関数savePhotoを削除していただきありがとうございます:) –