Project

General

Profile

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

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

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

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

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

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

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  private SaveWorkerThread()
63
    {
64
    }
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

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

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

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

    
82
  public void run()
83
    {
84
    WorkLoad load;
85

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

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

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

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

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

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

    
123
    byte[] tmp1 = new byte[width*4];
124
    byte[] tmp2 = new byte[width*4];
125

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

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

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

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

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

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