dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
34.92k stars 9.86k forks source link

Blazor RequestImageFileAsync to keep image EXIF data #28691

Open georgeemr opened 3 years ago

georgeemr commented 3 years ago

Is your feature request related to a problem? Please describe.

Maintain Exif metadata when you request a file picture resized. Example: When I upload an image using InputFile on Blazor, if I request the original file I can get the Exif metadata, but If I request the image resized I lost the information, this could be an important feature because I need to determine the rotation of the picture so I can rotate it automatically and try to avoid the user to manually rotate the picture.

Describe the solution you'd like

There's a way to write the Exif to a current image in Javascript so I think is possible to read the current and add it to the newly resized image, this way the server can receive the resized image and this translates to saving in bandwith, mostly on phone devices where a picture can have a size of 20mb.

mkArtakMSFT commented 3 years ago

Thanks for contacting us. This is indeed not supported currently. Do you have any recommendations / ideas about how this should be done? If you think it's simple feel free to send us a PR so we can discuss it that way. Alternatively, just share your thoughts here before sending a PR.

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

TanayParikh commented 2 years ago

I looked into this briefly, we do image resizing here:

https://github.com/dotnet/aspnetcore/blob/4b48d6f1321789a51178792795bcbbdc59fa1a07/src/Components/Web.JS/src/InputFile.ts#L70-L80

We need to preserve & extract the EXIF data from the original image, and embed it into the resizedImageBlob. There aren't any standard JS APIs to do this as far as I can tell, but it does seem to be possible via external EXIF libraries.

Due to limited community engagement, and the complexity of extracting/embedding the EXIF data via non-standard APIs this would fall pretty low on our priority list. Leaving open to see if we may want to revisit this in the future.

AbstractionsAs commented 2 years ago

I just want to second this. When getting images, EXIF data is nice to have for certain scenarios such as geolocation and timestamp, but for exif rotation it's absolutely critical. Otherwhise you might end up with weirdly rotated images, something that renders the entire functionality useless.

hrvoje-grabusic commented 8 months ago

I also need this.

I have a server blazor app where mobile users upload photos via input control by taking a camera photo and it is too slow to upload without browser resize. My app uses the photo metadata as evidence of where the photo was taken and when.

RequestImageFileAsync is amazing but would be much better if it could keep the EXIF data.

Meanwhile i use EXIF reader as a clunky workaround to extract the data before blazor upload.

_layout.cshtml

<script src="~/js/exif-reader.js"></script>
<script>
 async function getExif(id, index) 
 {
     console.log("getExif")

     var el = document.getElementById(id);
     const file = el.files[0];

     var tags = await ExifReader.load(file)
     //console.log(tags)
     var result = {
         latitude: tags["GPSLatitude"] ? tags["GPSLatitude"].description : 0,
         longitude: tags["GPSLongitude"] ? tags["GPSLongitude"].description : 0,
         dateTimeOriginal: tags["DateTimeOriginal"] ? tags["DateTimeOriginal"].description: "",

         orintation: tags["Orientation"] ? tags["Orientation"].description : "",
         orientation_id: tags["Orientation"] ? tags["Orientation"].id : "",
         orientation_value: tags["Orientation"] ? tags["Orientation"].value : "",
     }
     console.log(result)
     return result;
 }
</script>

fileupload.razor

@inject IJSRuntime jsRuntime

<InputFile OnChange="@LoadFiles" multiple class="form-control" acccept="image/*" id="@Folder" />

@{
 public record ExifTags(double latitude,
     double longitude,
     string dateTimeOriginal,
     string orientation,
     int orientation_id,
     int orientation_value
 );

private async Task LoadFiles(InputFileChangeEventArgs e)
{
    isLoading = true;
    loadedFiles.Clear();
    progressPercent = 0;

    int n = 0;
    foreach (var file in e.GetMultipleFiles(maxAllowedFiles))
    {
        try
        {
            ExifTags tags = await jsRuntime.InvokeAsync<ExifTags>("getExif", Folder, n);
            Console.WriteLine(tags);

            var resizedImage = await file.RequestImageFileAsync(file.ContentType, 1024, 1024);

            // upload image
            ....
           // fix meta data
           ...
           // draw meta data overlay
       }
}
aterbo commented 5 months ago

Has there been any progress or updates on this item? Having the images resized without handling the EXIF data makes the RequestImageFileAsync Method borderline useless.