Project

General

Profile

Download (5.96 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / save / SaveWorkerThread.java @ b4cc083b

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.examples.save;
21

    
22
import android.app.Activity;
23
import android.content.Intent;
24
import android.graphics.Bitmap;
25
import android.net.Uri;
26
import android.widget.Toast;
27

    
28
import java.io.BufferedOutputStream;
29
import java.io.File;
30
import java.io.FileOutputStream;
31
import java.io.IOException;
32
import java.lang.ref.WeakReference;
33
import java.nio.ByteBuffer;
34
import java.util.Vector;
35

    
36
class SaveWorkerThread extends Thread
37
  {
38
  private static Vector<WorkLoad> mBuffers;
39
  private static SaveWorkerThread mThis=null;
40
  private static WeakReference<Activity> mWeakAct;
41

    
42
  private static class WorkLoad
43
    {
44
    ByteBuffer buffer;
45
    int width;
46
    int height;
47
    String filename;
48

    
49
    WorkLoad(ByteBuffer buf, int w, int h, String name)
50
      {
51
      buffer   = buf;
52
      width    = w;
53
      height   = h;
54
      filename = name;
55
      }
56
    }
57

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

    
60
  private SaveWorkerThread()
61
    {
62
    }
63

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

    
66
  static void create(Activity act)
67
    {
68
    mWeakAct = new WeakReference<>(act);
69

    
70
    if( mThis==null )
71
      {
72
      mBuffers = new Vector<>();
73
      mThis = new SaveWorkerThread();
74
      mThis.start();
75
      }
76
    }
77

    
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

    
80
  public void run()
81
    {
82
    WorkLoad load;
83

    
84
    while(true)
85
      {
86
      synchronized(mThis)
87
        {
88
        while( mBuffers.size()>0 )
89
          {
90
          load = mBuffers.remove(0);
91
          process(load);
92
          }
93

    
94
        try  { mThis.wait(); }
95
        catch(InterruptedException ex) { }
96
        }
97
      }
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  static void newBuffer(ByteBuffer buffer, int width, int height, String filename)
103
    {
104
    synchronized(mThis)
105
      {
106
      WorkLoad load = new WorkLoad(buffer,width,height,filename);
107
      mBuffers.add(load);
108
      mThis.notify();
109
      }
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  private void process(WorkLoad load)
115
    {
116
    ByteBuffer buf = load.buffer;
117
    int width  = load.width;
118
    int height = load.height;
119
    final String filename = load.filename;
120

    
121
    byte[] tmp1 = new byte[width*4];
122
    byte[] tmp2 = new byte[width*4];
123

    
124
    for(int i=0; i<height/2; i++)
125
      {
126
      buf.position((         i)*width*4);  // GL uses a coordinate system from mathematics; i.e.
127
      buf.get(tmp1);                       // (0,0) is in the lower-left corner. 2D stuff has
128
      buf.position((height-1-i)*width*4);  // the origin on the upper-left corner; we have to flip
129
      buf.get(tmp2);                       // out bitmap upside down!
130

    
131
      buf.position((         i)*width*4);
132
      buf.put(tmp2);
133
      buf.position((height-1-i)*width*4);
134
      buf.put(tmp1);
135
      }
136

    
137
    buf.rewind();
138
    BufferedOutputStream bos =null;
139
    final Activity act = mWeakAct.get();
140

    
141
    try
142
      {
143
      bos = new BufferedOutputStream(new FileOutputStream(filename));
144
      Bitmap bmp = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888);
145
      bmp.copyPixelsFromBuffer(buf);
146
      bmp.compress(Bitmap.CompressFormat.PNG, 90, bos);
147
      bmp.recycle();
148

    
149
      act.runOnUiThread(new Runnable()
150
        {
151
        public void run()
152
          {
153
          Toast.makeText(act,
154
              "Saving to \n\n"+filename+"\n\nsuccessful" ,
155
              Toast.LENGTH_LONG).show();
156
          }
157
        });
158
      }
159
    catch(final Exception ex)
160
      {
161
      act.runOnUiThread(new Runnable()
162
        {
163
        public void run()
164
          {
165
          Toast.makeText(act,
166
              "Saving to \n\n"+filename+"\n\n failed: "+"\n\n"+ex.getMessage() ,
167
              Toast.LENGTH_LONG).show();
168
          }
169
        });
170
      }
171
    finally
172
      {
173
      if(bos!=null)
174
        {
175
        try { bos.close(); }
176
        catch(IOException io) {}
177
        }
178
      }
179

    
180
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
181
    File f = new File(filename);
182
    Uri contentUri = Uri.fromFile(f);
183
    mediaScanIntent.setData(contentUri);
184
    act.sendBroadcast(mediaScanIntent);
185
    }
186
  }
(4-4/4)