Project

General

Profile

« Previous | Next » 

Revision b9615af9

Added by Leszek Koltunski over 8 years ago

Save PNG effect almost finished. Supporting App (hopefully!) completely finished.

What remains to be done: put actual saving of the Bitmap in a separate thread, away from the Graphics thread!!

View differences:

src/main/java/org/distorted/examples/listener/ListenerRenderer.java
61 61
      }
62 62
   
63 63
///////////////////////////////////////////////////////////////////////////////////////////////////
64
// the library sending messages to us
64 65

  
65
   public void effectMessage(EffectMessage em, long effectID, int effectType, long bitmapID)
66
   public void effectMessage(final EffectMessage em, final long effectID, final int effectName, final long bitmapID, final String message)
66 67
     {
67 68
     switch(em)
68 69
        {
src/main/java/org/distorted/examples/save/SaveRenderer.java
4 4
import java.io.File;
5 5
import java.io.IOException;
6 6
import java.io.InputStream;
7
import java.util.Vector;
7 8

  
8 9
import javax.microedition.khronos.egl.EGLConfig;
9 10
import javax.microedition.khronos.opengles.GL10;
......
12 13

  
13 14
import org.distorted.library.Distorted;
14 15
import org.distorted.library.DistortedBitmap;
16
import org.distorted.library.EffectListener;
17
import org.distorted.library.EffectMessage;
15 18
import org.distorted.library.EffectTypes;
16 19
import org.distorted.library.Float1D;
17 20
import org.distorted.library.Float2D;
18 21
import org.distorted.library.Float4D;
19 22
import org.distorted.library.Interpolator1D;
20 23

  
24
import android.app.Activity;
21 25
import android.graphics.Bitmap;
22 26
import android.graphics.BitmapFactory;
23 27
import android.opengl.GLES20;
24 28
import android.opengl.GLSurfaceView;
25 29
import android.os.Environment;
30
import android.widget.Toast;
26 31

  
27 32
///////////////////////////////////////////////////////////////////////////////////////////////////
28 33

  
29
class SaveRenderer implements GLSurfaceView.Renderer 
30
{
31
    private GLSurfaceView mView;
32
    private static DistortedBitmap mGirl;
33
    private Float2D pLeft, pRight;
34
    private Float4D sinkRegion;
35
    private static Interpolator1D diSink;
36
    private static Float1D s0;
37
    
38
    private int bmpHeight, bmpWidth;
39
    
40
    private static float boobsSink;
41
    
34
class SaveRenderer implements GLSurfaceView.Renderer ,EffectListener
35
  {
36
  private GLSurfaceView mView;
37
  private static DistortedBitmap mGirl;
38
  private Float2D pLeft, pRight;
39
  private Float4D sinkRegion;
40
  private static Interpolator1D diSink;
41
  private static Float1D s0;
42

  
43
  private int bmpHeight, bmpWidth;
44
  private static int scrHeight, scrWidth;
45
  private static float boobsSink;
46

  
47
  private static class SaveInfo
48
    {
49
    private long id;
50
    private String path;
51

  
52
    SaveInfo(long id, String path)
53
      {
54
      this.id   =   id;
55
      this.path = path;
56
      }
57
    }
58

  
59
  private static Vector<SaveInfo> mSaveInfo;  // Vector keeping all the information about the PATH
60
                                              // where current 'SAVE' effects are saving to and also
61
                                              // the IDs of the effects.
62
                                              // We need to have a whole Vector because there can be
63
                                              // many concurrent 'SAVE' operations (click 'SAVE',
64
                                              // don't wait for the Toast to appear, immediately
65
                                              // click again! )
66

  
42 67
///////////////////////////////////////////////////////////////////////////////////////////////////
43 68

  
44
   public SaveRenderer(GLSurfaceView v) 
45
      {
46
      mView = v;
69
  public SaveRenderer(GLSurfaceView v)
70
    {
71
    mView = v;
47 72
      
48
      boobsSink  = 1.0f;
73
    boobsSink  = 1.0f;
49 74
      
50
      pLeft = new Float2D(132, 264);
51
      pRight= new Float2D(247, 264);
75
    pLeft = new Float2D(132, 264);
76
    pRight= new Float2D(247, 264);
52 77
      
53
      // Make the boobs bigger
54
      sinkRegion = new Float4D(0,0,60,60);
78
    sinkRegion = new Float4D(0,0,60,60);
55 79
      
56
      s0 = new Float1D(boobsSink);
80
    s0 = new Float1D(boobsSink);
57 81
      
58
      diSink = new Interpolator1D(); 
59
      diSink.setCount(0.5f);
60
      diSink.setDuration(0);
61
      diSink.add(s0);
62
      }
82
    diSink = new Interpolator1D();
83
    diSink.setCount(0.5f);
84
    diSink.setDuration(0);
85
    diSink.add(s0);
86

  
87
    mSaveInfo = new Vector<>();
88
    }
63 89

  
64 90
///////////////////////////////////////////////////////////////////////////////////////////////////
65 91

  
66
   public static void setSize(float s)
67
     {
68
     boobsSink = s;
69
     s0.set(boobsSink);
70
     }
92
  public static void setSize(float s)
93
    {
94
    boobsSink = s;
95
    s0.set(boobsSink);
96
    }
71 97

  
72 98
///////////////////////////////////////////////////////////////////////////////////////////////////
73 99

  
74
   public static void Save()
75
     {
76
     File file;
77
     String filePath;
78
     int lowestNotFound = 1;
79

  
80
     while(true)
81
       {
82
       filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/girl" + lowestNotFound +".png";
83
       file = new File(filePath);
84

  
85
       if( !file.exists() )
86
         {
87
         android.util.Log.e("SAVE", "Saving to "+file.getAbsolutePath());
88
         mGirl.savePNG(file.getAbsolutePath());
89
         break;
90
         }
91
       lowestNotFound++;
92
       }
93
     }
100
  public static void Save()
101
    {
102
    File file;
103
    int lowestNotFound = 1;
104
    String path;
94 105

  
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96
   
97
   public void onDrawFrame(GL10 glUnused) 
106
    while(true)
98 107
      {
99
      GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
100
      GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
101
      
102
      mGirl.draw(System.currentTimeMillis());
108
      path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/girl" + lowestNotFound +".png";
109
      file = new File(path);
110

  
111
      if( !file.exists() )
112
        {
113
        long id= mGirl.savePNG(file.getAbsolutePath(),0,0,scrWidth,scrHeight);
114
        mSaveInfo.add(new SaveInfo(id,path));
115
        break;
116
        }
117
      lowestNotFound++;
103 118
      }
119
    }
104 120

  
105 121
///////////////////////////////////////////////////////////////////////////////////////////////////
106
    
107
    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
108
      { 
109
      mGirl.abortEffects(EffectTypes.MATRIX);
110
      
111
      if( bmpHeight/bmpWidth > height/width )
112
        {
113
        int w = (height*bmpWidth)/bmpHeight;
114
        mGirl.move((width-w)/2 ,0, 0);
115
        mGirl.scale((float)height/bmpHeight);
122
// the library sending messages to us. This does not run on this UI thread!
123

  
124
  public void effectMessage(final EffectMessage em, final long effectID, final int effectName, final long bitmapID, final String message)
125
    {
126
    int numSaves = mSaveInfo.size();
127
    int found = -1;
128

  
129
    for(int i=0; i<numSaves; i++)           // doesn't need to be synchronized with Save()
130
      {                                     // because over there we only add() and here we only
131
      if( effectID == mSaveInfo.get(i).id ) // remove() - and even if we add() in between of
132
        {                                   // computing the 'numSaves' above and this loop,
133
        found = i;                          // it still doesn't matter :)
134
        break;
116 135
        }
117
      else
136
      }
137

  
138
    if( found>=0 )  // the message really is about one of the 'SAVE' effects in execution now
139
      {
140
      Activity act = (Activity)mView.getContext();
141
      final String path = mSaveInfo.get(found).path;
142
      mSaveInfo.remove(found);
143

  
144
      switch(em)
118 145
        {
119
        int h = (width*bmpHeight)/bmpWidth;
120
        mGirl.move(0 ,(height-h)/2, 0);
121
        mGirl.scale((float)width/bmpWidth);
146
        case EFFECT_FINISHED: act.runOnUiThread(new Runnable()
147
                                {
148
                                public void run()
149
                                  {
150
                                  Toast.makeText(mView.getContext(),
151
                                      "Saving to \n\n"+path+"\n\nsuccessful" ,
152
                                      Toast.LENGTH_LONG).show();
153
                                  }
154
                                });
155
                              break;
156

  
157
        case EFFECT_FAILED  : act.runOnUiThread(new Runnable()
158
                                {
159
                                public void run()
160
                                  {
161
                                  Toast.makeText(mView.getContext(),
162
                                      "Saving to \n\n"+path+"\n\n failed: "+"\n\n"+message ,
163
                                      Toast.LENGTH_LONG).show();
164
                                  }
165
                                });
166
                              break;
167

  
168
        default             : break;
122 169
        }
170
      }
171
    }
172

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
   
175
  public void onDrawFrame(GL10 glUnused)
176
    {
177
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
178
    GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
123 179
      
124
      Distorted.onSurfaceChanged(width, height); 
180
    mGirl.draw(System.currentTimeMillis());
181
    }
182

  
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184
    
185
  public void onSurfaceChanged(GL10 glUnused, int width, int height)
186
    {
187
    scrWidth = width;
188
    scrHeight= height;
189

  
190
    mGirl.abortEffects(EffectTypes.MATRIX);
191
      
192
    if( bmpHeight/bmpWidth > height/width )
193
      {
194
      int w = (height*bmpWidth)/bmpHeight;
195
      mGirl.move((width-w)/2 ,0, 0);
196
      mGirl.scale((float)height/bmpHeight);
125 197
      }
198
    else
199
      {
200
      int h = (width*bmpHeight)/bmpWidth;
201
      mGirl.move(0 ,(height-h)/2, 0);
202
      mGirl.scale((float)width/bmpWidth);
203
      }
204
      
205
    Distorted.onSurfaceChanged(width, height);
206
    }
126 207

  
127 208
///////////////////////////////////////////////////////////////////////////////////////////////////
128 209
    
129
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
130
      {    
131
      InputStream is = mView.getContext().getResources().openRawResource(R.raw.girl);
132
      Bitmap bitmap;
210
  public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
211
    {
212
    InputStream is = mView.getContext().getResources().openRawResource(R.raw.girl);
213
    Bitmap bitmap;
133 214
        
134
      try 
135
        {
136
        bitmap = BitmapFactory.decodeStream(is);
137
        } 
138
      finally 
215
    try
216
      {
217
      bitmap = BitmapFactory.decodeStream(is);
218
      }
219
    finally
220
      {
221
      try
139 222
        {
140
        try 
141
          {
142
          is.close();
143
          } 
144
        catch(IOException e) { }
145
        }  
223
        is.close();
224
        }
225
      catch(IOException e) { }
226
      }
146 227
      
147
      bmpHeight = bitmap.getHeight();
148
      bmpWidth  = bitmap.getWidth();
228
    bmpHeight = bitmap.getHeight();
229
    bmpWidth  = bitmap.getWidth();
149 230
      
150
      mGirl = new DistortedBitmap(bitmap, 30);
231
    mGirl = new DistortedBitmap(bitmap, 30);
232
    mGirl.addEventListener(this);
151 233

  
152
      mGirl.sink( diSink, sinkRegion, pLeft );
153
      mGirl.sink( diSink, sinkRegion, pRight);
234
    mGirl.sink( diSink, sinkRegion, pLeft );
235
    mGirl.sink( diSink, sinkRegion, pRight);
154 236

  
155
      try
156
        {
157
        Distorted.onSurfaceCreated(mView.getContext());
158
        }
159
      catch(Exception ex)
160
        {
161
        android.util.Log.e("Renderer", ex.getMessage() );
162
        }
237
    try
238
      {
239
      Distorted.onSurfaceCreated(mView.getContext());
240
      }
241
    catch(Exception ex)
242
      {
243
      android.util.Log.e("Renderer", ex.getMessage() );
163 244
      }
164
}
245
    }
246
  }
src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
312 312
    
313 313
///////////////////////////////////////////////////////////////////////////////////////////////////
314 314

  
315
    public void effectMessage(EffectMessage em, long effectID, int effectType, long bitmapID)
315
    public void effectMessage(final EffectMessage em, final long effectID, final int effectName, final long bitmapID, final String message)
316 316
      {
317 317
      if( em==EffectMessage.EFFECT_FINISHED )
318 318
        {

Also available in: Unified diff