给定用户设备上照片的 uri(file:// 和 content://),我如何调整照片大小?我正在运行一个托管的博览会应用程序,所以理想情况下我们可以在不分离的情况下做到这一点
Ula*_*ach 12
这可以通过 expo 的ImageManipulator util来完成:
const resizedPhoto = await ImageManipulator.manipulateAsync(
photo.uri,
[{ resize: { width: 300 } }], // resize to width of 300 and preserve aspect ratio
{ compress: 0.7, format: 'jpeg' },
);
Run Code Online (Sandbox Code Playgroud)
注意:我使用的是 expo@v31,最新版本的 @v33 有不同的语法 - 请参考上面的链接
奖励:这是一种确保宽度或高度都不超过最大值的方法
import { ImageManipulator } from 'expo';
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;
};
Run Code Online (Sandbox Code Playgroud)
以及它的一些测试覆盖率:
import { ImageManipulator } from 'expo';
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',
});
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4608 次 |
| 最近记录: |