5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【ReactNative】Androidでbase64画像の保存とPOST送信

Last updated at Posted at 2020-04-25

AndroidのReactNativeアプリでbase64画像の保存とPOST送信をします。

画像の保存

iOSでの保存、もしくはAndroidでhttp or httpsリソースの画像の保存(base64だとエラー)の場合

まずはbase64でない場合。
以下で画像のダウンロードができます。
一度FileSystemに画像をダウンロードして、そのURIを使っています。

DowloadImage.jsx

import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
import * as Permissions from 'expo-permissions';

const downloadImage=( file )=>{
    FileSystem.downloadAsync(
        file.uri,
        FileSystem.documentDirectory + 'image.jpeg'
    )
        .then( async ( { uri } ) => {
            const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL );
            if( status !== 'granted' ) return
            CameraRoll.saveToCameraRoll( uri, "photo" );
            MediaLibrary.saveToLibraryAsync( uri )
         })
}

Androidでbase64画像の保存の場合

Androidで、FileSystemでbase64画像を読み込むと、URLスキームがhttpかhttpsじゃないとダメですって怒られます。
ので、以下で保存します。

DowloadBase64Image.jsx

import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
import * as Permissions from 'expo-permissions';

const downloadImage=( file )=>{
    const dataUri = file.uri
    const tempFileDirectory = `${ FileSystem.cacheDirectory }uploadTmp`
    
    // 一時保存用のディレクトリを作る
    await FileSystem.makeDirectoryAsync( tempFileDirectory, { intermediates: true } ) 

    // 一時保存用のファイルを作る
    const tempFilePath = `${ tempFileDirectory }${ Date.now() }.jpeg`

    // データの中身を取り出す
    const base64EncodedData = dataUri.split( ',' )[ 1 ]

    // base64として、作ったファイルに書き込む
    await FileSystem.writeAsStringAsync( tempFilePath, base64EncodedData, {
            encoding: FileSystem.EncodingType.Base64,
        } )

    // そのファイルのパスをURIに、同様にカメラロールに保存
    const uri = tempFilePath
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL );
    if( status !== 'granted' ) return
    CameraRoll.saveToCameraRoll( uri, "photo" );
    MediaLibrary.saveToLibraryAsync( uri )

    // 一時的に作っていただけなので、ファイルを消す
    await FileSystem.deleteAsync( tempFilePath )                   
} 

Androidだと、ReactNativeのライブラリではFileSystemにそのままbase64はダウンロードできないので、自分でファイル作って書き込んで、それのURIを使っています。

POST送信

AndroidでAxiosを使って、base64画像を送信しようとすると、Network Errorが出ます。
これも、以下で送信可能です(ほぼ上記の保存と同じ)。

PostBase64Image.jsx

import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
import * as Permissions from 'expo-permissions';
import axios from 'axios'

const postImage=( file )=>{

    // 画像の保存と同様にFileSystemにファイルを作って書き込む
    const dataUri = file.uri
    const tempFileDirectory = `${ FileSystem.cacheDirectory }uploadTmp`
    toryAsync( tempFileDirectory, { intermediates: true } ) 
    const tempFilePath = `${ tempFileDirectory }${ Date.now() }.jpeg`
    const base64EncodedData = dataUri.split( ',' )[ 1 ]
    await FileSystem.writeAsStringAsync( tempFilePath, base64EncodedData, {
            encoding: FileSystem.EncodingType.Base64,
        } )

    const uri = tempFilePath
    // そのファイルのパスを、送るファイルのURIに指定
    const file = {
	    uri:uri,
	    type: "image/jpeg",
	    name: "file.jpeg",
	}
    const formData = new FormData()
    formData.append( "file", file )
    await axios.post( URL, data)
        .then( async () =>{ 
            // 一時的に作っていただけなので、ファイルを消す
            await FileSystem.deleteAsync( tempFilePath ) 
        })                  
} 

参考

[Android] FormData does not support data URIs

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?