Get Original Image Size in React Native
Posted By: Harish

We have seen a callback, onLoad to get the image size details after rendering the image. This is loaded image size which can be different from original image size. But sometimes we may need the original image size before even rendering.
For this, we have two methods for getting remote image size, getSize() and getSizeWithHeaders().
For local resource files, we have resolveAssetSource() method to get the size.
We will see their output in this post.
Create A New Project
Create a new react-native project by using npx. Check documentation for creating a new react native project.
npx react-native@latest init ImageRN
Example Implementation
We will create a simple screen with the above methods implementation.
Import and add Image
component with a local or remote image source.
To understand better, we will load a remote URL to get on load and original sizes.
//App.tsx
...
import { Image } from 'react-native';
...
const remoteImage = 'https://iet-images.s3.ap-south-1.amazonaws.com/fav.png';
...
<Image
style={styles.image}
resizeMode="contain"
onLoad={(e) => {
const data = e.nativeEvent;
console.log("On Load: ", data);
}}
src={remoteImage}
/>
...
If we run the app,
#for Android
npx react-native run-android
#for ios
npx react-native run-ios
We will get the width and height of the loaded image. Please note that the images get adjusted based on the screen and resize modes.
LOG On Load: {"source": {"height": 266, "uri": "https://iet-images.s3.ap-south-1.amazonaws.com/fav.png", "width": 355}, "target": 169}
Now, we will reload the app with getSize() and getSizeWithHeaders() methods.
Import useEffect
from react and run both methods at the same time. Check below code.
...
useEffect(() => {
Image.getSize(
remoteImage,
(width, height) => {
console.log("Original Size: ", width, height);
},
(err) => {
console.log(err);
}
)
Image.getSizeWithHeaders(
remoteImage,
{
'Content-Type': 'image/png',
'Authorization': 'your-token'
},
(width, height) => {
console.log("Original Size With Headers: ", width, height);
},
(err) => {
console.log(err);
}
)
}, []);
...
From the above code, we can see that these methods are called before rendering and we will get width and height properties as a callback event.
Both methods are the same but use the getSizeWithHeaders()
method when headers are needed to load the image.
LOG Original Size: 1200 900
LOG Original Size With Headers: 1200 900
Above methods are for remote images, but what about local image assets?
For local images, we can use the resolveAssetSource()
method. This takes the path of the image.
...
const imagePath = require('./assets/fav.png');
...
useEffect(() => {
...
const width = Image.resolveAssetSource(imagePath).width;
const height = Image.resolveAssetSource(imagePath).height;
console.log("Original Local Image Size: ", width, height);
...
}, []);
...
If we reload the screen, we will get the original width and height of the local image.
LOG Original Size With Headers: 1200 900

Complete code of our example,
//App.tsx
import React, { useEffect, useState } from "react";
import {
Text,
StyleSheet,
SafeAreaView,
StatusBar,
View,
Image
} from "react-native";
export default function App() {
const [originalSize, setOriginalSize] = useState({});
const [loadSize, setLoadSize] = useState({});
const remoteImage = 'https://iet-images.s3.ap-south-1.amazonaws.com/fav.png';
const imagePath = require('./assets/fav.png');
useEffect(() => {
// Remote Image without Headers
Image.getSize(
remoteImage,
(width, height) => {
console.log("Original Size: ", width, height);
setOriginalSize({
width: width,
height: height
})
},
(err) => {
console.log(err);
}
);
// Remote Image with Headers
Image.getSizeWithHeaders(
remoteImage,
{
'Content-Type': 'image/png',
'Authorization': 'your-token'
},
(width, height) => {
console.log("Original Size With Headers: ", width, height);
},
(err) => {
console.log(err);
}
);
// Local Image
const width = Image.resolveAssetSource(imagePath).width;
const height = Image.resolveAssetSource(imagePath).height;
console.log("Original Local Image Size: ", width, height);
}, []);
return (
<SafeAreaView style={{ flex: 1, backgroundColor: 'white' }}>
<StatusBar
barStyle="dark-content"
/>
<View style={styles.container} >
<Text style={styles.text}>
ifelsething.com
</Text>
<Text style={styles.text}>
original image size and loaded image size in react native
</Text>
<Image
style={styles.image}
resizeMode="contain"
onLoad={(e) => {
const data = e.nativeEvent;
console.log("On Load: ", data);
setLoadSize({
width: data.source.width,
height: data.source.height
})
}}
src={remoteImage}
/>
<Text style={styles.text}>
Original Image Size: {originalSize.width} x {originalSize.height}
</Text>
<Text style={styles.text}>
On Load Image Size: {loadSize.width} x {loadSize.height}
</Text>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
margin: 10,
gap: 20,
},
text: {
fontSize: 15,
color: 'black',
fontStyle: 'italic'
},
image: {
width: '100%',
height: 300,
alignSelf: 'center',
}
});