ascoders / react-native-image-viewer

🚀 tiny & fast lib for react native image viewer pan and zoom
MIT License
2.44k stars 578 forks source link

'Save image to album' not working #345

Open javfel94 opened 4 years ago

javfel94 commented 4 years ago

Hi, I'm testing my app on an Android device, and the functionality of saving the image to the phone's album is not working (after long-pressing the image). Is anyone else running into the same issue? In any case, is there a way of disabling the menu after long-pressing? I'm using Expo to develop the app

ChrisLFieldsII commented 4 years ago

I am experiencing the same on IOS

lsirdevan commented 4 years ago

This works just fine on iOS and Android.

The onSave prop won't automatically save the image. You'll have to import CameraRoll from react-native-community and save the image that way. Read over the following to import it correctly: https://github.com/react-native-community/react-native-cameraroll

Here's an example of how i'm using it in my app:

import React from "react";
import { ActivityIndicator, Modal, Alert } from "react-native";
import CameraRoll from "@react-native-community/cameraroll";
import ImageViewer from "react-native-image-zoom-viewer";

export default class Example extends React.Component {
    state = {
        image_index: 0,
        images: [],
        show_modal: false
    };

    constructor(props) {
        super(props);

        this._getImages();
    }

    _getImages = () => {
        // Make some external request to get images if needed... This is just an example
        let images = [
            {
                uri: "some uri",
                props: {
                    id: 1
                },
            },
            {
                uri: "some uri2",
                props: {
                    id: 2
                },
            }
        ];

        this.setState({ images });
    };

    _saveImage = uri => {
        let promise = CameraRoll.saveToCameraRoll(uri);

        promise
            .then(function(result) {
                Alert.alert(
                    "Success",
                    "Image Saved to Photo Gallery",
                    [
                        {
                            text: "OK"
                        }
                    ],
                    { cancelable: false }
                );
            })
            .catch(function(error) {
                Alert.alert(
                    "Error Saving Image",
                    error,
                    [
                        {
                            text: "OK"
                        }
                    ],
                    { cancelable: false }
                );
            });
    };

    render() {
        return (
            <Modal visible={this.state.show_modal} transparent={true}>
                <ImageViewer
                    imageUrls={this.state.images}
                    index={this.state.image_index}
                    enableSwipeDown
                    enablePreload
                    loadingRender={() => (
                        <ActivityIndicator
                            style={{
                                justifyContent: "center",
                                alignSelf: "center"
                            }}
                            size="large"
                            color="#FFFFFF"
                        />
                    )}
                    onSave={uri => this._saveImage(uri)}
                    onSwipeDown={() => this.setState({ show_modal: false })}
                    menuContext={{
                        saveToLocal: "Save Image",
                        cancel: "Cancel"
                    }}
                />
            </Modal>
        );
    }
}
BruceSuperProgramer commented 4 years ago
const saveImage = async uri => {
    RNFetchBlob.config({
      fileCache: true,
      appendExt: 'png',
    })
      .fetch('GET', uri)
      .then(res => {
        CameraRoll.saveToCameraRoll(res.data, 'photo')
          .then(res =>
            Alert.alert(
              'Success',
              'Image Saved to Photo Gallery',
              [
                {
                  text: 'OK',
                },
              ],
              {cancelable: false},
            ),
          )
          .catch(err =>
            Alert.alert(
              'Error Saving Image',
              error,
              [
                {
                  text: 'OK',
                },
              ],
              {cancelable: false},
            ),
          );
      })
      .catch(error =>
        Alert.alert(
          'Error Saving Image',
          error,
          [
            {
              text: 'OK',
            },
          ],
          {cancelable: false},
        ),
      );
  };

 <ImageViewer
          ref={n => {
            imageViewer = n;
          }}
          enablePreload={true}
          useNativeDriver={true}
          onSave={uri => saveImage(uri)}
          imageUrls={images}
        />

onSave will let you write custom code for image store operation. For the image store operation you can use rn-fetch-blob like what I did.

WangZiXiao-ChenDu commented 3 years ago

因为 saveToLocal 方法中 if (!this.props.onSave) { CameraRoll.saveToCameraRoll(this.props.imageUrls[this.state.currentShowIndex || 0].url); this!.props!.onSaveToCamera!(this.state.currentShowIndex); } else { this.props.onSave(this.props.imageUrls[this.state.currentShowIndex || 0].url); } !this.props.onSave有默认值所以此条件永远不满足,导致保存失败。临时解决方案 onSave值设置null 可以正常运行