Skip to content

Commit 91f8a67

Browse files
authored
Merge pull request #28 from LionelWei/pr-async
Convert image to data in a separate thread
2 parents 0194b56 + 45061cc commit 91f8a67

File tree

1 file changed

+60
-40
lines changed

1 file changed

+60
-40
lines changed

android/src/main/java/fr/greweb/reactnativeviewshot/ViewShot.java

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fr.greweb.reactnativeviewshot;
22

33
import javax.annotation.Nullable;
4+
45
import android.graphics.Bitmap;
56
import android.graphics.Canvas;
67
import android.net.Uri;
@@ -16,6 +17,8 @@
1617
import java.io.FileOutputStream;
1718
import java.io.IOException;
1819
import java.io.OutputStream;
20+
import java.util.concurrent.ExecutorService;
21+
import java.util.concurrent.Executors;
1922

2023
/**
2124
* Snapshot utility class allow to screenshot a view.
@@ -24,6 +27,8 @@ public class ViewShot implements UIBlock {
2427

2528
static final String ERROR_UNABLE_TO_SNAPSHOT = "E_UNABLE_TO_SNAPSHOT";
2629

30+
private final static ExecutorService sExecutor = Executors.newFixedThreadPool(5);
31+
2732
private int tag;
2833
private String extension;
2934
private Bitmap.CompressFormat format;
@@ -57,59 +62,63 @@ public ViewShot(
5762

5863
@Override
5964
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
60-
OutputStream os = null;
6165
View view = nativeViewHierarchyManager.resolveView(tag);
6266
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);
6468
return;
6569
}
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;
9875
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) {
10198
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+
}
102108
}
103109
}
104-
}
110+
});
111+
112+
105113
}
106114

107115
/**
108116
* Screenshot a view and return the captured bitmap.
117+
*
109118
* @param view the view to capture
110-
* @return the screenshot or null if it failed.
119+
* @return bitmap drawn by view
111120
*/
112-
private void captureView (View view, OutputStream os) {
121+
private Bitmap captureView(View view) {
113122
int w = view.getWidth();
114123
int h = view.getHeight();
115124
if (w <= 0 || h <= 0) {
@@ -125,6 +134,17 @@ private void captureView (View view, OutputStream os) {
125134
if (bitmap == null) {
126135
throw new RuntimeException("Impossible to snapshot the view");
127136
}
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);
129149
}
130150
}

0 commit comments

Comments
 (0)