There is really low quality when loading large bundled images, even when using resizeMethod="resize"
. This happens only on Android, not on any iOS simulator/device. Have tested it on Android 8.1 emulator and LG G6 with Android 8.0. Please see the screenshots bellow.
At the left screenshot we see the exact same code running with RN 0.56.0 and at the right screenshot we see RN 0.57.5. The code is just a simple image <Image source={require('./assets/ELHall1.png')} resizeMethod="resize" />
and the image size is 2111 x 4645 pixels
. Both projects are fresh installed using react-native init RN057ImageTest
and react-native init --version="0.56.0" RN056ImageTest
.
Simple App with an Image
...
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
{/*<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>To get started, edit App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>*/}
<Image source={require('./assets/ELHall1.png')} resizeMethod="resize" />
</View>
);
}
}
...
I have created a Github issue to RN repo since September but noone has replied which makes me think that I am doing something wrong. Is there a new prop or an other way to make large images show normal with full quality in RN 0.57.x? Maybe the metr obuilder updates to 0.57.x have changed how the bundler handles the image assets? I have used resizeMethod
prop to "scale"
and "resize"
with no difference at all. I have used PNG8
, PNG24
and PNG32
all same result.
EDIT
The Github repo with the code and the PNG image files: https://github.com/clytras/RN057ImageTest
Please don't give any answers about JPEG images and that they do work, I already know that; I want to make PNG images work like they do in RN 0.56.
UPDATE JAN/2020
This is an update for people landing here regarding this issue.
The RN Issue has been closed since August 10, 2019 with the statement that this is not a React Native issue but rather a Fresco issue.
I have created an issue at Fresco on August 22, 2019 and after some conversations and talkings, the only way for now to disable image downsample, is to compile Fresco from source after removing/comment out the downsample code inside DecodeProducer.java
.
I have created a repository that has RN 0.61 and has detailed instructions on how to compile Fresco and disable image downsample. The repository can be found here: https://github.com/clytras/RN061FrescoBuild.
It turns out Fresco has a bug and does not apply Fresco configuration using ImagePipelineConfig
and MainPackageConfig
inside MainApplication.java
, you can see more details about this here. RN has downsampling disabled by default! Until Fresco fixes this issue, the only way to disable image downsampling is to compile Fresco from source after removing the downsample code.
UPDATE FEB/2020
I have created a react-native-community/cli template that has RN 0.61.5 project and the required modifications to build Fresco from source. This is an easy and quick way to have a new RN project crafted with custom project name and with the changes needed to compile Fresco from source. It also uses Android NDK Revision 21 and I have tested it on macOS and Windows using yarn 1.21.
Github repository: clytras/react-native-fresco
NPM template: @lytrax/react-native-fresco
It can be installed like this:
npx @react-native-community/cli@next init --template=@lytrax/react-native-fresco <ProjectName>
There are detailed installation instruction in the README. You need to clone/patch Fresco using yarn fresco-setup
and then install Android NDK and create android/libraries/fresco/local.properties
with Android NDK path.
If you are using react-native-image-picker for uploading images, you can set maxWidth, maxHeight or quality of image for reducing the size.
To resize image with React Native, we set the width and height of the image to percentages and set resizeMode to 'cover' . <View style={{ width: 180, height: 200, aspectRatio: 1 * 1.4, }} > <Image source={{ uri: item.
React Native FastImage is a quick way to load images in React Native. All loaded pictures are aggressively cached by FastImage. You may add your own auth headers and preload pictures to your requests. GIF caching is also supported by react-native-fast-image.
I tested FastImage and it had a better quality
<FastImage source={require('./assets/ELHall1.png')} style={{height: '100%', aspectRatio: 2.5}} />
Most of the times it is the dimensions of the Image that matter, UI designers make Designs to standard high end Mobile phones(with fixed Screen Size) and export the Images as .png to xhdpi,xxhdpi and xxxhdpi resolutions. So developers rename those Images by appending @1x, @2x & @3x to those resolutions. Example: ELHall1@1x ,ELHall1@2x, ELHall1@3x
.
When Importing Images use the standard name of the Image. Example: ELHall1.png
.
To workaround <Image>
tag I use the help of Dimension
API in React-Native to auto set the width and height of the Image most of the time.
Example: var {height, width} = Dimensions.get('window');
For Example, if the Image has to cover the whole screen, I would do,
<View style={{flex:1,width:"100%",height:"100%"}}>
<Image style={{width:width, height:height}} source={require('./assets/ELHall1.png')} />
// width & height is auto taken using Dimension API
// To play around pixels use resizeMode= ("contain","center") (Keep this as last option)
</View>
I Hope I could help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With