iOS Question How to detect animated GIF via Camera_Complete() event on iMedia library?

laguilar

Member
Licensed User
Longtime User
I am using the iMedia library, the user select an animated GIF, but it seems as though the Bitmap object returned is converted to a single image from a GIF before the _Complete event is called, because no matter what method I attempt to detect a frame count, it always comes up as 1. I simply need to determine if the selected image is animated GIF or not.

Initialize/Select Code:
Sub Process_Globals
    Private camsel As Camera
End Sub

Private Sub Button1_Click
    Dim btn As B4XView = Sender
    camsel.Initialize("camsel", Page1)
    camsel.SelectFromPhotoLibrary(btn, camsel.TYPE_IMAGE)
End Sub

Private Sub mediascam_Complete (Success As Boolean, Image As Bitmap, VideoPath As String)
    If Success = False Then Return
    Dim minfo As Map = camsel.GetPickedMediaInfo
    Dim isGIF As Boolean = no.RunMethod("isAnimatedGIF:", Array(minfo.Get("UIImagePickerControllerImageURL")))
    Dim isGIF As Boolean = no.RunMethod("isAnimatedGIF2:", Array(minfo.Get("UIImagePickerControllerOriginalImage")))
    Dim isGIF As Boolean = no.RunMethod("isAnimatedGIF2:", Array(Image))
    Dim isGIF As Boolean = no.RunMethod("isAnimatedGIF2:", Array(Image.As(NativeObject)))
    If isGIF = True Then
        Log("GIF:true")
    Else
        Log("GIF:false")
    End If
End Sub

I've tried calling 2 different variations of Obj-C code. This one accepts an NSURL parameter of which I was sending minfo.Get("UIImagePickerControllerImageURL"):

Check Animation Code (URL):
- (BOOL *) isAnimatedGIF: (NSURL*) imageUrl {
    CGImageSourceRef imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)imageUrl, NULL);
    if (imageSource) {
        size_t imageCount = CGImageSourceGetCount(imageSource);
        if (imageCount > 1) {
            CFStringRef imageType = CGImageSourceGetType(imageSource);
            if (imageType) {
                NSString *imageTypeString = (__bridge NSString *)imageType;
                if ([imageTypeString isEqualToString:(NSString *)kUTTypeGIF]) {
                    CFDictionaryRef imageProperties = CGImageSourceCopyProperties(imageSource, NULL);
                    if (imageProperties) {
                        CFDictionaryRef gifProperties = CFDictionaryGetValue(imageProperties, kCGImagePropertyGIFDictionary);
                        if (gifProperties) {
                            CFStringRef gifLoopCountKey = kCGImagePropertyGIFLoopCount;
                            CFNumberRef gifLoopCount = CFDictionaryGetValue(gifProperties, gifLoopCountKey);
                            if (gifLoopCount) {
                                int loopCount;
                                CFNumberGetValue(gifLoopCount, kCFNumberIntType, &loopCount);
                                if (loopCount == 0) {
                                    // Animated GIF
                                    CFRelease(imageSource);
                                    CFRelease(imageProperties);
                                    return YES;
                                }
                            }
                        }
                        CFRelease(imageProperties);
                    }
                }
            }
        }
        CFRelease(imageSource);
    }
    return NO;
}

And this one accepts the UIImage object. Of which I've tried passing both "Image", "Image.As(NativeObject)", and minfo.Get("UIImagePickerControllerOriginalImage"). All 3 have the same result:


Check Animation Code (UIImage):
- (BOOL *) isAnimatedGIF2: (UIImage*) image {
    NSData *imageData = UIImagePNGRepresentation(image); // Convert the image to PNG data

    CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
    if (imageSource) {
        size_t imageCount = CGImageSourceGetCount(imageSource);
        if (imageCount > 1) {
            CFStringRef imageType = CGImageSourceGetType(imageSource);
            if (imageType) {
                NSString *imageTypeString = (__bridge NSString *)imageType;
                if ([imageTypeString isEqualToString:(NSString *)kUTTypeGIF]) {
                    CFDictionaryRef imageProperties = CGImageSourceCopyProperties(imageSource, NULL);
                    if (imageProperties) {
                        CFDictionaryRef gifProperties = CFDictionaryGetValue(imageProperties, kCGImagePropertyGIFDictionary);
                        if (gifProperties) {
                            CFStringRef gifLoopCountKey = kCGImagePropertyGIFLoopCount;
                            CFNumberRef gifLoopCount = CFDictionaryGetValue(gifProperties, gifLoopCountKey);
                            if (gifLoopCount) {
                                int loopCount;
                                CFNumberGetValue(gifLoopCount, kCFNumberIntType, &loopCount);
                                if (loopCount == 0) {
                                    // Animated GIF
                                    CFRelease(imageSource);
                                    CFRelease(imageProperties);
                                    return YES;
                                }
                            }
                        }
                        CFRelease(imageProperties);
                    }
                }
            }
        }
        CFRelease(imageSource);
    }
    return NO;
}
 
Top