2015-09-17 11 views
6

Sto cercando di ottenere immagini dai miei dispositivi di test. Ho recuperato con successo le immagini dal rullino fotografico e le ho visualizzate all'interno di una serie di elementi Immagine in una visualizzazione elenco ma richiedono molto tempo per essere caricate. Inoltre, ho letto i documenti React Native che l'elemento Image sceglierà dimensione dell'immagine corretta per lo spazio in cui verrà renderizzata.React Native - Come ottenere thumbnails del rullino fotografico invece di immagini a dimensione intera

Questo è dai documenti.

iOS salva più formati per la stessa immagine nel Rullino foto, è molto importante scegliere quello che è il più vicino possibile per motivi di prestazioni. Non si desidera utilizzare l'immagine 3264x2448 di qualità completa come sorgente quando si visualizza una miniatura 200x200. Se c'è una corrispondenza esatta, React Native la sceglierà, altrimenti userà la prima che è almeno del 50% più grande per evitare la sfocatura quando ridimensiona da una dimensione vicina. Tutto questo è fatto per impostazione predefinita in modo da non doversi preoccupare di scrivere il codice noioso (e incline agli errori) per farlo da soli. https://facebook.github.io/react-native/docs/image.html#best-camera-roll-image

Il codice che sto usando per leggere le immagini è semplicissimo.

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 
     }); 
    }); 

E quindi per renderlo ho queste funzioni.

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} 
    /> 
} 

Cosa mi manca qui? Sto impazzendo!!!

+0

esci con la soluzione javascript? –

risposta

0

OK, è possibile, ma dovrai mettere le mani nella parte Objective-C di react-native.

È possibile controllare this.

Dovrai modificare il file RCTCameraRollManager.m.

Dovrete aggiungere queste righe:

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); 

prima che il metodo [assets addObject:@{...}] e aggiunge:

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

dopo il metodo [assets addObject:@{...}].

È inoltre possibile aggiungere il puntello @"base64": base64Encoded nel metodo [assets addObject:@{.

Controllare il collegamento, si dispone del "nuovo file" che fornisce l'anteprima (dimensioni 125 x 125).

1

Ho anche faticato a trovare la soluzione. Apparentemente, react-native-image-resizer

risolve questo. Ecco come l'ho usato:

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) 
    }) 
} 

che sto aggiungendo la miniatura per l'oggetto immagine per avere la possibilità di utilizzare sia come necessario.
È possibile ridimensionare una sola immagine.

Non è incredibilmente veloce, quindi è meglio farlo a componentDidMount. Un approccio ancora migliore è usarlo in queste foto in un modale mentre il componente genitore caricherà e salverà le foto prima che l'utente le acceda

Problemi correlati