React Native 全栈开发实战班 -原生功能集成之相机与图片

在移动应用中,相机功能图片选择 是非常常见的需求,用户可以通过相机拍照或从相册中选择图片。React Native 提供了多种方式来实现相机和图片选择功能,包括使用第三方库(如 react-native-image-picker)和调用原生模块。本章节将详细介绍如何使用 react-native-image-picker 库来实现相机和图片选择功能,包括基本用法、图片处理、权限管理以及自定义相机界面。


2.1 相机与图片选择概述

在移动应用中,相机和图片选择功能主要用于以下场景:

  • 用户头像设置: 用户可以通过相机拍照或从相册中选择图片作为头像。
  • 图片上传: 用户可以上传图片到服务器,如发布动态、分享照片等。
  • 扫描二维码: 通过相机扫描二维码或条形码。
  • 图片编辑: 用户可以对图片进行编辑,如裁剪、旋转、添加滤镜等。

React Native 提供了多种方式来实现相机和图片选择功能:

  1. 第三方库:react-native-image-picker, react-native-camera, react-native-image-crop-picker 等,提供了封装好的 API,可以快速实现相机和图片选择功能。
  2. 原生模块: 可以通过原生代码实现自定义相机和图片选择功能,适用于需要高度定制化的场景。

本章节将重点介绍如何使用 react-native-image-picker 库来实现相机和图片选择功能。


2.2 使用 react-native-image-picker

react-native-image-picker 是一个流行的第三方库,用于实现相机和图片选择功能,支持 iOS 和 Android 平台。

2.2.1 安装 react-native-image-picker
npm install react-native-image-picker

链接原生依赖(React Native 0.60 及以上版本自动链接):

cd ios
pod install
cd ..
2.2.2 配置权限

iOS:

Info.plist 文件中添加相机和相册权限说明。

<key>NSCameraUsageDescription</key>
<string>需要访问相机以拍摄照片</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择照片</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要保存照片到相册</string>

Android:

AndroidManifest.xml 文件中添加相机和存储权限。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

注意: 对于 Android 6.0 及以上版本,还需要在代码中动态请求权限。

2.2.3 基本用法

请求相机或图片选择:

