如何使用 expo React Native 调整照片大小

2024-01-20

给定用户设备上照片的 uri(文件:// 和内容://),我如何调整照片大小?我正在运行一个托管的博览会应用程序,因此理想情况下我们能够在不分离的情况下执行此操作


这可以通过世博会来完成图像操纵器 https://docs.expo.io/versions/latest/sdk/imagemanipulator/ util:

import * as ImageManipulator from 'expo-image-manipulator'

const resizedPhoto = await ImageManipulator.manipulateAsync(
 photo.uri,
 [{ resize: { width: 300 } }], // resize to width of 300 and preserve aspect ratio 
 { compress: 0.7, format: 'jpeg' },
);

注意:我使用的是 expo@v31,最新版本 @v33 有不同的语法 - 请参考上面的链接


奖励:这是一种确保宽度或高度都不超过最大值的方法

// import { ImageManipulator } from 'expo'; // Original Post
import * as ImageManipulator from 'expo-image-manipulator' // Update based on documentation

enum PhotoDimensions {
  WIDTH = 'width',
  HEIGHT = 'height',
}

const maximalValuesPerDimension = { width: 1000, height: 1000 };
export const resizePhotoToMaxDimensionsAndCompressAsJPEG = async ({ photo }: { photo: { width: number, height: number, uri: string } }) => {
  // 1. define the maximal dimension and the allowed value for it
  const largestDimension = (photo.width > photo.height) ? PhotoDimensions.WIDTH : PhotoDimensions.HEIGHT;
  const initialValueOfLargestDimension = photo[largestDimension];
  const maximalAllowedValueOfLargestDimension = maximalValuesPerDimension[largestDimension];
  const targetValueOfLargestDimension = (initialValueOfLargestDimension > maximalAllowedValueOfLargestDimension) ? maximalAllowedValueOfLargestDimension : initialValueOfLargestDimension;

  // 2. resize the photo w/ that target value for that dimension (keeping the aspect ratio)
  const resizedPhoto = await ImageManipulator.manipulateAsync(
    photo.uri,
    [{ resize: { [largestDimension]: targetValueOfLargestDimension } }],
    { compress: 0.7, format: 'jpeg' },
  );

  // 3. return the resized photo
  return resizedPhoto;
};

以及一些测试覆盖率:

// import { ImageManipulator } from 'expo'; // Original Post
import * as ImageManipulator from 'expo-image-manipulator' // Update based on documentation
import { resizePhotoToMaxDimensionsAndCompressAsJPEG } from './resizePhotoToMaxDimensionsAndCompressAsJPEG';

jest.mock('expo', () => ({
  ImageManipulator: {
    manipulateAsync: jest.fn(),
  },
}));
const manipulateAsyncMock = ImageManipulator.manipulateAsync as jest.Mock;

describe('resizePhotoToMaxDimensionsAndCompressAsJPEG', () => {
  beforeEach(() => jest.clearAllMocks());
  it('should not change the dimensions of a photo if neither of its dimensions exceed the largest allowed value', async () => {
    const inputPhoto = { uri: '__TEST_URI__', width: 821, height: 128 };
    await resizePhotoToMaxDimensionsAndCompressAsJPEG({ photo: inputPhoto });
    expect(manipulateAsyncMock).toHaveBeenCalledTimes(1);
    expect(manipulateAsyncMock.mock.calls[0][1][0].resize).toEqual({
      width: 821,
    });
  });
  it('should resize the photo accurately if the width exceeds the largest allowed value', async () => {
    const inputPhoto = { uri: '__TEST_URI__', width: 12000, height: 128 };
    await resizePhotoToMaxDimensionsAndCompressAsJPEG({ photo: inputPhoto });
    expect(manipulateAsyncMock).toHaveBeenCalledTimes(1);
    expect(manipulateAsyncMock.mock.calls[0][1][0].resize).toEqual({
      width: 1000,
    });
  });
  it('should resize the photo accurately if the height exceeds the largest allowed value', async () => {
    const inputPhoto = { uri: '__TEST_URI__', width: 821, height: 12000 };
    await resizePhotoToMaxDimensionsAndCompressAsJPEG({ photo: inputPhoto });
    expect(manipulateAsyncMock).toHaveBeenCalledTimes(1);
    expect(manipulateAsyncMock.mock.calls[0][1][0].resize).toEqual({
      height: 1000,
    });
  });
  it('should compress the photo and convert it into a jpeg', async () => {
    const inputPhoto = { uri: '__TEST_URI__', width: 821, height: 12000 };
    await resizePhotoToMaxDimensionsAndCompressAsJPEG({ photo: inputPhoto });
    expect(manipulateAsyncMock).toHaveBeenCalledTimes(1);
    expect(manipulateAsyncMock.mock.calls[0][2]).toEqual({
      compress: expect.any(Number),
      format: 'jpeg',
    });
  });
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 expo React Native 调整照片大小 的相关文章

随机推荐

  • 如何 - 具有超时和取消功能的多个异步任务

    我想触发几个任务 同时为它们设置超时 这个想法是收集那些争分夺秒的任务的结果 并取消 甚至忽略 其他任务 我尝试使用扩展方法 WithCancellation 如所解释的here https stackoverflow com a 2568
  • Ember-数据递归 hasMany 关联

    有人使用 ember data 来建模数据树吗 我认为它会是这样的 Node DS Model extend children DS hasMany Node parent DS belongsTo Node 然而 我无法让这个工作正常进行
  • 如何制作一个更安全的 C++ 变体访问者,类似于 switch 语句?

    许多人使用 C 17 boost 变体的模式看起来与 switch 语句非常相似 例如 来自 cppreference com 的片段 http en cppreference com w cpp utility variant visit
  • 3 月 14 日不是 86400 秒长吗?

    在我的 Web 应用程序中 我让用户在简单的文本框中输入日期 该输入 当然是经过清理之后 通过 strtotime 运行 并向其中添加 86399 以使该时间戳成为所写入的当天的结束时间 11 59 59 这是出于截止日期的目的 因此 如果
  • 为什么 jQuery 模板 {{each}} 标签与 jQuery $.each 对 JavaScript 字符串数组的解释不同?

    强制性的jsFiddle 示例 http jsfiddle net patridge wuEyp 当我通过 jQuery 运行字符串数组时 each函数 我得到了我所期望的 each abc 123 def 456 function i v
  • 使用 RSpec 测试 searchkick

    我想创建用于在我的实践管理应用程序中搜索患者的功能规范 到目前为止 我已经在网上搜索并遵循了以下建议的解决方案 http bitsandbit es post 11295134047 unit testing with tire and e
  • 模板参数推导失败

    我正在尝试使用标签和enable if对模板参数实施约束 这是代码 include
  • iOS7 SKScene如何让精灵从屏幕边缘反弹?

    我正在开发一款球在 iPad 屏幕内弹跳的游戏 类似于乒乓球游戏 我看到 SKScene 的 SKPhysicsWorld 具有重力属性 并且还控制对象如何相互碰撞 有什么方法可以自动检测精灵的边缘是否与屏幕边缘发生碰撞 以便它可以反弹 或
  • WPF 应用程序转换为 ASP

    有没有办法把WPF应用程序变成ASP应用程序 或者它们是完全不相关的技术 XAML 格式让我想起了 HTML 似乎有一种方法 WPF 应用程序是 Windows 应用程序 而 ASP Net 应用程序是 Web 应用程序 这两个平台存在巨大
  • 无法使用 Namecheap 通过 Firebase 验证自定义域

    当我按照说明将 firebase 提供的文本记录 1 插入到我的 NameCheap 中后 不断弹出此错误消息 当前状态 抱歉 我们无法验证您的域名 该消息已经出现大约 5 天了 我捕获了 firebase 和 namecheap 设置的屏
  • H2数据库中auto_increment字段自增32?

    我有这个简单的表 仅供测试 create table table key int not null primary key auto increment name varchar 30 然后我执行以下请求 insert into table
  • 数据库恢复到特定状态以进行测试

    我们使用 Oracle 或 postgres 数据库和应用程序服务器来执行集成测试 为了将每个测试与另一个测试隔离 在每个测试之前都会删除并重新创建数据库模式 如您所见 这是一个耗时的过程 该应用程序使用 100 多个表 我们正在考虑编写自
  • C语言中的“静态”是什么意思?

    我见过这个词static在C代码中的不同地方使用 这是否像 C 中的静态函数 类 其中实现在对象之间共享 函数内的静态变量在调用之间保留其值 静态全局变量或函数仅在声明它的文件中 可见 如果你是新手 1 是一个比较陌生的话题 所以这里有一个
  • 为什么 document.addEventListener('load', function) 在 Greasemonkey 脚本中不起作用?

    它没有给出错误 我放了一个console log loaded userscript wifi autologin the console log有效 但 document addEventListener 的预期效果没有发生 在进行更多调
  • 如何使用 Visual Studio Code git Push 到不同的分支?

    我意识到在 VSCode 中提交后 有一个 推送 菜单选项可以将提交推送到默认分支 然而 我经常需要将它推送到不同的分支 有没有办法做到这一点或运行git push progress origin DEFAULT BRANCH OTHER
  • 如何找出哪个缺失的 DLL 导致我的 .NET 应用程序在启动时崩溃?

    当对第 3 方程序集的依赖项添加到典型的 NET 应用程序时 很容易忘记将它们添加到安装程序中 这个问题往往只有在应用程序安装后才会显现出来 并且以启动时崩溃的形式出现 几乎没有可用的有用信息 找出需要将哪些程序集添加到安装程序的最佳工具和
  • 头盔快递 ERR_BLOCKED_BY_RESPONSE.NotSameOrigin 200

    请我需要帮助 我检查了所有谷歌 但没有得到打开我的问题的真正答案 我想使用头盔来保护我的 Express 服务器 但是当我使用它时 我收到此错误 ERR BLOCKED BY RESPONSE NotSameOrigin 200 从数据库加
  • 使用 Matplotlib 创建 CSV 数据的实时绘图

    我正在尝试使用 Matplotlib 来可视化一些测量结果 测量通常持续约 24 小时 并将在 csv 中包含约 3 万行数据 我一直在努力让我的情节真正动画化 我可以执行代码 它将显示截至当前时间点的快照 但不会显示其他内容 当我尝试自动
  • 如何让 GridView 在添加项目时调整其高度

    我试图在 GridView 中显示一个带有复选框的动态增长的字符串列表 该复选框本身位于 TableLayout 中 我可以连续显示 复选框 字符串 当我让用户在 GridView 中动态添加新字符串时 就会出现问题 我创建了一个接收字符串
  • 如何使用 expo React Native 调整照片大小

    给定用户设备上照片的 uri 文件 和内容 我如何调整照片大小 我正在运行一个托管的博览会应用程序 因此理想情况下我们能够在不分离的情况下执行此操作 这可以通过世博会来完成图像操纵器 https docs expo io versions