在 Android 上的 React-Native 中压缩 Base64 编码图像无法识别“数据”协议

2023-12-05

Issue

在 React-Native (0.43) 应用程序中,我们使用一个组件,该组件使用 SectionList 来渲染按天排序的照片。每个部分可以包含多个图像。照片是使用反应本机图像作物选择器库并上传到后端,或者在没有可用互联网连接的情况下在本地排队,以 base64 格式编码。图像分辨率设置为 800x800 像素(图像其他用途的要求)。在内存较低的手机上,渲染约 20 张图像将导致应用程序因内存不足而崩溃。此问题只能在低端 Android 手机上重现,但我预计这是内存不足的问题,与操作系统无关。为了解决这个问题,需要生成缩略图来测试是否是这种情况。与这些缩略图的生成时间无关(在发送到服务器之前或在加载组件之前即时生成)。下面的代码在 iOS 上运行良好,但在 Android 上会抛出错误:未知协议:数据它来自于ImageEditor.cropImage()功能。

主 .js 文件的片段

//The mergeReduxWithMeteor function takes care of merging the redux state, 
//containing images not yet uploaded to the server, 
//and the Meteor data as received by the server.
//No issues here...

helpers.mergeReduxWithMeteor(props.photoStore, props.SynergySummaryReady ? props.SynergyData : [])

  //The imageHelper.compressPhoto does the actual compression
  //No issues with the promise chain as is.

  .then((data) => {
    return Promise.all(data.map(imageHelper.compressPhoto))
  })

  // The remaining functions take care of the formatting for the SectionList.
  // No issues here either... :)

  .then((data) => {
    return helpers.clusterDataByDay(data)
  })

  //We populate the resulting data in the state that is used for the SectionList

  .then((data) => {
    this.setState({NotHorusData: data})
  })
  .catch((error) => console.error(error))

imageHelper.compressphoto()

export function compressPhoto(photo) {
  return new Promise((resolve, reject) => {

    let imageSize = {
      offset: {
        x: 0,
        y: 0
      },
      size: {
        width: IMAGE_SIZE,
        height: IMAGE_SIZE
      },
      displaySize: {
        width: IMAGE_TARGET_SIZE,
        height: IMAGE_TARGET_SIZE,
      },
      resizeMode: 'contain'
    }


    ImageEditor.cropImage(`data:image/jpeg;base64,${photo.data.userPhoto}`, imageSize, (imageURI) => {
      ImageStore.getBase64ForTag(imageURI, (base64Data) => {
        resolve({
          ...photo,
          data: {
            ...photo.data,
            userPhoto: base64Data,
          }
        })
      }, (error) => reject(error))
    }, (error) => reject(error))

  })
}

方法一:修复Android上的数据协议问题

Github 上的问题来自 RN 解决了​​同样的问题,但没有提供解决方案。

方法2:在Android上通过提供uri来绕过数据协议问题

尽管由于增加的通信/延迟而不太有利,但另一种方法是通过提供 ImageStore 提供的临时 URI 来避免数据协议问题。请参阅下面针对 Android 的改编代码。

if(Platform.OS === 'android'){
  ImageStore.addImageFromBase64(`data:image/jpeg;base64,${photo.data.userPhoto}`, (tempURI) => {
    ImageEditor.cropImage(tempURI, imageSize, (imageURI) => {
         ImageStore.getBase64ForTag(imageURI, (base64Data) => {
           ImageStore.removeImageForTag(tempURI)
           resolve({
             ...photo,
             data: {
               ...photo.data,
               userPhoto: base64Data,
             }
           })
       }, (error) => reject(error))
     }, (error) => reject(error))
  }, (error) => reject(error))  
}

很遗憾ImageStore.addImageFromBase64Android 上无法识别。

有谁有任何经验图片编辑器 and 图片库在 Android 上,这在这种情况下可能会有帮助吗?也欢迎任何其他方法!


我设法使用以下方法解决了这个问题反应本机获取 blob and 反应本机图像调整器适用于 iOS 和 Android。与上述问题中的实现相比,性能出乎意料地好。我分享了下面的代码供其他人使用:)

export function compressPhoto(photo) {
    return new Promise((resolve, reject) => {

        let tempUri = `${cache}/Vire_${photo.data.userPhotoDate}.jpg`

        fs.writeFile(tempUri, photo.data.userPhoto, "base64")
            .then(() => {
                ImageResizer.createResizedImage(
                    `file:${tempUri}`, IMAGE_TARGET_SIZE, IMAGE_TARGET_SIZE, "JPEG", 100, 0).then((resizedImageUri) => {
                    fs.readFile(`${resizedImageUri}`, "base64")
                        .then( data => {
                            resolve({...photo, data: { ...photo.data, userPhoto: data }})
                        })
                        .catch(error => reject(`readFile:error: ${error}`))
                },
                (error) => reject(`createResizedImage:error: ${error}`)
                )
            })
            .catch( error => {
                reject(`writeFile:error: ${error}`)
            })
            
  })
}

要点是将base64编码的图片存储在缓存目录中,并使用imageResizer获取图像,压缩它,然后以base64再次读取它以供使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Android 上的 React-Native 中压缩 Base64 编码图像无法识别“数据”协议 的相关文章

