React Native 检索实际图像大小
React Native Retrieve Actual Image Sizes
我想知道已传递到 <Image />
的网络加载图像的实际大小 我尝试使用 onLayout
来计算大小(取自这里 https://github.com/facebook/react-native/issues/858) 但这似乎是 return 已经通过布局引擎推送后的清理尺寸。
我尝试查看 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)}} />
);
}
谢谢。
此答案现已过时。请参阅比尔的回答。
Image.getSize(myUri, (width, height) => { this.setState({ width, height }) });
旧答案(适用于旧版本的 React Native)
好的,我成功了。目前这需要对 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];
};
然后编辑处理加载完成的行:
[self.layer removeAnimationForKey:@"contents"];
self.layer.contentsScale = image.scale;
self.layer.contents = (__bridge id)image.CGImage;
loadEndHandler();
替换
loadEndHandler();
和
loadImageEndHandler(image);
然后在 React-Native 中,您可以通过本机事件访问大小。来自 onLoaded
函数的数据 - 请注意当前文档说该函数是 onLoad
但这是不正确的。 v0.8.0的正确函数如下:
onLoadStart
onLoadProgress
onLoaded
onLoadError
onLoadAbort
这些可以像这样访问:
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>
);
}
注意事项:
我设置了一个大图像 window 并将其设置在 1x1px 的环绕元素内,这是因为如果要检索有意义的值,图像必须适合内部。
resize mode必须是'contain'
才能得到正确的尺寸,否则会报constrained size
图像大小根据设备的比例因子按比例缩放,例如iPhone6(不是 6+)上的 200*200 图像将被报告为 100*100。我假设这也意味着它将在 iPhone6 plus 上报告为 67*67 但我没有测试过这个。
我还没有将它用于在桥的 Obj-C 端遍历不同路径的 GIF 文件。完成后我会更新这个答案。
我相信目前有一个 PR 正在为此进行,但在它被包含在核心之前,每次你 update/re-install.
Image 组件现在提供静态方法来获取图像的大小。例如:
Image.getSize(myUri, (width, height) => {this.setState({width, height})});
您可以使用图像组件中的 resolveAssetSource 方法:
import picture from 'pathToYourPicture';
const {width, height} = Image.resolveAssetSource(picture);
TypeScript 示例:
import {Image} from 'react-native';
export interface ISize {
width: number;
height: number;
}
function getImageSize(uri: string): Promise<ISize> {
const success = (resolve: (value?: ISize | PromiseLike<ISize>) => void) => (width: number, height: number) => {
resolve({
width,
height
});
};
const error = (reject: (reason?: any) => void) => (failure: Error) => {
reject(failure);
};
return new Promise<ISize>((resolve, reject) => {
Image.getSize(uri, success(resolve), error(reject));
});
}
我想知道已传递到 <Image />
的网络加载图像的实际大小 我尝试使用 onLayout
来计算大小(取自这里 https://github.com/facebook/react-native/issues/858) 但这似乎是 return 已经通过布局引擎推送后的清理尺寸。
我尝试查看 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)}} />
);
}
谢谢。
此答案现已过时。请参阅比尔的回答。
Image.getSize(myUri, (width, height) => { this.setState({ width, height }) });
旧答案(适用于旧版本的 React Native)
好的,我成功了。目前这需要对 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];
};
然后编辑处理加载完成的行:
[self.layer removeAnimationForKey:@"contents"];
self.layer.contentsScale = image.scale;
self.layer.contents = (__bridge id)image.CGImage;
loadEndHandler();
替换
loadEndHandler();
和
loadImageEndHandler(image);
然后在 React-Native 中,您可以通过本机事件访问大小。来自 onLoaded
函数的数据 - 请注意当前文档说该函数是 onLoad
但这是不正确的。 v0.8.0的正确函数如下:
onLoadStart
onLoadProgress
onLoaded
onLoadError
onLoadAbort
这些可以像这样访问:
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>
);
}
注意事项:
我设置了一个大图像 window 并将其设置在 1x1px 的环绕元素内,这是因为如果要检索有意义的值,图像必须适合内部。
resize mode必须是
'contain'
才能得到正确的尺寸,否则会报constrained size图像大小根据设备的比例因子按比例缩放,例如iPhone6(不是 6+)上的 200*200 图像将被报告为 100*100。我假设这也意味着它将在 iPhone6 plus 上报告为 67*67 但我没有测试过这个。
我还没有将它用于在桥的 Obj-C 端遍历不同路径的 GIF 文件。完成后我会更新这个答案。
我相信目前有一个 PR 正在为此进行,但在它被包含在核心之前,每次你 update/re-install.
Image 组件现在提供静态方法来获取图像的大小。例如:
Image.getSize(myUri, (width, height) => {this.setState({width, height})});
您可以使用图像组件中的 resolveAssetSource 方法:
import picture from 'pathToYourPicture';
const {width, height} = Image.resolveAssetSource(picture);
TypeScript 示例:
import {Image} from 'react-native';
export interface ISize {
width: number;
height: number;
}
function getImageSize(uri: string): Promise<ISize> {
const success = (resolve: (value?: ISize | PromiseLike<ISize>) => void) => (width: number, height: number) => {
resolve({
width,
height
});
};
const error = (reject: (reason?: any) => void) => (failure: Error) => {
reject(failure);
};
return new Promise<ISize>((resolve, reject) => {
Image.getSize(uri, success(resolve), error(reject));
});
}