Browse Source

Convert image to data in a separate thread

LionelWei 7 years ago
parent
commit
45061cc62a
1 changed files with 60 additions and 40 deletions
  1. 60
    40
      android/src/main/java/fr/greweb/reactnativeviewshot/ViewShot.java

+ 60
- 40
android/src/main/java/fr/greweb/reactnativeviewshot/ViewShot.java View File

1
 package fr.greweb.reactnativeviewshot;
1
 package fr.greweb.reactnativeviewshot;
2
 
2
 
3
 import javax.annotation.Nullable;
3
 import javax.annotation.Nullable;
4
+
4
 import android.graphics.Bitmap;
5
 import android.graphics.Bitmap;
5
 import android.graphics.Canvas;
6
 import android.graphics.Canvas;
6
 import android.net.Uri;
7
 import android.net.Uri;
16
 import java.io.FileOutputStream;
17
 import java.io.FileOutputStream;
17
 import java.io.IOException;
18
 import java.io.IOException;
18
 import java.io.OutputStream;
19
 import java.io.OutputStream;
20
+import java.util.concurrent.ExecutorService;
21
+import java.util.concurrent.Executors;
19
 
22
 
20
 /**
23
 /**
21
  * Snapshot utility class allow to screenshot a view.
24
  * Snapshot utility class allow to screenshot a view.
24
 
27
 
25
     static final String ERROR_UNABLE_TO_SNAPSHOT = "E_UNABLE_TO_SNAPSHOT";
28
     static final String ERROR_UNABLE_TO_SNAPSHOT = "E_UNABLE_TO_SNAPSHOT";
26
 
29
 
30
+    private final static ExecutorService sExecutor = Executors.newFixedThreadPool(5);
31
+
27
     private int tag;
32
     private int tag;
28
     private String extension;
33
     private String extension;
29
     private Bitmap.CompressFormat format;
34
     private Bitmap.CompressFormat format;
57
 
62
 
58
     @Override
63
     @Override
59
     public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
64
     public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
60
-        OutputStream os = null;
61
         View view = nativeViewHierarchyManager.resolveView(tag);
65
         View view = nativeViewHierarchyManager.resolveView(tag);
62
         if (view == null) {
66
         if (view == null) {
63
-            promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "No view found with reactTag: "+tag);
67
+            promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "No view found with reactTag: " + tag);
64
             return;
68
             return;
65
         }
69
         }
66
-        try {
67
-            if ("file".equals(result)) {
68
-                os = new FileOutputStream(output);
69
-                captureView(view, os);
70
-                String uri = Uri.fromFile(output).toString();
71
-                promise.resolve(uri);
72
-            }
73
-            else if ("base64".equals(result)) {
74
-                os = new ByteArrayOutputStream();
75
-                captureView(view, os);
76
-                byte[] bytes = ((ByteArrayOutputStream) os).toByteArray();
77
-                String data = Base64.encodeToString(bytes, Base64.NO_WRAP);
78
-                promise.resolve(data);
79
-            }
80
-            else if ("data-uri".equals(result)) {
81
-                os = new ByteArrayOutputStream();
82
-                captureView(view, os);
83
-                byte[] bytes = ((ByteArrayOutputStream) os).toByteArray();
84
-                String data = Base64.encodeToString(bytes, Base64.NO_WRAP);
85
-                data = "data:image/"+extension+";base64," + data;
86
-                promise.resolve(data);
87
-            }
88
-            else {
89
-                promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "Unsupported result: "+result+". Try one of: file | base64 | data-uri");
90
-            }
91
-        }
92
-        catch (Exception e) {
93
-            e.printStackTrace();
94
-            promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "Failed to capture view snapshot");
95
-        }
96
-        finally {
97
-            if (os != null) {
70
+        final Bitmap bitmap = captureView(view);
71
+        sExecutor.execute(new Runnable() {
72
+            @Override
73
+            public void run() {
74
+                OutputStream os = null;
98
                 try {
75
                 try {
99
-                    os.close();
100
-                } catch (IOException e) {
76
+                    if ("file".equals(result)) {
77
+                        os = new FileOutputStream(output);
78
+                        String uri = Uri.fromFile(output).toString();
79
+                        promise.resolve(uri);
80
+                    } else if ("base64".equals(result)) {
81
+                        os = new ByteArrayOutputStream();
82
+                        convertImageToData(bitmap, os);
83
+                        byte[] bytes = ((ByteArrayOutputStream) os).toByteArray();
84
+                        String data = Base64.encodeToString(bytes, Base64.NO_WRAP);
85
+                        promise.resolve(data);
86
+                    } else if ("data-uri".equals(result)) {
87
+                        os = new ByteArrayOutputStream();
88
+                        convertImageToData(bitmap, os);
89
+                        byte[] bytes = ((ByteArrayOutputStream) os).toByteArray();
90
+                        String data = Base64.encodeToString(bytes, Base64.NO_WRAP);
91
+                        data = "data:image/" + extension + ";base64," + data;
92
+                        promise.resolve(data);
93
+                    } else {
94
+                        promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "Unsupported result: " + result +
95
+                                ". Try one of: file | base64 | data-uri");
96
+                    }
97
+                } catch (Exception e) {
101
                     e.printStackTrace();
98
                     e.printStackTrace();
99
+                    promise.reject(ERROR_UNABLE_TO_SNAPSHOT, "Failed to capture view snapshot");
100
+                } finally {
101
+                    if (os != null) {
102
+                        try {
103
+                            os.close();
104
+                        } catch (IOException e) {
105
+                            e.printStackTrace();
106
+                        }
107
+                    }
102
                 }
108
                 }
103
             }
109
             }
104
-        }
110
+        });
111
+
112
+
105
     }
113
     }
106
 
114
 
107
     /**
115
     /**
108
      * Screenshot a view and return the captured bitmap.
116
      * Screenshot a view and return the captured bitmap.
117
+     *
109
      * @param view the view to capture
118
      * @param view the view to capture
110
-     * @return the screenshot or null if it failed.
119
+     * @return bitmap drawn by view
111
      */
120
      */
112
-    private void captureView (View view, OutputStream os) {
121
+    private Bitmap captureView(View view) {
113
         int w = view.getWidth();
122
         int w = view.getWidth();
114
         int h = view.getHeight();
123
         int h = view.getHeight();
115
         if (w <= 0 || h <= 0) {
124
         if (w <= 0 || h <= 0) {
125
         if (bitmap == null) {
134
         if (bitmap == null) {
126
             throw new RuntimeException("Impossible to snapshot the view");
135
             throw new RuntimeException("Impossible to snapshot the view");
127
         }
136
         }
128
-        bitmap.compress(format, (int)(100.0 * quality), os);
137
+        return bitmap;
138
+    }
139
+
140
+    /**
141
+     * As Bitmap.compress() may take a long time, it's better to
142
+     * call it in a separate thread
143
+     *
144
+     * @param bitmap image to convert
145
+     * @param os     output stream
146
+     */
147
+    private void convertImageToData(Bitmap bitmap, OutputStream os) {
148
+        bitmap.compress(format, (int) (100.0 * quality), os);
129
     }
149
     }
130
 }
150
 }