title: Android Eclipse How can i save rendered GLsurfaceView as *.png image
body: <p>hi i'm making a photograph effect app.
  So,i loaded bitmap from camera(i saved orginal image and then loaded) to glsurfaceview and applied some effects but i couldn't find a way of saving changed image as image file *.png or *.jpg.</p>
  
  <p>i looked almost everywhere ,but they aren't usable for my app.. always force close when i try save.</p>
  
  <p>Here is my code.</p>
  
  <p>i found some save codes but i couldn't get work.</p>
  
  <p>main.xml</p>
  
  <pre><code> &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical" &gt;
  
      &lt;android.opengl.GLSurfaceView
          android:id="@+id/effectsview"
          android:layout_width="fill_parent"
          android:layout_height="0dp"
          android:layout_weight="0.05" /&gt;
  
      &lt;GridLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content" &gt;
      &lt;/GridLayout&gt;
  
          &lt;GridLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:columnCount="1" &gt;
  
  &lt;Button
      android:id="@+id/button1"
      android:layout_width="159dp"
      android:layout_height="wrap_content"
      android:layout_column="0"
  
      android:layout_row="0"
      android:onClick="saverenderedimage"
          android:layout_gravity="left|top"
      android:text="Save Image" /&gt;
  
  &lt;Button
      android:id="@+id/Button01"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_gravity="left|top"
      android:onClick="gomain"
      android:text="Go Main Menu without saving" /&gt;
  
  &lt;Button
      android:id="@+id/button2"
      android:layout_width="156dp"
      android:layout_column="0"
      android:layout_gravity="right|top"
      android:layout_row="0"
      android:onClick="sharedialog"
      android:text="Share" /&gt;
  
          &lt;/GridLayout&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>Effect selector and applier .java</p>
  
  <pre><code>    public class Effects_selevtor extends Activity implements GLSurfaceView.Renderer {
  
  
           i declared some strings ints (deleted)
  
        String imagefilepath =  Environment.getExternalStorageDirectory().getAbsolutePath() + "/filename.jpg";
  
        int mCurrentEffect;
  
        public void setCurrentEffect(int effect) {
            mCurrentEffect = effect;
        }
  
  
        public void onCreate(Bundle savedInstanceState) {
              this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_effects_selevtor);
            mEffectView = (GLSurfaceView) findViewById(R.id.effectsview);
            mEffectView.setEGLContextClientVersion(2);
            mEffectView.setRenderer(this);
            mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
            mCurrentEffect = R.id.none;
  
            Uri imageFileUri = Uri.parse("file:///sdcard/filename.jpg");
              Intent cameraIntent = new Intent(
                      android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
              cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
              startActivityForResult(cameraIntent, 2);
  
  
  
        }
  
  
  
        public void gomain(View View) {
  
              startActivity(new Intent(Effects_selevtor.this,HelloEffects.class));
  
          }
  
  
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  
  
  
          if (requestCode == 2) {
  
  
              try {
  
                  if (bitmap != null) {
                    bitmap.recycle();
                  }
  
  
  
                  GLES20.glGenTextures(2, mTextures, 0);
  
                  // Load input bitmap
                  Bitmap bitmap = BitmapFactory.decodeFile(imagefilepath);
                  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();
  
                  Toast.makeText(getApplicationContext(), "Touch your phone's Menu button to select effects ",  Toast.LENGTH_SHORT).show();
  
  
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
        }
  
  
        public static Bitmap SavePixels(int x, int y, int w, int h, GL10 gl)
        {  
             int b[]=new int[w*(y+h)];
             int bt[]=new int[w*h];
             IntBuffer ib=IntBuffer.wrap(b);
             ib.position(0);
             gl.glReadPixels(x, 0, w, y+h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
  
             for(int i=0, k=0; i&lt;h; i++, k++)
             {//remember, that OpenGL bitmap is incompatible with Android bitmap
              //and so, some correction need.        
                  for(int j=0; j&lt;w; j++)
                  {
                       int pix=b[i*w+j];
                       int pb=(pix&gt;&gt;16)&amp;0xff;
                       int pr=(pix&lt;&lt;16)&amp;0x00ff0000;
                       int pix1=(pix&amp;0xff00ff00) | pr | pb;
                       bt[(h-k-1)*w+j]=pix1;
                  }
             }
  
  
             Bitmap sb=Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
             return sb;
        }
  
          public static void SavePNG(int x, int y, int w, int h, String name, GL10 gl)
          {
              Bitmap bmp=SavePixels(x,y,w,h,gl);
              try 
              {
                  FileOutputStream fos=new FileOutputStream("/sdcard/CamWay/"+name);
                  bmp.compress(CompressFormat.PNG, 100, fos);
                  try 
                  {
                      fos.flush();
                  } 
                  catch (IOException e) 
                  {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  try 
                  {
                      fos.close();
                  } 
                  catch (IOException e) 
                  {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
  
              } 
              catch (FileNotFoundException e) 
              {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }       
          }
  
  
            public void saverenderedimage(View view) {
  
  
  //i tried save but it not worked i don't understand what should i declare for "gl" 
  
                SavePNG(0, 0,mEffectView.getWidth() , mEffectView.getHeight(), "CamWay.png", gl);
              //  SavePNG(0, 0,mEffectView.getWidth() , mEffectView.getHeight(), imagefilepath, gl);
                startActivity(new Intent(Effects_selevtor.this,HelloEffects.class));
  
              }
  
  
        public void OnClickselector(View arg0) {
  
  
          startActivity(new Intent(Effects_selevtor.this,HelloEffects.class));
       }
  
  
        private void loadTextures() {
            // Generate textures
            GLES20.glGenTextures(2, mTextures, 0);
  
  
            // Load input bitmap
            Bitmap bitmap = BitmapFactory.decodeFile(imagefilepath);
  
  
            // Load input bitmap
  
            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();
        }
  
        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 R.id.none:
                    break;
  
  
  
                case R.id.vignette:
                    mEffect = effectFactory.createEffect(
                            EffectFactory.EFFECT_VIGNETTE);
                    mEffect.setParameter("scale", .5f);
                    break;
  
      //and a lot effect more i deleted for readability
  
                default:
                    break;
  
            }
        }
  
        private void applyEffect() {
            mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]);
        }
  
        private void renderResult() {
            if (mCurrentEffect != R.id.none) {
                // if no effect is chosen, just render the original bitmap
                mTexRenderer.renderTexture(mTextures[1]);
            }
            else {
                // render the result of applyEffect()
                mTexRenderer.renderTexture(mTextures[0]);
            }
        }
  
        @Override
        public void onDrawFrame(GL10 gl) {
            if (!mInitialized) {
                //Only need to do this once
                mEffectContext = EffectContext.createWithCurrentGlContext();
                mTexRenderer.init();
                loadTextures();
                mInitialized = true;
            }
            if (mCurrentEffect != R.id.none) {
                //if an effect is chosen initialize it and apply it to the texture
                initEffect();
                applyEffect();
            }
            renderResult();
  
  
  
        }
  
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            if (mTexRenderer != null) {
                mTexRenderer.updateViewSize(width, height);
            }
  
  
        }
  </code></pre>