Android Eclipse如何将渲染的GLsurfaceView保存为* .png图像

时间:2013-03-11 20:09:28

标签: java android eclipse opengl-es photography

我正在制作一个照片效果应用程序。 所以,我从相机加载位图(我保存的原始图像,然后加载)到glsurfaceview并应用了一些效果,但我找不到将更改后的图像保存为图像文件* .png或* .jpg的方法。

我几乎无处不在,但它们不能用于我的应用程序..当我尝试保存时总是强制关闭。

这是我的代码。

我找到了一些保存代码,但我无法工作。

main.xml中

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <android.opengl.GLSurfaceView
        android:id="@+id/effectsview"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="0.05" />

    <GridLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </GridLayout>

        <GridLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:columnCount="1" >

<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" />

<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" />

<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" />

        </GridLayout>

</LinearLayout>

效果选择器和应用程序.java

    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<h; i++, k++)
           {//remember, that OpenGL bitmap is incompatible with Android bitmap
            //and so, some correction need.        
                for(int j=0; j<w; j++)
                {
                     int pix=b[i*w+j];
                     int pb=(pix>>16)&0xff;
                     int pr=(pix<<16)&0x00ff0000;
                     int pix1=(pix&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);
          }


      }

1 个答案:

答案 0 :(得分:1)

我通过交叉编译libpng并通过JNI使用它来将GLSurfaceView保存为PNG。