Determine image MB size from PHAsset

After emailing the picture to myself and checking the size on the system, it turns out approach ONE is the closest to the actual size.

To get the size of a PHAsset (Image type), I used the following method:

var asset = self.fetchResults[index] as PHAsset

self.imageManager.requestImageDataForAsset(asset, options: nil) { (data:NSData!, string:String!, orientation:UIImageOrientation, object:[NSObject : AnyObject]!) -> Void in
    //transform into image
    var image = UIImage(data: data)

    //Get bytes size of image
    var imageSize = Float(data.length)

    //Transform into Megabytes
    imageSize = imageSize/(1024*1024)
 }

Command + I on my macbook shows the image size as 1,575,062 bytes.
imageSize in my program shows the size at 1,576,960 bytes.
I tested with five other images and the two sizes reported were just as close.


The NSData approach becomes precarious when data is prohibitively large. You can use the below as an alternative:

[[PHImageManager defaultManager] requestAVAssetForVideo:self.phAsset options:nil resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {

    CGFloat rawSize = 0;

    if ([asset isKindOfClass:[AVURLAsset class]])
    {
        AVURLAsset *URLAsset = (AVURLAsset *)asset;
        NSNumber *size;
        [URLAsset.URL getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
        rawSize = [size floatValue] / (1024.0 * 1024.0);
    }
    else if ([asset isKindOfClass:[AVComposition class]])
    {
        // Asset is an AVComposition (e.g. slomo video)

        float estimatedSize = 0.0;

        NSArray *tracks = [self tracks];
        for (AVAssetTrack * track in tracks)
        {
            float rate = [track estimatedDataRate] / 8.0f; // convert bits per second to bytes per second
            float seconds = CMTimeGetSeconds([track timeRange].duration);
            estimatedSize += seconds * rate;
        }

        rawSize = estimatedSize;
    }

    if (completionBlock)
    {
        NSError *error = info[PHImageErrorKey];
        completionBlock(rawSize, error);
    }

}];

Or for ALAssets, something like this:

        [[[ALAssetsLibrary alloc] init] assetForURL:asset.URL resultBlock:^(ALAsset *asset) {

            long long sizeBytes = [[asset defaultRepresentation] size];

            if (completionBlock)
            {
                completionBlock(sizeBytes, nil);
            }

        } failureBlock:^(NSError *error) {

            if (completionBlock)
            {
                completionBlock(0, error);
            }

        }];

Tags:

Ios

Swift