Skip to content

Commit

Permalink
[gl] Add WebP format as an option when taking GL snapshots (Android o…
Browse files Browse the repository at this point in the history
…nly) (#7490)

# Why

At some point (API 14), Android added native WebP support ([Bitmap.CompressFormat.WEBP](https://developer.android.com/reference/android/graphics/Bitmap.CompressFormat#WEBP)), so adding the option to export the render to WebP is trivial.
Creating a new module just for converting from PNG to WebP is silly since you can get the GL render as WebP directly. Also converting from PNG to WebP could create quality loss.

# How

In GLContext.java, I extended the block that specifies using png (instead of jpeg, the default) to recognize webp as another posible format.

# Test Plan

Sadly, a combination of living in Windows OS and lack of experience in some aspects of software development, I was not able to test this change using the proper methods (unit test, and that). But I did tried the change in the App I'm building and it worked fine

Thanks for your attention, sorry for any mistake in the PR, this is the second time I do a PR
  • Loading branch information
pacoelayudante committed May 17, 2020
1 parent 7a706b9 commit 093704f
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 5 deletions.
4 changes: 3 additions & 1 deletion docs/pages/versions/unversioned/sdk/gl-view.md
Expand Up @@ -80,9 +80,11 @@ Takes a snapshot of the framebuffer and saves it as a file to app's cache direct
- **framebuffer (_WebGLFramebuffer_)** -- Specify the framebuffer that we will be reading from. Defaults to underlying framebuffer that is presented in the view or the current framebuffer if context is headless.
- **rect (`{ x: number, y: number, width: number, height: number }`)** -- Rect to crop the snapshot. It's passed directly to `glReadPixels`.
- **flip (_boolean_)** -- Whether to flip the snapshot vertically. Defaults to `false`.
- **format (_string_)** -- Either `'jpeg'` or `'png'`. Specifies what type of compression should be used and what is the result file extension. PNG compression is lossless but slower, JPEG is faster but the image has visible artifacts. Defaults to `'jpeg'`.
- **format (_string_)** -- Either `'jpeg'`, `'png'` or `'webp'` (_Android only_ for the latter). Specifies what type of compression should be used and what is the result file extension. PNG compression is lossless but slower, JPEG is faster but the image has visible artifacts. Defaults to `'jpeg'`.
- **compress (_number_)** -- A value in range 0 - 1 specifying compression level of the result image. 1 means no compression and 0 the highest compression. Defaults to `1.0`.

> **Note:** When using WebP format, the iOS version will print a warning, and generate a `'png'` file instead. It is recommendable to use platform dependant code in this case. You can refer to the [documentation on platform specifi code](https://docs.expo.io/versions/latest/react-native/platform-specific-code/).
#### Returns

Returns `{ uri, localUri, width, height }` where `uri` is a URI to the snapshot. `localUri` is a synonym for `uri` that makes this object compatible with `texImage2D`. `width, height` specify the dimensions of the snapshot.
Expand Down
Expand Up @@ -278,9 +278,14 @@ protected Void doInBackground(Void... params) {
FileOutputStream output = null;
Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;

if (mFormat != null && mFormat.equals("png")) {
compressFormat = Bitmap.CompressFormat.PNG;
extension = ".png";
if (mFormat != null) {
if (mFormat.equals("png")) {
compressFormat = Bitmap.CompressFormat.PNG;
extension = ".png";
} else if (mFormat.equals("webp")) {
compressFormat = Bitmap.CompressFormat.WEBP;
extension = ".webp";
}
}

Context context = mContext.get();
Expand Down
7 changes: 6 additions & 1 deletion packages/expo-gl/ios/EXGL/EXGLContext.m
Expand Up @@ -230,7 +230,12 @@ - (void)takeSnapshotWithOptions:(nonnull NSDictionary *)options
NSData *imageData;
NSString *extension;

if ([format isEqualToString:@"png"]) {
if ([format isEqualToString:@"webp"]) {
UMLogWarn(@"iOS doesn't support 'webp' representation, so 'takeSnapshot' won't work with that format. The image is going to be exported as 'png', but consider using a different code for iOS. Check this docs to learn how to do platform specific code (https://reactnative.dev/docs/platform-specific-code)");
imageData = UIImagePNGRepresentation(image);
extension = @".png";
}
else if ([format isEqualToString:@"png"]) {
imageData = UIImagePNGRepresentation(image);
extension = @".png";
} else {
Expand Down

0 comments on commit 093704f

Please sign in to comment.