Closed Dakuan closed 2 years ago
Hi @Dakuan,
the exif-parser
package you are using in the code outputs JSON in different format than the ImagePicker
. The LensModel
property you are looking for is located in tags
not in exif
after the parse.
You can see your example with the fix in there:
heya, thats not working for me:
same if I use the piexifjs lib:
Object {
"0th": Object {
"274": 1,
"34665": 38,
},
"1st": Object {},
"Exif": Object {
"40961": 65535,
"40962": 5472,
"40963": 3648,
},
"GPS": Object {},
"Interop": Object {},
"thumbnail": null,
}
heya, thats not working for me:
Sorry, but I did not understand the problem, can you clarify? Is my Snack example not working for you, or you are talking about other code?
I'm not sure why you expect the different libraries to output exactly the same result. Currently for me it looks like the issues you are experiencing are not related to Expo.
Your updated snack is not retuning exif data for me. Same goes for when the file is eventually uploaded to cloud storage. its not reformatting, its removing the data entirely. It's for sure related to expo (or underlying lib). The photo 100% has exif data on device
Your updated snack is not retuning exif data for me.
This it weird, it might be related to the specific image you are trying to use. Snack works for me fine of the few test devices.
Also you need to remember that not all photos on the device will have the lens data, for example iOS screenshot do not have that property set at all, same for the most images download form the web.
Our app is for pro wildlife photographers. Their photos are straight from camera, or via adobe lightroom and contain lots of exif data. I've scraped all the files in the storage bucket, they are all blank. Images are not processed at all by our app. Just uploaded to GCloud.
before expo
after expo:
your snack:
exif output from filesystem:
"0th": Object {
"274": 1,
"34665": 38,
},
"1st": Object {},
"Exif": Object {
"40961": 65535,
"40962": 5472,
"40963": 3648,
},
"GPS": Object {},
"Interop": Object {},
"thumbnail": null,
}```
Still it looks like for me like exif-parser
issue, since it's the library responsible for parsing the base64 string.
The ImagePicker
returns correct EXIF (before value) as your example shows in the first place. It's one of your manipulation on that file which move/removes/inavlidates EXIF data.
Our app is for pro wildlife photographers. Their photos are straight from camera, or via adobe lightroom and contain lots of exif data. I've scraped all the files in the storage bucket, they are all blank. Images are not processed at all by our app. Just uploaded to GCloud.
Did you try to use uploadAsync
(https://docs.expo.dev/versions/latest/sdk/filesystem/#filesystemuploadasyncurl-fileuri-options) in your case instead of using readAsStringAsync
and re-parsing image back, just to send it?
And FYI you are processing the image right in here:
const file = await FileSystem.readAsStringAsync(result.uri, {
encoding: FileSystem.EncodingType.Base64,
});
const buf = Buffer.from(file, "base64");
const parser = Exif.create(buf);
const res = await parser.parse();
I did, in the original app the images are not being messed with at all, fileuri's from the picker get passed around redux a bit and get uploaded to google cloud storage like this:
const uploadResult = await FileSystem.uploadAsync(signedUrl, fileUri, {
headers: {
Accept: "application/json",
"Content-Type": contentType,
},
httpMethod: "PUT",
});
I have a script to inspect the files in the bucket:
import { Storage } from "@google-cloud/storage";
import * as piexif from "piexifjs";
import * as Exif from "exif-parser";
import fs from "fs";
import { promisify } from "util";
import path from "path";
const writeFile = promisify(fs.writeFile);
const BUCKET_NAME = "REDACTED";
async function stream2buffer(stream: Stream): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
const _buf = Array<any>();
stream.on("data", (chunk) => _buf.push(chunk));
stream.on("end", () => resolve(Buffer.concat(_buf)));
stream.on("error", (err) => reject(`error converting stream - ${err}`));
});
}
(async function () {
try {
const storage = new Storage();
const [files] = await storage.bucket(BUCKET_NAME).getFiles();
console.log("Files:");
await Promise.all(
files.map(async (file) => {
try {
if (file.name.includes("users")) {
const buffer = await stream2buffer(file.createReadStream());
// const binaryString = buffer.toString("binary");
// const existingExif = piexif.load(binaryString);
const parser = Exif.create(buffer);
const result = parser.parse();
console.log(result);
const segments = file.name.split("/");
await writeFile(
path.join(
__dirname,
"./results/parser/",
`${segments[segments.length - 1]}.txt`
),
JSON.stringify(result),
{ encoding: "utf-8" }
);
}
} catch (e) {
console.log(file.name, e);
}
})
);
} catch (err) {
console.log(err);
process.exit(1);
}
})();
I've tried using the script with piexifjs and exif-parse npm modules, all blank:
{
"startMarker":{
"offset":0
},
"tags":{
"Orientation":1,
"ColorSpace":65535,
"ExifImageWidth":1536,
"ExifImageHeight":2048
},
"imageSize":{
"height":2048,
"width":1536
},
"app1Offset":24
}
This issue is stale because it has been open for 60 days with no activity. If there is no activity in the next 7 days, the issue will be closed.
This issue was closed because it has been inactive for 7 days since being marked as stale. Please open a new issue if you believe you are encountering a related problem.
This issue is still reproducible
Summary
When you use
ImagePicker.launchImageLibraryAsync
it will extract the exif data from the image, and relay that if the{exif: true}
option is provided. However, when the selected image is copied to the temp folder, the exif data is missing from the copied image. This means that if the image is uploaded, the image on the server will not have the exif data. This behaviour has not been requested, and shouldn't happen.Managed or bare workflow? If you have
ios/
orandroid/
directories in your project, the answer is bare!managed
What platform(s) does this occur on?
iOS
SDK Version (managed workflow only)
42
Environment
Reproducible demo or steps to reproduce from a blank project
https://snack.expo.dev/@dakuan/exif-removed