Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine image MB size from PHAsset

Tags:

ios

swift

I want to determine the memory size of the image accessed through the PHAsset. This size is so that we know how much memory it occupies on the device. Which method does this?

var imageSize = Float(imageData.length)

var image = UIImage(data: imageData)
var jpegSize = UIImageJPEGRepresentation(image, 1)
var pngSize = UIImagePNGRepresentation(image)
var pixelsMultiplied = asset.pixelHeight * asset.pixelWidth

println("regular data: \(imageSize)\nJPEG Size: \(jpegSize.length)\nPNG Size: \(pngSize.length)\nPixel multiplied: \(pixelsMultiplied)")

Results in:

regular data: 1576960.0
JPEG Size: 4604156
PNG Size: 14005689
Pixel multiplied: 7990272

Which one of these values actually represents the amount it occupies on the device?

like image 635
William Falcon Avatar asked Aug 20 '14 02:08

William Falcon


2 Answers

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.

like image 61
William Falcon Avatar answered Oct 08 '22 08:10

William Falcon


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);
            }

        }];
like image 4
Alfie Hanssen Avatar answered Oct 08 '22 08:10

Alfie Hanssen