React Native检索实际图像大小

Mos*_*mer 34 react-native

我希望能够知道已经传入的网络加载图像的实际大小<Image />我已经尝试使用onLayout来计算大小(从这里开始https://github.com/facebook/react-native/问题/ 858)但这似乎在已经通过布局引擎推送之后返回已清理的大小.

我试着查看onLoadStart,onLoad,onLoadEnd,onProgress以查看是否有其他可用信息,但似乎无法解决任何这些问题.我当时声明如下:

  onImageLoadStart: function(e){
    console.log("onImageLoadStart");
  },

  onImageLoad: function(e){
    console.log("onImageLoad");
  },

  onImageLoadEnd: function(e){
    console.log("onImageLoadEnd");
  },


  onImageProgress: function(e){
    console.log("onImageProgress");
  },

  onImageError: function(e){
    console.log("onImageError");
  },

  render: function (e) {
    return (
      <Image
        source={{uri: "http://adomain.com/myimageurl.jpg"}}
        style={[this.props.style, this.state.style]}
        onLayout={this.onImageLayout}
        onLoadStart={(e) => {this.onImageLoadStart(e)}}
        onLoad={(e) => {this.onImageLoad(e)}}
        onLoadEnd={(e) => {this.onImageLoadEnd(e)}}
        onProgress={(e) => {this.onImageProgress(e)}}
        onError={(e) => {this.onImageError(e)}} />
    );
  }
Run Code Online (Sandbox Code Playgroud)

谢谢.

Bil*_*ill 70

图像组件现在提供了一种静态方法来获取图像的大小.例如:

Image.getSize(myUri, (width, height) => {this.setState({width, height})});
Run Code Online (Sandbox Code Playgroud)

  • 我爱你,正在为那个&lt;3而苦苦挣扎 (5认同)
  • 对于静态图像,请使用Image.resolveAssetSource(your_static_image).width或Image.resolveAssetSource(your_static_image).height.资料来源:/sf/ask/2939832801/ (4认同)
  • 如果我用它来获取图像尺寸,然后用它设置图像,这是否意味着它会获取图像两次? (3认同)

Mos*_*mer 11

这个答案现在可能已经过时了.请参阅QuidProQuo的答案.

Image.getSize(myUri, (width, height) => { this.setState({ width, height }) });
Run Code Online (Sandbox Code Playgroud)

旧答案(适用于旧版本的本机反应)

好的,我搞定了.目前,这需要对React-Native安装进行一些修改,因为它本身不受支持.

我按照这个帖子中的提示使我能够这样做. https://github.com/facebook/react-native/issues/494

主要是,更改RCTNetworkImageView.m文件:将以下内容添加到 setImageURL

void (^loadImageEndHandler)(UIImage *image) = ^(UIImage *image) {
  NSDictionary *event = @{
    @"target": self.reactTag,
    @"size": @{
      @"height": @(image.size.height),
      @"width": @(image.size.width)
    }
  };
  [_eventDispatcher sendInputEventWithName:@"loaded" body:event];
};
Run Code Online (Sandbox Code Playgroud)

然后编辑处理加载完成的行:

[self.layer removeAnimationForKey:@"contents"];
self.layer.contentsScale = image.scale;
self.layer.contents = (__bridge id)image.CGImage;
loadEndHandler();
Run Code Online (Sandbox Code Playgroud)

更换

loadEndHandler();
Run Code Online (Sandbox Code Playgroud)

loadImageEndHandler(image);
Run Code Online (Sandbox Code Playgroud)

然后在React-Native中,您可以通过本机事件访问大小.来自onLoaded函数的数据- 注意文档当前说的函数是onLoad但这是不正确的.对于v0.8.0,正确的功能如下:

onLoadStart
onLoadProgress
onLoaded
onLoadError
onLoadAbort
Run Code Online (Sandbox Code Playgroud)

这些可以像这样访问:

onImageLoaded: function(data){
    try{
        console.log("image width:"+data.nativeEvents.size.width);
        console.log("image height:"+data.nativeEvents.size.height);
    }catch(e){
        //error
    }
},
...
render: function(){
    return (
        <View style={{width:1,height:1,overflow='hidden'}}>
            <Image source={{uri: yourImageURL}} resizeMode='contain' onLoaded={this.onImageLoaded} style={{width:5000,height:5000}} />
        </View>
    );
}
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 我已经设置了一个大的图像窗口并将其设置在1x1px的包装元素内,这是因为如果要检索有意义的值,图像必须适合内部.

  • 调整大小模式必须'contain'使您能够获得正确的大小,否则将报告约束大小.

  • 图像大小与设备的比例因子成比例缩放,例如,iPhone6(不是6 +)上的200*200图像将报告为100*100.我认为这也意味着它将在iPhone6 plus上报告为67*67,但我还没有测试过.

  • 我还没有这个用于GIF文件,这些文件遍历桥的Obj-C侧的不同路径.我做完之后会更新这个答案.

  • 我相信目前有一个PR正在进行中,但是直到它被包含在核心中,然后每次更新/重新安装时都必须对react-native安装进行此更改.


bal*_*ine 10

您可以使用Image组件中的resolveAssetSource方法:

import picture from 'pathToYourPicture';  
const {width, height} = Image.resolveAssetSource(picture);
Run Code Online (Sandbox Code Playgroud)

  • 非常适合静态图片资产! (3认同)
  • 问题是关于网络加载的图像。 (2认同)