Closed floric closed 1 month ago
Hi,
getting the EXIF data itself as "raw bytes" (I assume a Vec
To conclude: Yes, getting the EXIF data itself (and performing at least some of the file-specific encoding) should be possible via little_exif after a small update. However, the other file-type specific stuff you'll have to figure out yourself.
Best, Tobi
Hi,
getting the EXIF data itself as "raw bytes" (I assume a Vec should be fine?) can be added relatively easily. However, writing this to an output stream can be a bit tricky:
* As you mentioned, what you have to write to the stream depends on the filetype, e.g. PNG has a special header, needs additional PNG-specific encoding, etc. (sidenote: PNG is, of the currently supported file types, the _worst_ to work with from a programmer's perspective) * You also have to figure out _where_ (or in case of a stream, _when_) to write the EXIF data * With some file types (e.g. WebP) you need to have the encoded EXIF data _before_ you start your output stream as you need to know the size of the resulting file to write it at the start.
To conclude: Yes, getting the EXIF data itself (and performing at least some of the file-specific encoding) should be possible via little_exif after a small update. However, the other file-type specific stuff you'll have to figure out yourself.
Best, Tobi
Hey Tobi,
thanks a lot for this comprehensive and fast response. I hope, that using img_pars::ImageEXIF
will be enough. At least there I can provide bytes (Vec<u8>
) for EXIF data as well as ICC profiles. The exporting to the different formats is done with the resulting object. I could give it a try, if providing the EXIF data as bytes is really easy for you, and see if img_parts
really handles all of the hard work mentioned by you for us.
Hi,
I've added a new function for the Metadata
called as_u8_vec
where you provide information about which image format you want to use (e.g. FileExtension::WEBP
) and get the EXIF data as a Vec<u8>
. However, as always, the PNG format is a pita to work with, so don't expect this to work on the first try. I'd be glad to help you with getting this to run with img_parts and PNGs if required, but there is the chance that this library will need an update as well due to how EXIF data is handled over there.
So, try it out with little_exif ver 0.3.0 and let me know what you think and if it works or where work is still required. And, in the likely case that you do run into problems, it would be great to get some sort of file stream as hex code or (best case) an image file you tried to create but are unable to use due to problems with the EXIF data so I can compare and debug.
Best, Tobi
Hi,
I've added a new function for the
Metadata
calledas_u8_vec
where you provide information about which image format you want to use (e.g.FileExtension::WEBP
) and get the EXIF data as aVec<u8>
. However, as always, the PNG format is a pita to work with, so don't expect this to work on the first try. I'd be glad to help you with getting this to run with img_parts and PNGs if required, but there is the chance that this library will need an update as well due to how EXIF data is handled over there.So, try it out with little_exif ver 0.3.0 and let me know what you think and if it works or where work is still required. And, in the likely case that you do run into problems, it would be great to get some sort of file stream as hex code or (best case) an image file you tried to create but are unable to use due to problems with the EXIF data so I can compare and debug.
Best, Tobi
Hey :) thanks a lot. I will definitely give it a try. In the mean time I was also successful to use kamadak/exif-rs for the same purpose. But I only tried JPEG so far. But your lib is a little easier to write and read.
This works for me:
Note that you need to strip the first 10 bytes of the little_exif output (see line 25). Took me a while to find out 😄 !
My task is copy (lots of) images and modify the EXIF of the copies. While this is easy using "little" it would be m0re effective to modify EXIF while copying. Would this issue - if resolved - allow for this ?
My task is copy (lots of) images and modify the EXIF of the copies. While this is easy using "little" it would be m0re effective to modify EXIF while copying. Would this issue - if resolved - allow for this ?
I guess what could be done is to
Would that workflow suit you?
Exactly.
It was not obvious to me that it can be done that way, i.e. having little_exif
work on a memory buffer
I'll do some more research....
Exactly. It was not obvious to me that it can be done that way, i.e. having
little_exif
work on a memory buffer I'll do some more research....
Sorry, that's not yet possible. I just wanted to make sure that I understand correctly what you mean before I start working on that feature.
Edit: Just for clarification: During your copy operation you are handling the file as a Vec<u8>
that is read/written using std::fs
functions, right? In that case I'll add a function to little_exif to additionally handle data that is not contained in a file but given as a &mut Vec<u8>
.
I did not yet implement the copying, as I intended just to use a rust std functionality for copying a file.
But of course when doing the file copy manually the content will be a &mut Vec<u8>
.
I added the required functions to perform this actions for JPGs stored as Vec<u8>
, see 0.5.0-beta.1
GREAT ! Many thanks. I'll check this out ASAP .
I tested new_from_vec
from the current GitHub version
something seems to work....
I get a panic!("from_u8_vec: Mangled EXIF data encountered!")
in the build_u8conversion
macro.
It seems to have been called for byte 19912 in the jpg file. the vector content at that point is "Nicon\0...." which seems OK.
The caller seems to have been from_u8_vec_macro
.
And that came from
let subifd_decode_result = Self::decode_ifd(
&encoded_data[relative_offset..].to_vec(),
&subifd_group,
offset,
endian
);
with relative_offset
= 340.
then
let ifd0_decode_result = Self::decode_ifd(
&encoded_data[14..].to_vec(),
&ExifTagGroup::IFD0,
8, // TODO: What if IFD0 is at another offset? Can this even happen?
&endian
);
with endian = Little
and encoded_data
= "Exif\0..."
any idea ? Thanks again....
Update:
I found that the new_from_vec
function is not to blame, but the same file creates the same panic when opend by new_from_path
This is the file: www.bitvibe.de/Upload/0010_A0420427.JPG
I tested that it also happens with the released version from crates.io.
I found that I do have many more files that trigger this.
Thanks for taking a look ....
This has to do with the MakerNotes IFD and, as I recently found out, is also the cause for issue #6. For now, with the fix in 0.5.0-beta2, this data will be handled as a single tag and not further processed. Please let me know if this solves the issue for you as well on other photos.
I added the required functions to perform this actions for JPGs stored as Vec
, see 0.5.0-beta.1
That was easy enough to find out after I modified the sting in the references to be the github linlk :+1:
This has to do with the MakerNotes IFD and, as I recently found out, is also the cause for issue #6. For now, with the fix in 0.5.0-beta2, this data will be handled as a single tag and not further processed. Please let me know if this solves the issue for you as well on other photos.
Yea ! The set of files I am currently testing with allows reading with new_from,_path
.
Many files also are handled without an error by new_from_vec
.
but in the set also is a file with the extension .tif
. FileExtension::from_str
cant handle this as there is no "tif" arm in the FileExtension
enum yet.
I did not yet test writing a file.....
Testing more files:
with some (and new_from_path
I get : Error during decoding: Custom { kind: Other, error: "No EXIF data found!" }
I'll check those files ASAP.... with those files, other software shows exif data
with some it's Illegal format for known tag! Tag: SubjectDistance([]) Expected: RATIONAL64S Got: RATIONAL64U
with some I get a panic:
thread 'main' panicked at C:\Users\Michael Schnell\.cargo\git\checkouts\little_exif-fdd18c59a5ea2fbd\b6ab7bc\src\metadata.rs:591:34:
attempt to subtract with overflow
BTW.: in the released version, FileExtension::from_str
should issue a dedicated Error, rather than ().
Thanks for listening !
This has to do with the MakerNotes IFD and, as I recently found out, is also the cause for issue #6. For now, with the fix in 0.5.0-beta2, this data will be handled as a single tag and not further processed. Please let me know if this solves the issue for you as well on other photos.
Yea ! The set of files I am currently testing with allows reading with
new_from,_path
. Many files also are handled without an error bynew_from_vec
. but in the set also is a file with the extension.tif
.FileExtension::from_str
cant handle this as there is no "tif" arm in theFileExtension
enum yet. I did not yet test writing a file.....
Added TIFF to the todo list
Testing more files:
with some (and
new_from_path
I get :Error during decoding: Custom { kind: Other, error: "No EXIF data found!" }
I'll check those files ASAP.... with those files, other software shows exif data
If you could share an example image where little_exif isn't able to locate the exif data that would be great!
with some it's
Illegal format for known tag! Tag: SubjectDistance([]) Expected: RATIONAL64S Got: RATIONAL64U
My bad! Wrong format from my side. Fixed in 0.5.0-beta3.
with some I get a panic:
thread 'main' panicked at C:\Users\Michael Schnell\.cargo\git\checkouts\little_exif-fdd18c59a5ea2fbd\b6ab7bc\src\metadata.rs:591:34: attempt to subtract with overflow
Again, example image would be helpful!
I'll upload examples ASAP...
(In fact I do need TIFF 👍 )
Just trying to write to a vecFileExtension
would be useful. Or maybe storing the file type with the Metadata struct might make sense ?
testing write No errors issued, the resulting file seems OK.
but when trying new_from_vec
on the file created using write_to_vec
or write_to_path
I get:
thread 'main' panicked at C:\Users\mschnell\.cargo\git\checkouts\little_exif-fdd18c59a5ea2fbd\c62d0d4\src\metadata.rs:592:40:
range end index 510 out of range for slice of length 508
testing write No errors issued, the resulting file seems OK.
but when trying
new_from_vec
on the file created usingwrite_to_vec
orwrite_to_path
I get:thread 'main' panicked at C:\Users\mschnell\.cargo\git\checkouts\little_exif-fdd18c59a5ea2fbd\c62d0d4\src\metadata.rs:592:40: range end index 510 out of range for slice of length 508
Again, without example I can't tell what is going on :-(
I 'll upload the file ASAP.
BTW.: when reading the Metadata of the same file with read_from_path
, I don't get the error.
Here the file that works with new_from_path
but not with new_from_vec
code:
let extension = file_path.extension().unwrap();
let extension = extension.to_str().unwrap();
let file_type = filetype::FileExtension::from_str(extension).unwrap();
let mut content = std::fs::read(file_path).unwrap();
let metadata = Metadata::new_from_vec(&content, file_type);
-> www.bitvibe.de/Upload/x.jpg
the file that does
14: copying //marianne-1/public/hdd_1_1_1/Fotos/Fremde & Scans/Isabell/2019_Stuttgart_Emilio_SL_925-014-126.JPG -> t:/test/2019_Stuttgart_Emilio_SL_925-014-126.JPG <>
Error during decoding: Custom { kind: Other, error: "No EXIF data found!" }
WARNING: Can't read metadata - Create new & empty struct
is
-> www.bitvibe.de/Upload/2019_Stuttgart_Emilio_SL_925-014-126.JPG
the file that does:
thread 'main' panicked at C:\Users\Michael Schnell\.cargo\git\checkouts\little_exif-fdd18c59a5ea2fbd\b6ab7bc\src\metadata.rs:591:34:
attempt to subtract with overflow
is www.bitvibe.de/Upload/2017_emilio_meister_IMG_4436.JPG
My bad! Wrong format from my side. Fixed in 0.5.0-beta3.
In cargo.toml [dependenmcies] I have
little_exif = {git= "https://github.com/TechnikTobi/little_exif.git"}
but when compiling I see
Checking little_exif v0.5.0-beta.2 (https://github.com/TechnikTobi/little_exif.git#b6ab7bcd)
is this normal or do I need to do something special to access beta 3 ?
With this file it seems to take a very long time until the error "No EXIF data found!" is returned.
www.bitvibe.de/Upload/A0462208sw.JPG
My bad! Wrong format from my side. Fixed in 0.5.0-beta3.
In cargo.toml [dependenmcies] I have
little_exif = {git= "https://github.com/TechnikTobi/little_exif.git"}
but when compiling I see
Checking little_exif v0.5.0-beta.2 (https://github.com/TechnikTobi/little_exif.git#b6ab7bcd)
is this normal or do I need to do something special to access beta 3 ?
No idea what is going on here, beta 3 has been published the same way as the previous beta versions; I personally never declare a dependency via the git link. Perhaps this might work for you?
little_exif = { version = "0.5.0-beta.3" }
I suppsed a giuthub ling would provide the latest commit on main
be that beta or whatever.
little_exif = { version = "0.5.0-beta.3" }
does work as expected !
Thanks
Right now I see no difference with Beta.3
BTW.: there is another Black and White picture ( name ?sw.jpg) that takes a very long time to be decoded before issuing the Exif not found
error. Maybe this is a hint for something....
www.bitvibe.de/Upload/A0386910sw.JPG
Right now I see no difference with Beta.3
Regarding what?
Edit: 0.5.0 is now available as a release.
Right now I see no difference with Beta.3
Regarding what?
The files I am currently testing show the same behavior with either.
Right now I see no difference with Beta.3
Regarding what?
The files I am currently testing show the same behavior with either.
Can't be. SubjectDistance
has been changed to RATIONAL64U
. What does the error message say?
(I'll create dedicated issues next time ....)
Can't be.
SubjectDistance
has been changed toRATIONAL64U
. What does the error message say?
Yep. I suppse just the compiling message stating "beta 2" is wrong. I changed the dependency as you suggested and now it correctly is beta 3.
Let me know when I need to change this to "beta 4".
Hey :)
would it be possible to get the exif data as raw bytes instead of writing to an image? The background is, that I'm writing an image directly to an output stream without any filesystem. So I like to build the exif data, add this to the image with
img_parts
and render the result directly in a HTTP response.And: would this exif payload be generic or is it already prepared for the output format (eg. jpeg or png)?
What do you think?
Kind regards, Florian