reactjs - 如何向图像添加附加信息?
问题描述
我是 React 和 Ionic 的新手,并在这个 ionic 教程的帮助下构建了 Ionic React 照片库应用程序。现在我还想在图像显示时添加其他信息,如日期、位置、一些输入字段……但我只是不知道如何。
这是教程中的代码:
import { useState, useEffect } from "react";
import { isPlatform } from '@ionic/react';
import { Camera, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
import { Filesystem, Directory } from '@capacitor/filesystem'
import { Storage } from '@capacitor/storage'
import { Capacitor } from '@capacitor/core';
import internal from "assert";
import { defaultMaxListeners } from "stream";
const PHOTO_STORAGE = "photos";
export function usePhotoGallery() {
const [photos, setPhotos] = useState<UserPhoto[]>([]);
useEffect(() => {
const loadSaved = async () => {
const {value} = await Storage.get({key: PHOTO_STORAGE });
const photosInStorage = (value ? JSON.parse(value) : []) as UserPhoto[];
// If running on the web...
if (!isPlatform('hybrid')) {
for (let photo of photosInStorage) {
const file = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data
});
// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${file.data}`;
}
}
setPhotos(photosInStorage);
};
loadSaved();
}, []);
const takePhoto = async () => {
const cameraPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100
});
const fileName = new Date().getTime() + '.jpeg';
const savedFileImage = await savePicture(cameraPhoto, fileName);
const newPhotos = [savedFileImage, ...photos];
setPhotos(newPhotos);
Storage.set({key: PHOTO_STORAGE,value: JSON.stringify(newPhotos)});
};
const savePicture = async (photo: Photo, fileName: string): Promise<UserPhoto> => {
let base64Data: string;
// "hybrid" will detect Cordova or Capacitor;
if (isPlatform('hybrid')) {
const file = await Filesystem.readFile({
path: photo.path!
});
base64Data = file.data;
} else {
base64Data = await base64FromPath(photo.webPath!);
}
const savedFile = await Filesystem.writeFile({
path: fileName,
data: base64Data,
directory: Directory.Data
});
if (isPlatform('hybrid')) {
// Display the new image by rewriting the 'file://' path to HTTP
// Details: https://ionicframework.com/docs/building/webview#file-protocol
return {
filepath: savedFile.uri,
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
};
}
else {
// Use webPath to display the new image instead of base64 since it's
// already loaded into memory
return {
filepath: fileName,
webviewPath: photo.webPath
};
}
};
const deletePhoto = async (photo: UserPhoto) => {
// Remove this photo from the Photos reference data array
const newPhotos = photos.filter(p => p.filepath !== photo.filepath);
// Update photos array cache by overwriting the existing photo array
Storage.set({key: PHOTO_STORAGE, value: JSON.stringify(newPhotos) });
// delete photo file from filesystem
const filename = photo.filepath.substr(photo.filepath.lastIndexOf('/') + 1);
await Filesystem.deleteFile({
path: filename,
directory: Directory.Data
});
setPhotos(newPhotos);
};
return {
deletePhoto,
photos,
takePhoto
};
}
export interface UserPhoto {
filepath: string;
webviewPath?: string;
}
export async function base64FromPath(path: string): Promise<string> {
const response = await fetch(path);
const blob = await response.blob();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onerror = reject;
reader.onload = () => {
if (typeof reader.result === 'string') {
resolve(reader.result);
} else {
reject('method did not return a string')
}
};
reader.readAsDataURL(blob);
});
}
我设法使用地理定位插件获取日期和位置,但我不知道如何将其绑定到拍摄的照片......
我假设我必须通过function base64FromPath()
网络和const file = await Filesystem.readFile()
移动设备添加所需的数据?然后显示该export interface UserPhoto
部分,但我完全迷路了,不知道从哪里开始。欢迎任何建议!
解决方案
我发现一种方法可能不是最漂亮或最直接的,但它似乎对我有用。
在takePhoto
函数中,我获取位置和日期,然后通过savePicture
函数传递它。在savePicture
我返回的函数内部latitude
,longitude
因此time
可以通过对象loadSaved
内的函数访问它photo
。里面interface UserPhoto
的3个变量也需要声明。
如果有人想提出建议,这是更新的代码:
import { useState, useEffect } from "react";
import { isPlatform } from '@ionic/react';
import { Geolocation, Geoposition } from '@ionic-native/geolocation';
import { Camera, CameraResultType, CameraSource, CameraDirection, Photo } from '@capacitor/camera';
import { Filesystem, Directory } from '@capacitor/filesystem'
import { Storage } from '@capacitor/storage'
import { Capacitor } from '@capacitor/core';
import { stringify } from "querystring";
const PHOTO_STORAGE = "photos";
export function usePhotoGallery() {
const [photos, setPhotos] = useState<UserPhoto[]>([]);
useEffect(() => {
const loadSaved = async () => {
const {value} = await Storage.get({key: PHOTO_STORAGE });
const photosInStorage = (value ? JSON.parse(value) : []) as UserPhoto[];
// If running on the web...
if (!isPlatform('hybrid')) {
for (let photo of photosInStorage) {
const file = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data
});
// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${file.data}`;
}
}
setPhotos(photosInStorage);
};
loadSaved();
}, []);
const takePhoto = async () => {
const position = await Geolocation.getCurrentPosition();
const latitude = position.coords.latitude
const longitude = position.coords.longitude
const time = new Date(position.timestamp).toLocaleString()
const cameraPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
direction: CameraDirection.Rear,
quality: 100
});
const fileName = new Date().getTime() + '.jpeg';
const savedFileImage = await savePicture(cameraPhoto, fileName, latitude, longitude, time);
const newPhotos = [savedFileImage, ...photos];
setPhotos(newPhotos);
Storage.set({key: PHOTO_STORAGE,value: JSON.stringify(newPhotos)});
};
const savePicture = async (photo: Photo, fileName: string, latitude: number, longitude: number, time:string): Promise<UserPhoto> => {
let base64Data: string;
// "hybrid" will detect Cordova or Capacitor;
if (isPlatform('hybrid')) {
const file = await Filesystem.readFile({
path: photo.path!
});
base64Data = file.data;
} else {
base64Data = await base64FromPath(photo.webPath!);
}
console.log("base64Data")
console.log(base64Data)
let savedFile = await Filesystem.writeFile({
path: fileName,
data: base64Data,
directory: Directory.Data
});
console.log(savedFile)
if (isPlatform('hybrid')) {
// Display the new image by rewriting the 'file://' path to HTTP
// Details: https://ionicframework.com/docs/building/webview#file-protocol
return {
filepath: savedFile.uri,
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
latitude: latitude,
longitude: longitude,
time: time
};
}
else {
// Use webPath to display the new image instead of base64 since it's
// already loaded into memory
return {
filepath: fileName,
webviewPath: photo.webPath,
latitude: latitude,
longitude: longitude,
time: time
};
}
};
const deletePhoto = async (photo: UserPhoto) => {
// Remove this photo from the Photos reference data array
const newPhotos = photos.filter(p => p.filepath !== photo.filepath);
// Update photos array cache by overwriting the existing photo array
Storage.set({key: PHOTO_STORAGE, value: JSON.stringify(newPhotos) });
// delete photo file from filesystem
const filename = photo.filepath.substr(photo.filepath.lastIndexOf('/') + 1);
await Filesystem.deleteFile({
path: filename,
directory: Directory.Data
});
setPhotos(newPhotos);
};
return {
deletePhoto,
photos,
takePhoto
};
}
export interface UserPhoto {
filepath: string;
webviewPath?: string;
latitude: number;
longitude: number;
time: string;
}
export async function base64FromPath(path: string): Promise<string> {
const response = await fetch(path);
const blob = await response.blob();
//const blob = new Blob(neu)
return new Promise((resolve, reject) => {
const reader = new FileReader();
console.log(reader)
reader.onerror = reject;
reader.onload = () => {
if (typeof reader.result === 'string') {
resolve(reader.result);
} else {
reject('method did not return a string')
}
};
reader.readAsDataURL(blob);
});
}
要访问是在我的 UI.tsx 我使用例如{photo.latitude}
显示采取的纬度值
推荐阅读
- javascript - 如何在函数 javascript 中使用自定义 JSON 模式?
- botframework - 自适应卡片中的 Action.OpenUrl,打开 URl 的确认
- javascript - 如何在 c# .net 中读取 formdata 和 json 数据
- yocto - Yocto - 为 WIC 创建对 cpio.gz 映像的依赖项
- elasticsearch - 单个字符的phrase_prefix es搜索问题
- reactjs - React - 得到错误导出多个组件用作 NPM 包
- javascript - 将 HTML 作为字符串加载时未获取 href 的值
- python - 从构造函数或文字创建集合时 Python 中的不同行为
- django - Django REST 测试 - 如何指定引用 setUp 函数中创建的模型实例的 pk 参数
- routes - 以前的路线显示在 Sapper 的当前路线中