0

I am trying to create a mobile application (using React Native with JavaScript), by which you can create and view posts. The posts contain an image, and the preview is supposed to only show a thumbnail of the original image, but the original image (usually high quality, high resolution) should be shown, when clicking on the thumbnail image.

But with my current implementation the original images inside the modal look very pixelated in the zoom view. My problem is somehow similar to this post. However, in my application it happens both on Android and on iOS, which makes me think, that the cause in my case is different.

Here is the code, that renders the thumbnail, as well as the modal, which contains the full-size image inside of a react-native-zoomable-view:

Posts.js

import { ReactNativeZoomableView } from '@openspacelabs/react-native-zoomable-view';
import Modal from "react-native-modal";
import { AutoscaleImage } from '../../atoms';
...

var windowWidth = Math.ceil(Dimensions.get('window').width);

export const FullWidthPostsContainer = ({ props }) => {
    const [modalVisible, setModalVisible] = useState(false);
    const [contWidth] = useState(0);
    const [contHeight] = useState(0);
    return (
        <View style={styles.container}>
            <Modal
                isVisible={modalVisible}
                style={{ margin: 0 }}
                animationIn="fadeIn"
                animationOut="fadeOut"
                backdropOpacity={0.8}
                propagateSwipe
            >
                <TouchableOpacity
                    style={styles.button}
                    onPress={() => setModalVisible(!modalVisible)}
                >
                    <Icon name='window-close' size={30} color="lightgray" />
                </TouchableOpacity>

                <ReactNativeZoomableView
                    maxZoom={6}
                    minZoom={1}
                    zoomStep={0.5}
                    initialZoom={1}
                    bindToBorders={true}
                    visualTouchFeedbackEnabled={false}
                    onZoomAfter={this.logOutZoomState}
                    disablePanOnInitialZoom={true}
                    style={{borderColor: "yellow", borderWidth: 0}}
                >
                    <AutoscaleImage uri={props.image} width={Dimensions.get('window').width}/>
                    
                </ReactNativeZoomableView>
            </Modal>

            <TouchableOpacity
                onPress={() => setModalVisible(true)}
            >
                <FullWidthImage
                    props={props}
                    contHeight={contHeight}
                    contWidth={contWidth}
                />
            </TouchableOpacity>

        </View>
    )
}

const styles = StyleSheet.create({
    container: {
        marginVertical: "0%",
        borderWidth: 0,
        borderColor: "red",
        flex: 1,
        maxWidth: "100%"
    },
    button: {
        flexDirection: "row",
        justifyContent: 'flex-end',
        paddingVertical: 12,
        paddingHorizontal: 32,
        elevation: 3,
        maxHeight: 50,
        top: 40,
        zIndex: 400
    }
})

My idea was, that the original images are rendered in their full size (and quality) by the AutoscaleImage component shown below (compare this post):

AutoscaleImage.js

import React, { Component } from "react";
import { Image } from "react-native";
import { PropTypes } from "prop-types"


export default class ScaledImage extends Component {
    constructor(props) {
        super(props);
        this.state = { source: { uri: this.props.uri } };
    }

    componentDidMount() {
        Image.getSize(this.props.uri, (width, height) => {
            if (this.props.width && !this.props.height) {
                this.setState({
                    width: this.props.width,
                    height: height * (this.props.width / width)
                });
            } else if (!this.props.width && this.props.height) {
                this.setState({
                    width: width * (this.props.height / height),
                    height: this.props.height
                });
            } else {
                this.setState({ width: width, height: height });
            }
        });
    }

    render() {
        return (
            <Image
                source={this.state.source}
                style={{ height: this.state.height, width: this.state.width }}
            />
        );
    }
}

ScaledImage.propTypes = {
    uri: PropTypes.string.isRequired,
    width: PropTypes.number,
    height: PropTypes.number
};

What am I doing wrong?

0 Answers0