Чтение двоичных данных из BLOB-объекта для отображения Image React Native

вот поток того, что я должен сделать:

  1. возьмите изображение с помощью средства выбора изображения для реагирования на нативный и получите данные изображения в base64 (sourceData)
ImagePicker.showImagePicker(imagePickerOptions, (response) => {
    const sourceData = { uri: 'data:image/jpeg;base64,' + response.data };
});
  1. Отправьте sourceData.uri на сервер, работающий локально на моей машине:
const data = new FormData();
data.append('receipt', {
    uri: sourceData.uri,
    type: 'image/jpeg',
    name: 'receipt'
});

const response = await fetch(SERVER_POST_ROUTE, {
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'multipart/form-data',
    },
    body: data
});

sourceData.uri выглядит так:

'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABLKADAAQAAAABAAAA4QAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgA4QEsAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMABgYGBgYGCgYGCg4KCgoOEg4ODg4SFxISEhISFxwXFxcXFxccHBwcHBwcHCIiIiIiIicnJycnLCwsLCwsLCwsLP/bAEMBBwcHCwoLEwoKEy4fGh8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u<…>'
  1. Это маршрут POST сервера (сокращенный)
router.post('/:id/receipts', (req, res) => {
  const id = req.params.id
  const expense = expenses.find((expense) => expense.id === id)

  if (expense) {
    const receipt = req.files.receipt as UploadedFile
    const receiptId = `${id}-${expense.receipts.length}`
    receipt.mv(`${process.cwd()}/receipts/${receiptId}`, (err) => {

      expense.receipts.push({
        url: `/receipts/${receiptId}`
      })
      res.status(200).send(expense)

    })

  } else {
    res.status(404)
  }
})
  1. Вот что получает сервер, когда я console.log(receipt)
{ name: 'receipt',
  data:
   <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 48 00 48 00 00 ff e1 00 58 45 78 69 66 00 00 4d 4d 00 2a 00 00 00 08 00 02 01 12 00 03 00 00 00 01 00 01 ... >,
  encoding: '7bit',
  truncated: false,
  mimetype: 'image/jpeg',
  md5: SOME_MD5_STRING,
  mv: [Function: mv] }
  1. Как видите, сервер перемещает файл в локальную папку receipt.mv(`${process.cwd()}/receipts/${receiptId}`).

<сильный>6. МОЯ ПРОБЛЕМА: мне нужно получить доступ к этому местоположению и преобразовать то, что я получаю, в изображение

Что я делаю прямо сейчас: - Используйте fetch, чтобы получить то, что находится в этом месте, и извлечь blob

const response = await fetch(FILE_LOCAL_URL);
const blob = await response.blob();
  • И вот что я получаю, когда console.log(blob)
{ _data: 
   { size: 23296,
     offset: 0,
     blobId: 'F8F693CD-6FBB-41C8-95E3-E54EB2A82F63',
     type: 'application/octet-stream',
     name: '5b996064dfd5b783915112f5-3' } }

Теперь: я не могу понять, как превратить этот двоичный файл в строку base64, чтобы добавить к uri изображения. Вот что я пробовал, но, очевидно, это не работает:

<Image 
    source={{ uri: 'data:image/jpeg;base64,' + blob._data }}
    style={{height: 120, width: 80}}/>

Любая помощь действительно приветствуется. Спасибо


person TheGees    schedule 03.11.2019    source источник
comment
для получения файла вы можете использовать github.com/joltup/rn-fetch-blob. выборка не работает должным образом для извлечения файла   -  person Majid lotfinia    schedule 03.11.2019


Ответы (1)


На самом деле я решил это: для чтения блоба в идеале вы должны использовать readAsArrayBuffer, но это не реализовано в нативном реагировании (читайте также https://forums.expo.io/t/blob-object-how-can-i-access-the-blobs-raw-data-as-arraybuffer/9717). Но вы можете использовать readAsDataURL То, что я искал, хранится в reader.result.

const response = await fetch(URL_OF_BINARY_DATA_FILE);
const blob = await response.blob();
var reader = new FileReader();
reader.onload = () => {
   console.log(reader.result);  
}
reader.readAsDataURL(blob);
person TheGees    schedule 05.11.2019
comment
Это работает только с выставочными проектами, а не с чистыми проектами RN. Выборка RN не отправляет данные больших двоичных объектов через мост RN, поэтому вы не можете прочитать их со стороны JS. - person philk; 12.10.2020