簡體   English   中英

保存 NativeScript/Angular ImagePicker 選擇或獲取完整文件路徑

[英]Save a NativeScript/Angular ImagePicker selection or get the full file path

使用圖像選擇器選擇圖像后,我收到內容// url

content://com.android.providers.media.documents/document/image%3A139

使用 ImageSource.fromAsset() 時,我返回空 object。我當前的目標是將該圖像另存為新圖像,以便我可以將其發送到請求中。

我也嘗試過 Utils.android.getApplicationContext().getContentResolver() 但無濟於事。

    public onSelectSingleTap() {
    return new Promise((resolve, reject) => {
        this.isSingleMode = true;

        let context = imagepicker.create({
            mode: "single",
            mediaType: ImagePickerMediaType.Image,
        });

        context
            .authorize()
            .then(() => {
                return context.present();
            })
            .then((selection) => {
                if (selection.length > 0) {
                    ImageSource.fromAsset(selection[0])
                        .then((imageSource) => {
                            console.log('Image Source: ', imageSource)
                            let documentsFolder = knownFolders.documents();
                            let random = Math.floor(Math.random() * 1000000000);
                            const filePath: string = path.join(documentsFolder.path, 'image' + random.toString());
                            let saved = imageSource.saveToFile(filePath, 'jpg')
                            if (saved) {
                                const savedFilePath: string = path.join(documentsFolder.path, 'image' + random.toString() + '.jpg');
                                const file: File = File.fromPath(savedFilePath);
                                // resolve({file: file, content: selection[0]})
                            }
                        })
                        .catch((err) => console.error("Error loading ImageSource:", err));
                }
            });
    })
}

圖片來源:{“安卓”:{}}

我不確定我是否需要另存為新圖像或獲取實際文件路徑以在我的請求中發送它。

我遇到的大多數其他答案都已棄用。

我不得不在幾年前構建的應用程序中的幾個地方執行此操作。 該應用程序使用@nativescript/core@7.1.3 和@nativescript/imagepicker@1.0.2。 我認為它應該在當前版本中仍然有效。

我已經實現了一個可重用的服務來觸發圖像選擇器並返回圖像路徑數組。 該數組被鍵入為字符串數組,但我不確定它實際上是什么。 (當時沒有正確輸入內容是一個巨大的疏忽)

import { Injectable } from '@angular/core'
import * as imgPicker from '@nativescript/imagepicker'
import { ImageSource, Folder, knownFolders, path, isAndroid, isIOS } from '@nativescript/core'

@Injectable({
   providedIn: 'root'
})
export class ImagePickerService {
   private iosFolder: Folder
   private iosCounter = 0

   constructor() {}

   public async chooseImages(maxImages: number, folderName: string): Promise<string[]> {
      // init image picker
      const options: imgPicker.Options = {
         mode: maxImages > 1 ? 'multiple' : 'single',
         mediaType: imgPicker.ImagePickerMediaType.Image
      }
      const context = imgPicker.create(options)

      // authorize
      await context.authorize()

      // get selection
      const selection = await context.present()
      const imgPaths = []
      if (!selection || !selection.length) return imgPaths

      // create folder for ios
      if (isIOS) {
         this.iosFolder = knownFolders.documents().getFolder(folderName)
      }

      // get the local path for each image and add it to images array
      for (const imgAsset of selection) {
         if (isIOS) {
            const imgSrc = await ImageSource.fromAsset(imgAsset)

            // imgAsset.ios is PHAsset and not path - so I am creating my own path
            const imgPath = path.join(this.iosFolder.path, `${Date.now()}-${this.iosCounter}.jpg`)
            imgSrc.saveToFile(imgPath, 'jpg')
            imgPaths.push(imgPath)
            this.iosCounter++
         } else if (isAndroid) {
            imgPaths.push(imgAsset.android.toString())
         }
      }

      return imgPaths
   }

   public clearFolder(folderName: string): void {
      if (this.iosFolder) this.iosFolder.clear()
   }
}

獲得圖像路徑列表后,您可以通過后台 http 服務將它們發送到后端:

import { Injectable } from '@angular/core'
import { UtilsService } from './utils.service'
const bgHttp = require('@nativescript/background-http')
const nsLocalStorage = require('@proplugins/nativescript-localstorage')
import { config } from '../config/config'
import { UserError } from '../classes/custom-errors'

@Injectable({
   providedIn: 'root'
})
export class FormdataService {
   private serverUrl = this.utilsService.serverUrl

   constructor(private utilsService: UtilsService) {}

   public uploadPhotos(imgPaths, folder, complete, res) {
      const jwt = nsLocalStorage.getItem('JWT')

      // upload configuration
      const session = bgHttp.session('images')
      const request = {
         url: `${this.serverUrl}/photos/${folder}`,
         method: 'POST',
         headers: {
            'Content-Type': 'application/octet-stream',
            Authorization: `Bearer ${jwt}`
         },
         androidDisplayNotificationProgress: true,
         androidAutoClearNotification: true
      }

      // prepare images for upload
      const uploadImgs = imgPaths.map((image) => {
         if (image.size > config.fileSizeLimit) throw new UserError('One or more photos are too large.')
         return { name: 'images', filename: image, mimeType: 'image/jpeg' }
      })

      // upload images and data
      const task = session.multipartUpload(uploadImgs, request)

      // handle events
      task.on('complete', (e) => complete(e))
      task.on('error', (e) => complete(e))
      task.on('responded', (e) => res(e.data))
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM