在本教程中,我们将一起构建一个使用 React-Native 的图片裁剪工具。图片裁剪(Image Crop)工具对于裁剪图片来说非常重要。我们将实现让用户从存储中选择图片,对其进行裁剪,并将其保存到本地的功能。
预览图:!Screenshot-2023-09-22-204909
前置知识
- React Native 简介
- React Native 组件
- React Native 状态
- React Native 属性
- Expo CLI
- Node.js 和 npm (Node 包管理器)
项目设置
步骤 1: 创建项目
npx create-expo-app image_crop
步骤 2: 导航到项目目录
cd image_crop
步骤 3: 安装所需的依赖包。
npx expo install expo-file-system expo-image-picker
- expo-file-system: 用于保存文件。
- expo-image-picker: 用于选择和裁剪图片。
项目结构:
package.json 包含了依赖项及其对应的版本。
{
"name": "image_crop",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"expo": "~49.0.11",
"expo-file-system": "~15.4.4",
"expo-image-picker": "~14.3.2",
"expo-status-bar": "~1.6.0",
"react": "18.2.0",
"react-native": "0.72.4"
},
"devDependencies": {
"@babel/core": "^7.20.0"
},
"private": true
}
实现思路
- 应用程序将包含三个按钮:选择图片、重置图片和保存图片。
- 点击“选择图片”按钮时,将打开图片选择器。我们需要选择一张图片。
- 随后会打开裁剪窗口,我们在其中进行裁剪操作。
- 裁剪完成后,图片将显示在屏幕上。
- 如果满意,请按“保存”按钮。
- 完成后,我们可以重置应用程序。
示例: 下面的示例展示了如何使用 React-Native 创建图片裁剪工具。
JavaScript
“
// App.js 文件
import {
Button,
StyleSheet,
Text,
View,
Image,
TextInput,
} from "react-native";
import * as ImagePicker from "expo-image-picker";
import * as FileSystem from "expo-file-system";
import { useRef, useState } from "react";
export default function App() {
const [fileUri, setFileUri] = useState("");
const [fileType, setFileType] = useState("");
const [heightAspect, setHeightAspect] = useState("3");
const [widthAspect, setWidthAspect] = useState("4");
const handlePickFile = async () => {
if (heightAspect == "0" || widthAspect == "0") {
const res =
await ImagePicker.launchImageLibraryAsync({
mediaTypes:
ImagePicker.MediaTypeOptions.Images,
quality: 1,
allowsEditing: true,
allowsMultipleSelection: false,
});
if (res.canceled) return;
setFileUri(res.assets[0].uri);
setFileType(res.assets[0].type);
} else {
const res =
await ImagePicker.launchImageLibraryAsync({
mediaTypes:
ImagePicker.MediaTypeOptions.Images,
quality: 1,
aspect: [
parseInt(widthAspect),
parseInt(heightAspect),
],
allowsEditing: true,
allowsMultipleSelection: false,
});
if (res.canceled) return;
setFileUri(res.assets[0].uri);
setFileType(res.assets[0].type);
}
};
const saveFile = async (uri, mimetype) => {
let fileName = Date.now() + ".jpg";
const permissions =
await
FileSystem.StorageAccessFramework
.requestDirectoryPermissionsAsync();
if (permissions.granted) {
const base64 =
await FileSystem.readAsStringAsync(uri, {
encoding:
FileSystem.EncodingType.Base64,
});
await FileSystem.StorageAccessFramework.createFileAsync(
permissions.directoryUri,
fileName,
mimetype
)
.then(async (uri) => {
await FileSystem.writeAsStringAsync(
uri,
base64,
{
encoding: