React Native - How to get thumbnails for a camera roll instead of full-size images

I am trying to get images from my skating rink of a camera for test devices for rendering in the form of sketches. I successfully extracted the images from the camera roll and displayed them in a series of image elements as a list, but they take a very long time to load. In addition, I read in React Native docs that the Image element will select the correct image size for the space in which it will be displayed.

This is from the docs.

iOS saves several sizes for the same image in Camera Roll, it is very important to choose the one that is as close to performance as possible. You would not want to use a full 3264x2448 image as a source when displaying a 200x200 thumbnail. If there is an exact match, React Native will select it, otherwise it will use the first one, which is at least 50% larger, to avoid blurring when resizing from a close size. This is all done by default, so you don’t have to worry about writing tedious (and error prone) code to do it yourself. https://facebook.imtqy.com/react-native/docs/image.html#best-camera-roll-image

The code I use to read images is very simple.

CameraRoll.getPhotos({ first: 21, assetType: 'Photos' }, (data) => { console.log(data); var images = data.edges.map((asset) => { return { uri: asset.node.image.uri }; }); this.setState({ images: this.state.images.cloneWithRows(images) }); }, () => { this.setState({ retrievePhotoError: messages.errors.retrievePhotos }); }); 

And then, to do this, I have these functions.

 renderImage(image) { return <Image resizeMode="cover" source={{uri: image.uri}} style={[{ height: imageDimensions, // imageDimensions == 93.5 width: imageDimensions }, componentStyles.thumbnails]}/>; }, render() { <ListView automaticallyAdjustContentInsets={false} contentContainerStyle={componentStyles.row} dataSource={this.state.images} renderRow={this.renderImage} /> } 

What am I missing here? I'm going crazy!

+6
source share
2 answers

I also tried to find a solution. Apparently react-native-image-resizer

solves this. Here is how I used it:

 import ImageResizer from 'react-native-image-resizer'; async getPhotos(){ await CameraRoll.getPhotos({ first: 10 , assetType: 'Photos' }) .then(r => { this.setState({ photos:r.edges, endCursorPhotos:r.page_info.end_cursor }) let resizePromiseArray = [] for(let i=0; i<r.edges.length; i++){ resizePromiseArray.push(ImageResizer.createResizedImage(r.edges[i].node.image.uri , 300, 500, 'JPEG', 100)) } return Promise.all(resizePromiseArray) }) .then(newUris=>{ // console.log(JSON.stringify(this.state.photos,null,4)) let newPhotos = this.state.photos.map((photo,i) => { photo.node.image['optiUri'] = newUris[i] return photo }) this.setState({ photos:newPhotos }) }) .catch(err =>{ console.log(err) }) } 

I am adding a thumbnail to the image object to be able to use either as needed.
You can resize only one image.

It is not incredibly fast, so it’s best to do it on componentDidMount. An even better approach is to use it in these photos in Modal, while the parent component will load and save the photos to a state before the user accesses them.

+1
source

OK, it’s possible, but you have to put your hands in the Objective-C group responsible for the reaction.

You can check it out .

You will have to modify the RCTCameraRollManager.m file.

You will need to add the following lines:

 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; NSURL *url = [[NSURL alloc] initWithString:uri]; [library assetForURL:url resultBlock:^(ALAsset *asset) { // Create an ALAssetRepresentation object using our asset // and turn it into a bitmap using the CGImageRef opaque type. CGImageRef imageRef = [asset thumbnail]; CGSize dimensions = [UIImage imageWithCGImage:imageRef].size; // Create UIImageJPEGRepresentation from CGImageRef NSData *imageData = UIImageJPEGRepresentation([UIImage imageWithCGImage:imageRef], 0.1); 

to the [assets addObject:@{...}] method and add:

 } failureBlock:^(NSError *error) { NSLog(@"that didn't work %@", error); }]; 

after the method [assets addObject:@{...}] .

You can also add prop @"base64": base64Encoded to the [assets addObject:@{ .

Check the link, you have a β€œnew file” that gives you a thumbnail (size 125 x 125).

0
source

All Articles