Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HEIF / HEIC file support #2887

Open
1 task done
SeppPenner opened this issue Jun 4, 2024 · 2 comments
Open
1 task done

HEIF / HEIC file support #2887

SeppPenner opened this issue Jun 4, 2024 · 2 comments

Comments

@SeppPenner
Copy link

Is your feature request related to a problem?

I wanted to load images on Android (Net Maui) from the gallery, but it only seems to be working with .JPEG images, not .HEIC images (I didn't test .PNG and that kind of stuff yet).

Describe the solution you would like

I would like to be able to decode heic images to a SKBitmap object.

Describe alternatives you have considered

None, I hace no idea how this could be done.

Additional context

Feature request #1700 was close because of license issues, https://stackoverflow.com/questions/61232393/open-heic-bitmap-file-in-skiasharp states that it isn't supported.

Code of Conduct

  • I agree to follow this project's Code of Conduct
@SeppPenner
Copy link
Author

SeppPenner commented Jun 4, 2024

I worked around this by following https://learn.microsoft.com/en-us/answers/questions/1282529/does-anybody-know-if-maui-has-a-utility-or-package:

#if ANDROID
global using AndroidBitmapFactory = Android.Graphics.BitmapFactory;
global using AndroidBitmap = Android.Graphics.Bitmap;
#endif

#if IOS
global using IoSNSData = Foundation.NSData;
global using IoSUIImage = UIKit.UIImage;
#endif

public static class ImageHelper
{
    try
    {
        var originalFilePath = await SavePhotoToCache(photo);

        // Don't convert a JPG / JPEG file.
        var filePathLowerCase = originalFilePath.ToLowerInvariant();

        if (filePathLowerCase.EndsWith(".jpg") || filePathLowerCase.EndsWith(".jpeg"))
        {
            return originalFilePath;
        }

        var jpegFilePath = Path.Combine(FileSystem.CacheDirectory, $"{Path.GetFileNameWithoutExtension(photo.FileName)}.jpg");
#if IOS
        using var data = IoSNSData.FromFile(originalFilePath);
        using var image = IoSUIImage.LoadFromData(data);

        if (image is null)
        {
            return null;
        }

        using var jpegData = image.AsJPEG();

        if (jpegData is null)
        {
            return null;
        }

        if (jpegData.Save(jpegFilePath, false, out var error))
        {
            FileHelper.TryDeleteFile(originalFilePath);
            return jpegFilePath;
        }
        else
        {
            return null;
        }
#endif

#if ANDROID
        var image = await AndroidBitmapFactory.DecodeFileAsync(originalFilePath);
        var compressionFormat = AndroidBitmap.CompressFormat.Jpeg;

        if (image is null || compressionFormat is null)
        {
            return null;
        }

        using var ms = new MemoryStream();
        image.Compress(compressionFormat, 100, ms);
        await File.WriteAllBytesAsync(jpegFilePath, ms.ToArray());
        FileHelper.TryDeleteFile(originalFilePath);
        return jpegFilePath;
#endif
    }
    catch
    {
        return null;
    }
}

The code takes the photo that comes from the MAUI media picker or camera as FileResult, saves it to the cache directory first and afterwards tries to convert and save the file as JPG format. I have tested this on Android (Not yet for iOS), and it works with .heic files.

Note: I have left the deletion of the cached file(s) here for simplicity reasons. In my code, the files get deleted properly once not needed anymore, of course.

EDIT: The new version is tested with iOS as well now.

@nandor23
Copy link

Encoding does not work either, it would be great if it were supported too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Ready For Work
Development

No branches or pull requests

2 participants