React-native, how to resize the image based on the original size of image?

9.5k Views Asked by At

I have list of images to be displayed, wherein size of the image is unknown, how can I display the image fully without any transparent spaces in top and bottom of the image? (I tried getting image size from getSize method, which is eventually giving lot of spaces in top and bottom) I wanted image to resized and fit in like this, I wanted image to resized and fit in like this,

But I'm getting white spaces if I put resize mode to contain, and if I put resize mode to stretch the size of small image is loosing its quality and if I put resize mode to stretch the size of small image is loosing its quality

how can I resize the image so that the white spaces are removed, and fit itself

2

There are 2 best solutions below

0
On BEST ANSWER
    import React, { Component } from "react";
    import { Dimensions, Image } from "react-native";

    const { width, height } = Dimensions.get("window");

    export default class ResizedImage extends Component {
      constructor(props) {
        super(props);
        this.state = {
          height: 0
        };
      }

      componentDidMount() {
        Image.getSize(
          this.props.source.uri,
          (srcWidth, srcHeight) => {
            const ratio = Math.min(width / srcWidth, height / srcHeight);
            this.setState({ height: srcHeight * ratio });
          },
          error => console.log(error)
        );
      }
      componentWillUnmount() {
        this.setState({ height: 0 });
      }

      render() {
        const { source} = this.props;
        return (
          <Image
            source={{ uri: source.uri }}
            style={{
              width: width * 0.9,
              height: this.state.height
            }}
            resizeMode={"cover"}
          />
        );
      }
    }

You can use this as component and pass the URI as props and everything is done.

0
On

This is the image component I wrote to solve that issue. It works with both Image and ImageBackground (with children).

import React, {Component} from 'react';
import resolveAssetSource from 'resolveAssetSource';
import {
    Image,
    ImageBackground,
    View,
} from 'react-native';

export default class ScalableImageComponent extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        const source = resolveAssetSource(this.props.source);
        if (source == null) {
            return null;
        }
        const aspectRatio = source.width / source.height;
        const fixedWidth = this.props.width;
        const fixedHeight = this.props.height;

        const widthCalculated = fixedWidth != null ? fixedWidth : fixedHeight * aspectRatio;
        const heightCalculated = fixedHeight != null ? fixedHeight : fixedWidth / aspectRatio;

        if (this.props.isBackgroundImage) {
            return (
                <ImageBackground
                    source={this.props.source}
                    style={[
                        this.props.style,
                        {
                            width: widthCalculated,
                            height: heightCalculated,
                        }
                    ]}
                >
                    {this.props.children}
                </ImageBackground>
            );
        } else {
            return (
                <Image
                    source={this.props.source}
                    style={[
                        this.props.style,
                        {
                            width: widthCalculated,
                            height: heightCalculated,
                        }
                    ]}
                />
            );
        }
    }
}

Use it just like you would use a regular image. If you want it to be an image background just pass a prop isBackgroundImage={true} eg:

<ScalableImageComponent
    isBackgroundImage={true}
    source={require('./static.png')}
>
<Text>text over image</Text>
</ScalableImageComponent>