随机推荐

  • NoClassDefFoundError:com.opencsv.CSVWriter

    我尝试使用 opencsv libray 来获取加密格式数据 但在 CSV writer 上写入时 我收到 NoClassDefFoundError 我看过很多与相同错误相关的帖子 并尝试了几乎所有方法 但仍然无法纠正问题 下面的链接有同样
  • 现在如何使用 Blaze 在 Meteor 模板中的动态字段上使用 X-editable?

    I had x 可编辑在 Meteor 0 7 2 中工作 但自从升级到 0 8 0 后 它不再正确渲染 我往往会得到一堆空标签 这很令人沮丧 因为数据就在那里 只是在渲染函数被触发时还没有
  • 使服务层可以访问对象,而无需在 MVC4 应用程序中作为参数传递

    我正在构建一个多租户 MVC 应用程序 其中有一个应用程序池和一个数据库 我有一个租户表 并且我的每个模型都有一个标识的 TenantId 每个租户都有一个字符串 Url 用于标识用于访问该租户数据的完整 URL 我可以通过以下方式从 Ba
  • 如何对列表重新排序? [关闭]

    Closed 这个问题需要调试细节 目前不接受答案 给定一个任意大小的数组n 我想根据数组的离散索引重新组织数组的元素 Python 示例 Unique array of size n a b c d e
  • 对 Tkinter bind_class 感到困惑

    我定义了 GCanvas Canvas 的扩展 我的目的是在类级别绑定到 GCanvas 它不起作用 我还尝试绑定到 tk Canvas 但它也不起作用 绑定到root或 GCanvas 实例工作正常 这两种选择对我来说都没有用 但我只是尝
  • PowerShell:将 HTML 表提取为 CSV

    我正在尝试将 HTML 表提取到 CSV 文件 我对 PowerShell 了解不多 但在网上我找到了一些示例 但我总是收到相同的错误消息 您不能对空值表达式调用方法 行数 8 字符 1 table oHTML ParsedHtml bod
  • 使用重写规则从 url 中删除 .php

    我想重写 nginx 中的 url 以便 php扩展名可以省略 这就是我所拥有的 但这对我不起作用 有人知道如何做到这一点吗 Thanks server listen 80 server name example com return 30
  • 根据 3 个变量的颜色 - 麦克斯韦三角形

    我有一个由三个变量 u v w 组成的模型 它们随时间和空间而变化 我对这三个变量的比率特别感兴趣 但我宁愿只使用一张图 而不是显示三张图 每张图对应一个变量 我的想法是使用麦克斯韦三角形 颜色三角形 参见http homepages ab
  • ASP.NET Intranet 站点要求提供凭据 - Windows 身份验证

    我在 ASP Net 中创建了我的第一个网站 并且正在尝试在我们工作的 Intranet 上启动并运行它 我现在几乎已经完成了所有事情 但我遇到了障碍 我需要使用 Windows 身份验证 我的团队的要求 因此我完成了设置网站的过程 我已配
  • 对同一对象调用两次 MustHaveHappened 失败

    给定以下被测类 以及关联的 DTO 类和接口 public class Foo private readonly IBar bar public Foo IBar bar bar bar public void DoStuff var dt
  • 如何在项目中包含多个log4j2.xml文件?

    我的项目由多个模块组成 每个模块都可以独立运行并有单独的log4j2 xml 假设 Project X 由三个模块组成 模块 A 有 log4j2 xml 包含 Loggers 和 Appenders 模块 B 有 log4j2 xml 模
  • .vimrc 来源不正确

    我的 vimrc 中有以下几行 colorscheme solarized 这显然设置了日晒配色方案 我实际的 vimrc 肯定比这个长 并且我还指定了更多 Solarized 选项 但是 我面临的问题可以使用这个最小的 vimrc 文件来
  • Linux中DMA如何处理memcpy

    我在程序中使用 memcpy 不幸的是 当我增加变量数量时 CPU 使用率会增加 就好像 memcpy 是通过使用 for 循环迭代来运行的 linux 中也有快速的 memcpy 函数吗 我应该使用补丁并编译内核吗 在某些架构中 CPU
  • Bootstrap 突然不适用于我的 React JS 项目

    突然 引导程序停止了我的项目的工作 我不知道为什么 这是我们的 package json name blankets version 0 1 0 private true dependencies amazon cognito identi
  • 数据卡和U盘或U盘的区别

    我有一张沃达丰数据卡 可以插入 USB 端口 我有 XP 和 Vista 操作系统 并且我正在使用WM DEVICECHANGEWindows 事件 了解 USB 插入和拔出 它对我来说工作得很好 但我无法区分数据卡插入和笔驱动器插入 是否
  • 为了迭代数组,我们应该使用 size_t 还是 ptrdiff_t?

    In this 安德烈 卡尔波夫 Andrey Karpov 的博客文章标题为 About size t and ptrdiff t 他举了一个例子 for ptrdiff t i 0 i lt n i a i 0 不过不知道对不对 好像应
  • 如何在 F# 中将字典“转换”为序列?

    如何将字典 转换 为序列以便可以按键值排序 let results new Dictionary results Add George 10 results Add Peter 5 results Add Jimmy 9 results A
  • Django 垃圾评论

    Django 的评论框架中的反垃圾邮件系统效果如何 你用过吗 它大约可以防止多少百分比的垃圾评论 您还采取其他措施来帮助防止使用 Django 评论框架的网站上出现垃圾评论吗 有一个 Python API 可以Askimet 这就是 Wor
  • 在C中递归创建并遍历二叉树

    我想创建一个二叉树并通过前序遍历来遍历它 并且我使用递归方法 这些代码可以编译但不能正确运行 我发现它可能无法完成CreateBitree 功能可以 但不知道问题出在哪里 include
  • 在 Android 上的 React-Native 中压缩 Base64 编码图像无法识别“数据”协议

    Issue 在 React Native 0 43 应用程序中 我们使用一个组件 该组件使用 SectionList 来渲染按天排序的照片 每个部分可以包含多个图像 照片是使用反应本机图像作物选择器库并上传到后端 或者在没有可用互联网连接的