import { launchCamera, launchImageLibrary } from 'react-native-image-picker';const handleChooseImage = () => {const options = {mediaType: 'photo',cameraType: 'back',maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchImageLibrary(options, (response) => {if (response.didCancel) {console.log('用户取消选择图片');} else if (response.errorCode) {console.error('图片选择错误:', response.errorMessage);} else {const asset = response.assets[0];console.log('选择的图片:', asset);// 处理选择的图片}});
};const handleTakePhoto = () => {const options = {mediaType: 'photo',cameraType: 'back',saveToPhotos: true,maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchCamera(options, (response) => {if (response.didCancel) {console.log('用户取消拍照');} else if (response.errorCode) {console.error('拍照错误:', response.errorMessage);} else {const asset = response.assets[0];console.log('拍摄的图片:', asset);// 处理拍摄的图片}});
};

示例:

import React from 'react';
import { View, Button, Image, StyleSheet, Alert } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';const CameraExample = () => {const handleTakePhoto = () => {const options = {mediaType: 'photo',cameraType: 'back',saveToPhotos: true,maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchCamera(options, (response) => {if (response.didCancel) {console.log('用户取消拍照');} else if (response.errorCode) {Alert.alert('拍照错误', response.errorMessage);} else {const asset = response.assets[0];console.log('拍摄的图片:', asset);// 处理拍摄的图片}});};const handleChooseImage = () => {const options = {mediaType: 'photo',maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchImageLibrary(options, (response) => {if (response.didCancel) {console.log('用户取消选择图片');} else if (response.errorCode) {Alert.alert('图片选择错误', response.errorMessage);} else {const asset = response.assets[0];console.log('选择的图片:', asset);// 处理选择的图片}});};return (<View style={styles.container}><Button title="拍照" onPress={handleTakePhoto} /><Button title="选择图片" onPress={handleChooseImage} /></View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},
});export default CameraExample;

解释:

  • launchCamera 方法: 打开相机进行拍照。
  • launchImageLibrary 方法: 打开相册选择图片。
  • options 参数: 配置相机或图片选择选项,如媒体类型、图片尺寸、质量等。
  • 回调函数: 处理用户取消、错误或选择结果。
2.2.4 处理选择的图片

react-native-image-picker 返回的图片信息包含图片的 URI、宽度、高度、大小等信息。可以使用 react-native-fast-image 或其他图片加载库来显示图片,并根据需要进行后续处理,如上传到服务器或保存到本地。

2.2.4.1 显示选择的图片

以下是如何使用 react-native-fast-image 显示用户选择的图片:

import React from 'react';
import { View, Button, StyleSheet, Alert } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import FastImage from 'react-native-fast-image';const CameraExample = () => {const [image, setImage] = React.useState(null);const handleTakePhoto = () => {const options = {mediaType: 'photo',cameraType: 'back',saveToPhotos: true,maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchCamera(options, (response) => {if (response.didCancel) {console.log('用户取消拍照');} else if (response.errorCode) {Alert.alert('拍照错误', response.errorMessage);} else {const asset = response.assets[0];console.log('拍摄的图片:', asset);setImage(asset);}});};const handleChooseImage = () => {const options = {mediaType: 'photo',maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchImageLibrary(options, (response) => {if (response.didCancel) {console.log('用户取消选择图片');} else if (response.errorCode) {Alert.alert('图片选择错误', response.errorMessage);} else {const asset = response.assets[0];console.log('选择的图片:', asset);setImage(asset);}});};return (<View style={styles.container}><View style={styles.buttonContainer}><Button title="拍照" onPress={handleTakePhoto} /><Button title="选择图片" onPress={handleChooseImage} /></View>{image && (<View style={styles.imageContainer}><FastImagesource={{ uri: image.uri }}style={styles.image}resizeMode={FastImage.resizeMode.cover}/></View>)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},buttonContainer: {flexDirection: 'row',justifyContent: 'space-around',width: '100%',marginBottom: 20,},imageContainer: {width: 300,height: 300,borderRadius: 10,overflow: 'hidden',marginBottom: 20,},image: {width: '100%',height: '100%',},
});export default CameraExample;

解释:

  • setImage(asset): 将选择的图片信息存储在组件状态中。
  • FastImage: 使用 react-native-fast-image 显示图片,asset.uri 是图片的 URI。
  • resizeMode: 设置图片的缩放模式,如 cover, contain, stretch 等。
2.2.4.2 图片上传

用户选择或拍摄图片后,通常需要将图片上传到服务器。以下是如何实现图片上传的示例:

import React from 'react';
import { View, Button, StyleSheet, Alert } from 'react-native';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import axios from 'axios';const CameraExample = () => {const [image, setImage] = React.useState(null);const handleTakePhoto = () => {const options = {mediaType: 'photo',cameraType: 'back',saveToPhotos: true,maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchCamera(options, (response) => {if (response.didCancel) {console.log('用户取消拍照');} else if (response.errorCode) {Alert.alert('拍照错误', response.errorMessage);} else {const asset = response.assets[0];setImage(asset);uploadImage(asset);}});};const handleChooseImage = () => {const options = {mediaType: 'photo',maxWidth: 1080,maxHeight: 1080,quality: 0.8,};launchImageLibrary(options, (response) => {if (response.didCancel) {console.log('用户取消选择图片');} else if (response.errorCode) {Alert.alert('图片选择错误', response.errorMessage);} else {const asset = response.assets[0];setImage(asset);uploadImage(asset);}});};const uploadImage = async (asset) => {const formData = new FormData();formData.append('file', {uri: asset.uri,type: asset.type,name: asset.fileName || 'image.jpg',});try {const response = await axios.post('https://example.com/upload', formData, {headers: {'Content-Type': 'multipart/form-data',},});Alert.alert('上传成功', `图片上传成功,图片ID: ${response.data.id}`);} catch (error) {Alert.alert('上传失败', '图片上传失败,请稍后重试');}};return (<View style={styles.container}><View style={styles.buttonContainer}><Button title="拍照" onPress={handleTakePhoto} /><Button title="选择图片" onPress={handleChooseImage} /></View>{image && (<View style={styles.imageContainer}><FastImagesource={{ uri: image.uri }}style={styles.image}resizeMode={FastImage.resizeMode.cover}/></View>)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},buttonContainer: {flexDirection: 'row',justifyContent: 'space-around',width: '100%',marginBottom: 20,},imageContainer: {width: 300,height: 300,borderRadius: 10,overflow: 'hidden',marginBottom: 20,},image: {width: '100%',height: '100%',},
});export default CameraExample;

解释:

  • uploadImage 函数: 使用 axios 发送 POST 请求,将图片上传到服务器。
  • FormData: 用于构建 multipart/form-data 请求体。
  • asset.uri: 图片的 URI,用于上传。
  • asset.type: 图片的 MIME 类型。
  • asset.fileName: 图片的文件名,如果未提供,则使用默认名称。
2.2.4.3 图片保存到相册

用户拍摄或选择的图片可以保存到相册中。

示例:

import { writeToFile, copyFile, saveToLibrary } from 'react-native-image-picker';const saveImageToAlbum = async (asset) => {try {const result = await saveToLibrary(asset.uri);Alert.alert('保存成功', '图片已保存到相册');} catch (error) {Alert.alert('保存失败', '图片保存到相册失败');}
};

作者简介

前腾讯电子签的前端负责人,现 whentimes tech CTO,专注于前端技术的大咖一枚!一路走来,从小屏到大屏,从 Web 到移动,什么前端难题都见过。热衷于用技术打磨产品,带领团队把复杂的事情做到极简,体验做到极致。喜欢探索新技术,也爱分享一些实战经验,帮助大家少走弯路!

温馨提示:可搜老码小张公号联系导师

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/473724.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无线迷踪:陈欣的网络之旅

第一章 陈欣是一名资深的网络工程师&#xff0c;工作在一家领先的科技公司。她的生活平静而有序&#xff0c;直到有一天&#xff0c;公司的无线网络突然出现了严重的问题。员工们的设备频繁断开连接&#xff0c;无法正常使用。这个问题不仅影响了工作效率&#xff0c;还引起了…

ssm129办公用品管理系统开发与设计+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;办公用品管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本办公用品管理系统…

OMV7 树莓派 tf卡安装

​ 升级7之后&#xff0c;问题多多&#xff0c;不是docker不行了&#xff0c;就是代理不好使 今天又重装了一遍&#xff0c;用官方的链接&#xff0c;重新再折腾一遍…… 使用raspberry pi imager安装最新版lite OS。 注意是无桌面 Lite版 配置好树莓派初始化设置&#xff0…

【数据结构与算法】查找

文章目录 一.查找二.线性结构的查找2.1顺序查找2.2折半查找2.3分块查找 三.树型结构的查找3.1二叉排序树1.定义2.二叉排序树的常见操作3.性能分析 3.2平衡二叉树1.定义2.平衡二叉树的常见操作3.性能分析 3.3B树1.定义2.B树的相关操作 3.4B树1.定义2.B树与B树的比较 四.散列表1.…

SpringCloud篇(服务保护 - Sentinel)

目录 一、雪崩问题及解决方案 1. 雪崩问题 2. 解决方案 方案一&#xff1a;超时处理 方案二&#xff1a;仓壁模式 方案三&#xff1a;断路器模式 方案四&#xff1a;限流 3. 总结 二、服务保护技术对比 三、Sentinel介绍与安装 1. 初识Sentinel 2. Sentinel 优势 3…

C语言项⽬实践-贪吃蛇

目录 1.项目要点 2.窗口设置 2.1mode命令 2.2title命令 2.3system函数 2.Win32 API 2.1 COORD 2.2 GetStdHandle 2.3 CONSOLE_CURSOR_INFO 2.4 GetConsoleCursorInfo 2.5 SetConsoleCursorInfo 2.5 SetConsoleCursorPosition 2.7 GetAsyncKeyState 3.贪吃蛇游戏设…

笔记|M芯片MAC (arm64) docker上使用 export / import / commit 构建amd64镜像

很简单的起因&#xff0c;我的东西最终需要跑在amd64上&#xff0c;但是因为mac的架构师arm64&#xff0c;所以直接构建好的代码是没办法跨平台运行的。直接在arm64上pull下来的docker镜像也都是arm64架构。 检查镜像架构&#xff1a; docker inspect 8135f475e221 | grep Arc…

热点更新场景,OceanBase如何实现性能优化

案例背景 这个案例来自一个保险行业的客户&#xff1a;他们的核心系统底层采用了OceanBase数据库作为存储解决方案&#xff0c;然而&#xff0c;在系统上线运行后&#xff0c;出现了一个异常情况&#xff0c;执行简单的主键更新语句时SQL执行时间出现了显著的波动。为了迅速定…

MYSQL_深入理解自连接_图书借阅情况(2/2)

光说不练假把式。这就开门见山——引出我们的自连接实例&#xff1a;图书借阅情况。 题目&#xff1a; 这是一道笔试题目&#xff1a;如果限时5min内完成&#xff0c;同学们可以测试一下自己对于SQL语句的熟练程度。 题目分析&#xff1a; 可以看见这个数据库有三个实体&…

uniapp luch-request 使用教程+响应对象创建

1. 介绍 luch-request 是一个基于 Promise 开发的 uni-app 跨平台、项目级别的请求库。它具有更小的体积、易用的 API 和方便简单的自定义能力。luch-request 支持请求和响应拦截、全局挂载、多个全局配置实例、自定义验证器、文件上传/下载、任务操作、自定义参数以及多拦截器…

MySQL技巧之跨服务器数据查询:基础篇-A数据库与B数据库查询合并--封装到存储过程中

MySQL技巧之跨服务器数据查询&#xff1a;基础篇-A数据库与B数据库查询合并–封装到存储过程中 我们的最终目的是什么&#xff1f;当然的自动执行这些合并操作&#xff01; 上一篇 MySQL技巧之跨服务器数据查询&#xff1a;基础篇-A数据库与B数据库查询合并 我们已经知道怎么合…

解决 IDEA 修改代码重启不生效的问题

前言 在使用 IntelliJ IDEA 进行 Java 项目开发时&#xff0c;有时会遇到一个令人头疼的问题&#xff1a;修改了代码后&#xff0c;重启服务却发现更改没有生效。通常情况下&#xff0c;解决这个问题需要通过 Maven 的 clean 和 compile 命令来强制重新编译&#xff0c;但这显…

【Mysql】Mysql函数(上)

1、概述 在Mysql中&#xff0c;为了提高代码重用性和隐藏实现细节&#xff0c;Mysql提供了很多函数。函数可以理解为封装好的模块代码。 2、分类 在Mysql中&#xff0c;函数非常多&#xff0c;主要可以分为以下几类&#xff1a; &#xff08;1&#xff09;聚合函数 &#xf…

帧中继原理与配置

Frame Relay 帧中继 LMI(Local Management Interface)本地管理接口 LMI协议通过状态查询报文和状态应答报文维护帧中继的链路状态和PVC状态. DLCI(Data Link Connection Identifier)数据链路连接标识符 DLCI只在本地接口和与之直接相连的对端接口有效,不具有全局有效性,记载帧…

Spring Boot 接口防重复提交解决方案

文章目录 前言使用Token机制实现步骤1.生成Token2.传递Token3.验证Token 使用Redis实现步骤1.引入Redis依赖2.生成Token3.传递Token4.验证Token 使用Spring AOP实现步骤1.定义注解2.创建切面3.使用注解 总结 前言 在Web开发中&#xff0c;防止用户重复提交表单是一个常见的需求…

【QT】解决生成的exe文件出现“无法定位程序入口”或“找不到xxx.dll”的问题

【QT】解决生成的exe文件出现“无法定位程序入口”或“找不到xxx.dll”的问题 零、问题 使用QT编译好项目后&#xff0c;想直接在文件资源管理器中运行exe程序或想分享出去给别人使用发现出现如下问题&#xff1a; 系统错误&#xff1a;找不到xxx.dll。 无法找到入口&#x…

Tomcat启动过程中cmd窗口(控制台)中文乱码的问题

目录 一、问题产生 二、问题分析 三、解决方法(2种) 一、问题产生 在服务器上使用新的Tomcat9(绿色版ZIP),打开一个cmd窗口后,将路径定位到“tomcat\bin\”目录,运行“startup.bat”。程序会自动打开一个新窗口,这个是Java程序的运行窗口,但是里面的中文全是乱码,如…

【MySQL】MySQL数据库入门:构建你的数据基石

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;MySQL初阶探索&#xff1a;构建数据库基础 欢迎大家点赞收藏评论&#x1f60a; 目录 &#x1f985;数据库基础&#x1f400;什么是数据库&#x1f40f;主流数据库&#x1f986;MySQL数据库的基本…

如何使用正则表达式验证域名

下面是一篇关于如何使用正则表达式验证域名的教程。 如何使用正则表达式验证域名 简介 域名是互联网上网站的地址&#xff0c;每个域名由多个标签&#xff08;label&#xff09;组成&#xff0c;标签之间用点 . 分隔。域名规则有很多细节&#xff0c;但基本要求是&#xff1a…

Python中的正则表达式教程

一、 正则表达式基础 1。1。概念介绍 正则表达式是用于处理字符串的强大工具,它并不是Python的一部分。 其他编程语言中也有正则表达式的概念,区别只在于不同的编程语言实现支持的语法数量不同。 它拥有自己独特的语法以及一个独立的处理引擎&#xff0c;在提供了正则表达式…