Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Image] Set correct image height #494

Closed
coryoso opened this issue Mar 30, 2015 · 21 comments
Closed

[Image] Set correct image height #494

coryoso opened this issue Mar 30, 2015 · 21 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@coryoso
Copy link

coryoso commented Mar 30, 2015

I want to display images from the internet and want to make them as wide as the parent view, which is possible by setting the flex value. But I also want to make the image as high as width * aspectRatio.
Neither StyleSheet.create nor the direct style tag gives access to the image width and aspectRatio.
Any ideas?

@vjeux
Copy link
Contributor

vjeux commented Mar 30, 2015

Unfortunately CSS doesn't have a good way to do aspect ratio like this. The best hack you can come up with is padding-bottom: 150% but it's super ugly. I prototyped an implementation of aspectRatio and it worked but wasn't spec compliant so I backed off.

In the meantime, you can do height: require('Dimensions').get('window').width / 1.5

@coryoso
Copy link
Author

coryoso commented Apr 14, 2015

If possible, could you show your aspectRatio prototype implantation?

@paramaggarwal
Copy link
Contributor

Same concern here. Is there a way to get the width of the parent view? Then I can do the math and set absolute height and width on the Image.

The parent view itself might be configured with alignSelf: 'stretch', so it would get its width during layout. Is there any way to access this computed width?

@brentvatne
Copy link
Collaborator

@paramaggarwal - check out these bridge methods on RCTUIManager for performing measurements

@brentvatne brentvatne changed the title Set correct image height [Image] Set correct image height May 31, 2015
@paramaggarwal
Copy link
Contributor

Please feel free to close this. Continuing discussion and sharing code snippets on #858.

@felixakiragreen
Copy link
Contributor

@paramaggarwal - would it help if you were given a callback with the width and height of the network image when it finishes loading?

This is what I need. I don't know the width and height before I receive the image. Is there a way to do this @brentvatne ?

@brentvatne
Copy link
Collaborator

@DUBERT - there is no way to do this right now, at least as far as I know, but you could potentially submit a patch to provide this information in a load callback at some point. For example, you can add the following code to RCTImageDownloader to see the dimensions logged to your Xcode console:

  NSLog(@"*********************************************");
  NSLog(@"%@", url);
  NSLog(@"%f", image.size.height);
  NSLog(@"%f", image.size.width);
  NSLog(@"*********************************************");

I'm curious - what are your use cases for this?

@felixakiragreen
Copy link
Contributor

@brentvatne I have a listview with rows of flexible height. Some rows have network images, and I want to make them full width, and then have their height proportionally take up as much space as they need.

So I was thinking.. if I could get the height and width, then I could calculate how height it should be and set it. Because right now, if a static height is not set on the image, then it doesn’t show. But each one will be different, and I don't have it before hand.

@paramaggarwal
Copy link
Contributor

@DUBERT You'll see the items stutter around if you implement something like that, because let's say the third image loads first and takes up its space. Then the second one loads and pushes the third one down. Now imagine this constant re-layout for tens of items. Ideally you would want to let your server tell the app of the image uri as well as the width and height of the image beforehand.

@felixakiragreen
Copy link
Contributor

I can handle the stuttering, that's what I want: the image size in the onLoad as a callback. Because then at least I could have a progress bar, and then animated it to it's full height once it's loaded.

I've been digging around the RCT Image library but I don't know any Objective-C. :(

@paramaggarwal
Copy link
Contributor

Progress indicator is available: https://github.com/oblador/react-native-image-progress, but image size data is not exposed. Maybe you could start a separate issue to generate interest in implementing the feature?

What you are looking for is to send image.size.height and image.size.width in RCTImageView.m#L146-L147 inside event. Try this:

NSDictionary *event = @{
  @"target": self.reactTag,
  @"size": @{
    @"height": @(image.size.height),
    @"width": @(image.size.width)
  }
};

and then read it on e.nativeEvent.size in onLoad.

@felixakiragreen
Copy link
Contributor

@paramaggarwal Thank you very much for your assistance. One last issue if you're willing to help out. I'm using 0.8.0, and the source looks pretty different for it. Would I add that event here? https://github.com/facebook/react-native/blob/0.8-stable/Libraries/Image/RCTNetworkImageView.m#L123-L124 Doesn't the image need to be passed as a parameter?

I tried using master, but there were many errors in Xcode, I don't know if I'm supposed to build it or something :(

@paramaggarwal
Copy link
Contributor

@DUBERT Ah you are right. Here is what that entire section will look like:

Add this right under loadEndHandler declaration on #L122-L125: (making a copy that takes the image as an argument, should work for now)

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

and then call loadImageEndHandler(image); instead in the else block on line #L159. Then you can listen to e.size in onLoad.

If it works, please do raise a PR! (for the version on master) This is useful.

@felixakiragreen
Copy link
Contributor

Woohoo! I got it working, thanks so much @paramaggarwal. I'll try to get master working on my machine, so I can submit a PR for it.

@MossP
Copy link

MossP commented Jul 31, 2015

I look forward to this PR! :) 👍

@MossP
Copy link

MossP commented Aug 3, 2015

I'm having trouble implementing this. The size that gets returned across the bridge is the size that I had specified in the styles all of the time? Skipping the size declaration results in no image being loaded though. Could either of you shed any further light on this? @DUBERT, @paramaggarwal ?

@MossP
Copy link

MossP commented Aug 3, 2015

Further testing shows that it's not always the defined sizes that get returned. The sizes vary depending on the resizeMode used and whether the image would fill the space or not. I Can see different sizes coming through but, none of them relate to the actual size of the image that I'm seeing?

@paramaggarwal
Copy link
Contributor

@MossP I haven't tried this out, but the image.size should be the height/width of the image itself. The behaviour you describe seems to be the case if it was imageView.size. @DUBERT has actually tried this out - so will let him respond.

@MossP
Copy link

MossP commented Aug 3, 2015

Thanks, @paramaggarwal. I think I may have just found it. The image must have resizeMode 'contain' applied and also the sizes returned are scaled in proportion to the device dpi, e.g. iPhone6 returns 50/100 for a 100/200 image. Thanks for the code above. I think the only place it fails is for gif's but that's due to the alternate loading method.

@MossP
Copy link

MossP commented Aug 3, 2015

Extra info for anyone else.. the style attributed to the <Image /> element needs to be larger than the image it's loading in order to return the correct size. At the point that the image begins to get shrunk to fit the frame the sizes start to change their scaling value making meaningful readings difficult.

e.g. loading a 300/200 image yields the following results. (Container Size vs reported image size)

container / reported
500*500   / 160*100
400*400   / 160*100
300*300   / 160*100
200*200   / 160*100
100*100   / 100*62.5
50*50     / 50*31.5
10*10     / 10*6.5

Wrapping a large image window inside a 1*1 view with overflow:'hidden' will allow you to still read the sizes and display these against a smaller window if there is no other way around it. i.e use the large window to retrieve the size and the smaller window to actually display the image.

@originerd
Copy link
Contributor

I've published to npm react-native-fit-image. It enables you to draw responsive image component.

@facebook facebook locked as resolved and limited conversation to collaborators Jun 8, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

8 participants