React Native - 如何获取相机胶卷缩略图而不是全尺寸图像

时间:2015-09-17 23:08:55

标签: react-native

我正在尝试从我的测试设备相机胶卷中获取图像以渲染为缩略图。我已成功从相机胶卷中取出图像并在列表视图中的一系列图像元素中显示它们,但它们需要很长时间才能加载。另外,我在React Native文档中读到了Image元素将选择它将渲染的空间的图像大小正确。

这是来自文档。

  

iOS为相机胶卷中的同一图像保存多种尺寸,因性能原因选择尽可能接近的图像非常重要。在显示200x200缩略图时,您不希望使用全质量3264x2448图像作为源。如果存在精确匹配,React Native将选择它,否则它将使用至少大50%的第一个,以避免在从近似大小调整大小时出现模糊。所有这些都是默认完成的,因此您不必担心编写繁琐(且容易出错)的代码来自己完成。 https://facebook.github.io/react-native/docs/image.html#best-camera-roll-image

我用来阅读图像的代码非常简单。

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

然后渲染它我有这些功能。

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

我在这里缺少什么?我疯了!!!

2 个答案:

答案 0 :(得分:1)

我也很难找到解决方案。显然,react-native-image-resizer

解决了这个问题。 以下是我如何使用它:

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

我将缩略图添加到图像对象中,以便根据需要选择使用。
您只能调整一张图片的大小。

它的速度并不快,所以在componentDidMount上做得更好。 更好的方法是在模态中的这些照片中使用它,而父组件将加载并在用户访问之前将照片保存到状态

答案 1 :(得分:0)

好的,这是可能的,但你必须把你的手放在react-native的Objective-C派对上。

您可以查看this

您必须修改RCTCameraRollManager.m文件。

您必须添加以下这些内容:

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

[assets addObject:@{...}]方法之前添加:

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

[assets addObject:@{...}]方法之后。

您还可以在@"base64": base64Encoded方法中添加道具[assets addObject:@{

检查链接,你有&#34;新文件&#34;它为您提供缩略图(125 x 125大小)。