Issue with takeSnapshotAsync

#1

Hey there,

I’m trying to make a view that shows an image with another image on top of it. The purpose is that a user can pick an image, add a ‘sticker’ that can be panned, scaled and rotated a la Snapchat and save it.

To save the result, I’m using takeSnapshotAsync, but I’m having difficulty understanding how to set the quality, height and width variables.

The view that gets snapshotted has a size of 300x300 pixels on the iPhone (7) emulator. The image I choose from the camera roll (waterfall) is 2002x3000 (height x width)

The results I’m getting from different configs of takeSnapshotAsync are not logical to me:

quality: 1, 
height: undefined, 
width: undefined, 
resulting image saved: 600x600

____
quality: 1, 
height: 100, 
width: 100, 
resulting image saved: 200x200

____
quality: 1, 
height: 300, 
width: 300, 
resulting image saved: 600x600

____
quality: 1, 
height: 500, 
width: 500, 
resulting image saved: 1000x1000

____
quality: 1, 
height: 1000, 
width: 1000, 
resulting image saved: 2000x2000

____
quality: 1, 
height: 2002, 
width: 3000, 
resulting image saved: 1367 x 2048

So it seems that

  1. If no width/height is specified, the result will be twice the size of the viewport. Also tested by changing viewport size to 225x225, where the result was 450x450
  2. If width/height is specified, the result will be twice the size of the given dimensions
  3. If a too large size is given (as in the last example where I try to pass along the size of the original image), a max of some sorts is reached

My goal is, of course, to save an image with same dimensions as the original but with the sticker ‘burnt in’, but I can’t see how and if this is possible from the above tests?

I’ve made a sketch to play around with here: https://snack.expo.io/ryO6GTAbf

I hope someone can help or clarify what I’m doing wrong :grin:

#2

Further investigation:

quality: 1, 
height: 1000, 
width: 1000, 
resulting image saved: 1750 x 1750

But then I remembered that I get the resulting sizes from a console.log when I choose it from the Expo.imagePicker, which might affect the size by having maximum import sizes, so I checked in the camera roll - and the 1000x1000 above was actually saved as 3500x3500, so twice the size of what is re-imported. So I tried again:

quality: 1, 
height: 1200, 
width: 1200, 
resulting image when imported back into the app by imagePicker: 1050 x 1050
real size in camera roll: 4200 x 4200

quality: 1, 
height: 800, 
width: 800, 
resulting image when imported back into the app by imagePicker: 1400 x 1400
real size in camera roll: 2800 x 2800

So it seems that takeSnapshotAsync can produce a large enough image (at least for my needs, 4200x4200 = 17.6 megapixels), but I still cannot see the relation between the results, and what height/width I’m supposed to pass in the config to end up with an image the same size as the original.

#3

Solved, see https://github.com/expo/expo/issues/1110#issuecomment-353009156