Anonymous
Я не могу получить метаданные GPS изображения на Android React Native, большинство показывают 0 и некоторые 0/1, 0/1, 0/
Сообщение
Anonymous » 31 мар 2025, 17:05
Я не могу получить метаданные GPS изображения на Android React Native, я проверил многие библиотеки, большинство показывают 0/1, 0/1, 0/1, но они не являются правильными координатами GPS.
Код: Выделить всё
import React, { useEffect, useState } from "react";
import { Text, View, TouchableOpacity, Image, Modal } from "react-native";
import ImagePicker from "react-native-image-crop-picker";
import { requestPermission } from "../../utils/nativeFunctions";
import { getStyles } from "./styles";
import { useTheme } from "@trizyapp/sdk";
import { CameraIcon, GaleriaIcon } from "../../assets/icons";
import { parse } from "date-fns";
import { writeAsync, readAsync, ExifTags } from "@lodev09/react-native-exify";
import { PermissionsAndroid } from "react-native";
import { convertCoordinates } from "../../utils/convertCoordenadas";
interface Props {
resource: string;
setResource: (resource: any) => void;
onlyModal?: boolean;
openModal?: boolean;
handleClose?: () => void;
setOpenModal?: (openModal: boolean) => void;
}
const CustomImagePicker = ({
resource,
setResource,
onlyModal = false,
openModal = false,
handleClose,
}: Props) => {
const styles = getStyles({});
const { color: colors, spaces } = useTheme();
const [openButtonsModal, setOpenButtonsModal] = useState(false);
const handlePress = () => {
setOpenButtonsModal(true);
};
useEffect(() => {
if (openModal && !openButtonsModal) {
setOpenButtonsModal(true);
}
}, [openModal]);
const handleModalClose = () => {
setOpenButtonsModal(false);
handleClose && handleClose();
};
const extractMetadata = (exifData: any) => {
if (!exifData) {
return {
data_evidencia: null,
latitude: null,
longitude: null,
};
}
let latitude = null;
let longitude = null;
if (exifData.GPS && exifData.GPS.Latitude && exifData.GPS.Longitude) {
latitude = exifData.GPS.Latitude;
longitude = exifData.GPS.Longitude;
} else if (
exifData.GPSLatitude !== undefined &&
exifData.GPSLongitude !== undefined
) {
latitude = exifData.GPSLatitude;
longitude = exifData.GPSLongitude;
} else if (
exifData.latitude !== undefined &&
exifData.longitude !== undefined
) {
latitude = exifData.latitude;
longitude = exifData.longitude;
}
let dataEvidencia = null;
const dateFields = [
"DateTime",
"DateTimeOriginal",
"DateTimeDigitized",
"creationDate",
];
for (const field of dateFields) {
if (exifData[field]) {
try {
let dateString = exifData[field];
if (dateString.includes(":")) {
dateString = dateString.replace(
/^(\d{4}):(\d{2}):(\d{2})/,
"$1-$2-$3"
);
dataEvidencia = parse(
dateString,
"yyyy-MM-dd HH:mm:ss",
new Date()
);
} else {
dataEvidencia = new Date(dateString);
}
if (!isNaN(dataEvidencia.getTime())) {
break;
}
} catch (e) {
console.log(`Error parsing date from ${field}:`, e);
}
}
}
return {
data_evidencia: dataEvidencia,
...convertCoordinates(longitude, latitude),
};
};
const selectFile = async (tipo: string) => {
try {
let permissao = false;
if (tipo === "camera") {
permissao = await requestPermission({ tipo: "camera" });
permissao = await requestPermission({ tipo: "localizacao_midia" });
} else {
permissao = await requestPermission({ tipo: "galeria" });
permissao = await requestPermission({
tipo: "ler_armazenamento_externo",
});
permissao = await requestPermission({ tipo: "localizacao_midia" });
console.log("Permissão de localizacao_midia", permissao);
}
console.log(
"Status real das permissões:",
await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
),
await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.ACCESS_MEDIA_LOCATION
)
);
if (permissao) {
const options = {
width: 1000,
height: 1000,
cropping: false,
includeExif: true,
includeExtra: true,
compressImageQuality: 0.8,
forceJpg: true,
};
let result = null;
if (tipo === "camera") {
permissao = await requestPermission({ tipo: "localizacao" });
console.log("Permissão de localização:", permissao);
result = await ImagePicker.openCamera({
...options,
useFrontCamera: false,
});
} else {
result = await ImagePicker.openPicker(options);
}
if (result) {
const imagePath = result.path;
const tags = await readAsync(imagePath);
console.log(tags);
// const tags = await readAsync(imagePath);
console.log(
"Raw image result:",
JSON.stringify(
{
path: result.path,
width: result.width,
height: result.height,
mime: result.mime,
size: result.size,
exif: result.exif
? // Criar um novo objeto com pares chave-valor
Object.fromEntries(
Object.entries(result.exif).map(([key, value]) => [
key,
// Converter valores complexos para formato legível
value instanceof Object && !(value instanceof Array)
? value.toString()
: value,
])
)
: null,
},
null,
2
) // Formatação com indentação
);
const metaData = extractMetadata(result.exif);
setResource({ image: result.path, metaData });
}
handleModalClose();
}
} catch (error) {
Promise.reject(error);
}
};
const renderModal = () => {
return (
handleModalClose()}
>
selectFile("camera")}>
Câmera
selectFile("gallery")}>
Galeria
);
};
return onlyModal ? (
renderModal()
) : (
{resource && resource.length > 0 ? (
) : (
Insira seu arquivo aqui
(.jpeg, .jpg ou png)
)}
{renderModal()}
);
};
export default CustomImagePicker;
< /code>
< /code>
import React, { useState } from "react";
import { View, Modal, TouchableOpacity } from "react-native";
import { getStyles } from "./styles";
import { useTheme, Button, CloseIcon, Text, SizedBox } from "@trizyapp/sdk";
import { ImagePicker, TextInput } from "../../../../components";
import { DeleteIcon, RefreshIcon, SendIcon } from "../../../../assets/icons";
interface Evidencia {
imagem_url: string;
legenda: string;
data_evidencia: string | null;
latitude?: number;
longitude?: number;
}
interface Props {
open: boolean;
handleClose: () => void;
handleRemove: () => void;
evidencias?: Evidencia[];
setEvidencias: (evidencias: Evidencia[]) => void;
}
const ModalEvidencia = ({
open,
handleClose,
handleRemove,
evidencias = [],
setEvidencias,
}: Props) => {
const styles = getStyles({});
const { color: colors, spaces } = useTheme();
const [openPicker, setOpenPicker] = useState(false);
const [files, setFiles] = useState(
evidencias?.length > 0
? evidencias
: [{ imagem_url: "", legenda: "", data_evidencia: null }]
);
const toggleModalPicker = () => setOpenPicker((prev) => !prev);
const updateFile = (index: number, updatedData: Partial) => {
console.log(`Atualizando arquivo no índice ${index}:`, updatedData);
setFiles((prevFiles) =>
prevFiles.map((file, i) =>
i === index ? { ...file, ...updatedData } : file
)
);
};
return (
{files.map((file, index) => (
setOpenPicker(false)}
resource={file.imagem_url}
setResource={(newValue) =>
updateFile(index, {
imagem_url: newValue?.image,
data_evidencia: newValue?.metaData?.data_evidencia,
latitude: newValue?.metaData?.latitude,
longitude: newValue?.metaData?.longitude,
})
}
/>
updateFile(index, { legenda: text })}
numberOfLines={2}
placeholder="Inserir legenda"
maxLength={90}
/>
))}
setEvidencias(files)}
disabled={!files[0]?.imagem_url}
>
);
};
export default ModalEvidencia;
Пример ответа:
"path": "file: //storage/emulate/0/android/data/com.formularios/files/pictures/3307a61e-b805-49d5-85a7-950ca6b48530.jpg",
"Br/>". /> «Высота»: 4624,
«mime»: «image /jpeg»,
«размер»: 302829,
"Exif": {
"sepactimeoriginal": null,
"sepectimedIgitized": null,
"sopectime": null,
nullized ": nullized": nullized ": nullized". «2025: 03: 28 16:35:42»,
«Ориентация»: «6»,
«Imagelength»: «2604»,
«gpsprocessingmethod»: null,
«Make»: «Samsung»,
«gpslongituderef»:
»,
« gpslongituderef »:« br /> »,
«Flash»: «0»,
«gpslatity»: «0 /1,0 /1,0 /1»,
«ImageWidth»: «4624»,
«gpsdatestamp»: null,
«gpsaltituderef»: null,
whitebalance «:»,
" ":",
": ",
":". /> «Фокусировка»: «523/100»,
«exposuretime»: «0,1»,
«isospeedratings»: «2500»,
«широта»: 0,
"dateTime": "2025: 03: 28 16:35:42",
"Londude": 0,
"B. "1.8",
"Модель": "sm-m315f",
"gpstimestamp": null,
"gpslongity": "0/1,0/1,0/1"
Подробнее здесь:
https://stackoverflow.com/questions/795 ... -show-0-an
1743429904
Anonymous
Я не могу получить метаданные GPS изображения на Android React Native, я проверил многие библиотеки, большинство показывают 0/1, 0/1, 0/1, но они не являются правильными координатами GPS.[code]import React, { useEffect, useState } from "react"; import { Text, View, TouchableOpacity, Image, Modal } from "react-native"; import ImagePicker from "react-native-image-crop-picker"; import { requestPermission } from "../../utils/nativeFunctions"; import { getStyles } from "./styles"; import { useTheme } from "@trizyapp/sdk"; import { CameraIcon, GaleriaIcon } from "../../assets/icons"; import { parse } from "date-fns"; import { writeAsync, readAsync, ExifTags } from "@lodev09/react-native-exify"; import { PermissionsAndroid } from "react-native"; import { convertCoordinates } from "../../utils/convertCoordenadas"; interface Props { resource: string; setResource: (resource: any) => void; onlyModal?: boolean; openModal?: boolean; handleClose?: () => void; setOpenModal?: (openModal: boolean) => void; } const CustomImagePicker = ({ resource, setResource, onlyModal = false, openModal = false, handleClose, }: Props) => { const styles = getStyles({}); const { color: colors, spaces } = useTheme(); const [openButtonsModal, setOpenButtonsModal] = useState(false); const handlePress = () => { setOpenButtonsModal(true); }; useEffect(() => { if (openModal && !openButtonsModal) { setOpenButtonsModal(true); } }, [openModal]); const handleModalClose = () => { setOpenButtonsModal(false); handleClose && handleClose(); }; const extractMetadata = (exifData: any) => { if (!exifData) { return { data_evidencia: null, latitude: null, longitude: null, }; } let latitude = null; let longitude = null; if (exifData.GPS && exifData.GPS.Latitude && exifData.GPS.Longitude) { latitude = exifData.GPS.Latitude; longitude = exifData.GPS.Longitude; } else if ( exifData.GPSLatitude !== undefined && exifData.GPSLongitude !== undefined ) { latitude = exifData.GPSLatitude; longitude = exifData.GPSLongitude; } else if ( exifData.latitude !== undefined && exifData.longitude !== undefined ) { latitude = exifData.latitude; longitude = exifData.longitude; } let dataEvidencia = null; const dateFields = [ "DateTime", "DateTimeOriginal", "DateTimeDigitized", "creationDate", ]; for (const field of dateFields) { if (exifData[field]) { try { let dateString = exifData[field]; if (dateString.includes(":")) { dateString = dateString.replace( /^(\d{4}):(\d{2}):(\d{2})/, "$1-$2-$3" ); dataEvidencia = parse( dateString, "yyyy-MM-dd HH:mm:ss", new Date() ); } else { dataEvidencia = new Date(dateString); } if (!isNaN(dataEvidencia.getTime())) { break; } } catch (e) { console.log(`Error parsing date from ${field}:`, e); } } } return { data_evidencia: dataEvidencia, ...convertCoordinates(longitude, latitude), }; }; const selectFile = async (tipo: string) => { try { let permissao = false; if (tipo === "camera") { permissao = await requestPermission({ tipo: "camera" }); permissao = await requestPermission({ tipo: "localizacao_midia" }); } else { permissao = await requestPermission({ tipo: "galeria" }); permissao = await requestPermission({ tipo: "ler_armazenamento_externo", }); permissao = await requestPermission({ tipo: "localizacao_midia" }); console.log("Permissão de localizacao_midia", permissao); } console.log( "Status real das permissões:", await PermissionsAndroid.check( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION ), await PermissionsAndroid.check( PermissionsAndroid.PERMISSIONS.ACCESS_MEDIA_LOCATION ) ); if (permissao) { const options = { width: 1000, height: 1000, cropping: false, includeExif: true, includeExtra: true, compressImageQuality: 0.8, forceJpg: true, }; let result = null; if (tipo === "camera") { permissao = await requestPermission({ tipo: "localizacao" }); console.log("Permissão de localização:", permissao); result = await ImagePicker.openCamera({ ...options, useFrontCamera: false, }); } else { result = await ImagePicker.openPicker(options); } if (result) { const imagePath = result.path; const tags = await readAsync(imagePath); console.log(tags); // const tags = await readAsync(imagePath); console.log( "Raw image result:", JSON.stringify( { path: result.path, width: result.width, height: result.height, mime: result.mime, size: result.size, exif: result.exif ? // Criar um novo objeto com pares chave-valor Object.fromEntries( Object.entries(result.exif).map(([key, value]) => [ key, // Converter valores complexos para formato legível value instanceof Object && !(value instanceof Array) ? value.toString() : value, ]) ) : null, }, null, 2 ) // Formatação com indentação ); const metaData = extractMetadata(result.exif); setResource({ image: result.path, metaData }); } handleModalClose(); } } catch (error) { Promise.reject(error); } }; const renderModal = () => { return ( handleModalClose()} > selectFile("camera")}> Câmera selectFile("gallery")}> Galeria ); }; return onlyModal ? ( renderModal() ) : ( {resource && resource.length > 0 ? ( ) : ( Insira seu arquivo aqui (.jpeg, .jpg ou png) )} {renderModal()} ); }; export default CustomImagePicker; < /code> < /code> import React, { useState } from "react"; import { View, Modal, TouchableOpacity } from "react-native"; import { getStyles } from "./styles"; import { useTheme, Button, CloseIcon, Text, SizedBox } from "@trizyapp/sdk"; import { ImagePicker, TextInput } from "../../../../components"; import { DeleteIcon, RefreshIcon, SendIcon } from "../../../../assets/icons"; interface Evidencia { imagem_url: string; legenda: string; data_evidencia: string | null; latitude?: number; longitude?: number; } interface Props { open: boolean; handleClose: () => void; handleRemove: () => void; evidencias?: Evidencia[]; setEvidencias: (evidencias: Evidencia[]) => void; } const ModalEvidencia = ({ open, handleClose, handleRemove, evidencias = [], setEvidencias, }: Props) => { const styles = getStyles({}); const { color: colors, spaces } = useTheme(); const [openPicker, setOpenPicker] = useState(false); const [files, setFiles] = useState( evidencias?.length > 0 ? evidencias : [{ imagem_url: "", legenda: "", data_evidencia: null }] ); const toggleModalPicker = () => setOpenPicker((prev) => !prev); const updateFile = (index: number, updatedData: Partial) => { console.log(`Atualizando arquivo no índice ${index}:`, updatedData); setFiles((prevFiles) => prevFiles.map((file, i) => i === index ? { ...file, ...updatedData } : file ) ); }; return ( {files.map((file, index) => ( setOpenPicker(false)} resource={file.imagem_url} setResource={(newValue) => updateFile(index, { imagem_url: newValue?.image, data_evidencia: newValue?.metaData?.data_evidencia, latitude: newValue?.metaData?.latitude, longitude: newValue?.metaData?.longitude, }) } /> updateFile(index, { legenda: text })} numberOfLines={2} placeholder="Inserir legenda" maxLength={90} /> ))} setEvidencias(files)} disabled={!files[0]?.imagem_url} > ); }; export default ModalEvidencia; [/code] Пример ответа: "path": "file: //storage/emulate/0/android/data/com.formularios/files/pictures/3307a61e-b805-49d5-85a7-950ca6b48530.jpg", "Br/>". /> «Высота»: 4624, «mime»: «image /jpeg», «размер»: 302829, "Exif": { "sepactimeoriginal": null, "sepectimedIgitized": null, "sopectime": null, nullized ": nullized": nullized ": nullized". «2025: 03: 28 16:35:42», «Ориентация»: «6», «Imagelength»: «2604», «gpsprocessingmethod»: null, «Make»: «Samsung», «gpslongituderef»: », « gpslongituderef »:« br /> », «Flash»: «0», «gpslatity»: «0 /1,0 /1,0 /1», «ImageWidth»: «4624», «gpsdatestamp»: null, «gpsaltituderef»: null, whitebalance «:», " ":", ": ", ":". /> «Фокусировка»: «523/100», «exposuretime»: «0,1», «isospeedratings»: «2500», «широта»: 0, "dateTime": "2025: 03: 28 16:35:42", "Londude": 0, "B. "1.8", "Модель": "sm-m315f", "gpstimestamp": null, "gpslongity": "0/1,0/1,0/1" Подробнее здесь: [url]https://stackoverflow.com/questions/79546242/i-cant-get-the-gps-metadata-of-an-image-on-android-react-native-most-show-0-an[/url]