Get size of a UIImage (bytes length) not height and width

IphoneUiimage

Iphone Problem Overview


I'm trying to get the length of a UIImage. Not the width or height of the image, but the size of the data.

Iphone Solutions


Solution 1 - Iphone

 UIImage *img = [UIImage imageNamed:@"sample.png"];
 NSData *imgData = UIImageJPEGRepresentation(img, 1.0); 
 NSLog(@"Size of Image(bytes):%d",[imgData length]);

Solution 2 - Iphone

The underlying data of a UIImage can vary, so for the same "image" one can have varying sizes of data. One thing you can do is use UIImagePNGRepresentation or UIImageJPEGRepresentation to get the equivalent NSData constructs for either, then check the size of that.

Solution 3 - Iphone

Use the CGImage property of UIImage. Then using a combination of CGImageGetBytesPerRow *
CGImageGetHeight, add in the sizeof UIImage, you should be within a few bytes of the actual size.

This will return the size of the image, uncompressed, if you want to use it for purposes such as malloc in preparation for bitmap manipulation (assuming a 4 byte pixel format of 3 bytes for RGB and 1 for Alpha):

int	height = image.size.height,
	width = image.size.width;
int bytesPerRow = 4*width;
if (bytesPerRow % 16)
	bytesPerRow = ((bytesPerRow / 16) + 1) * 16;
int dataSize = height*bytesPerRow;

Solution 4 - Iphone

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)editInfo
{
   UIImage *image=[editInfo valueForKey:UIImagePickerControllerOriginalImage];
   NSURL *imageURL=[editInfo valueForKey:UIImagePickerControllerReferenceURL];
   __block long long realSize;
  
   ALAssetsLibraryAssetForURLResultBlock resultBlock=^(ALAsset *asset)
   {
      ALAssetRepresentation *representation=[asset defaultRepresentation];
      realSize=[representation size];
   };

   ALAssetsLibraryAccessFailureBlock failureBlock=^(NSError *error)
   {
      NSLog(@"%@", [error localizedDescription]);
   };

   if(imageURL)
   {
      ALAssetsLibrary *assetsLibrary=[[[ALAssetsLibrary alloc] init] autorelease];
      [assetsLibrary assetForURL:imageURL resultBlock:resultBlock failureBlock:failureBlock];
   }
}

Solution 5 - Iphone

Example in Swift:

let img: UIImage? = UIImage(named: "yolo.png")
let imgData: NSData = UIImageJPEGRepresentation(img, 0)
println("Size of Image: \(imgData.length) bytes")

Solution 6 - Iphone

This following is the fastest, cleanest, most general, and least error-prone way to get the answer. In a category UIImage+MemorySize:

#import <objc/runtime.h>

- (size_t) memorySize
{
  CGImageRef image = self.CGImage;
  size_t instanceSize = class_getInstanceSize(self.class);
  size_t pixmapSize = CGImageGetHeight(image) * CGImageGetBytesPerRow(image);
  size_t totalSize = instanceSize + pixmapSize;
  return totalSize;
}

Or if you only want the actual bitmap and not the UIImage instance container, then it is truly as simple as this:

- (size_t) memorySize
{
  return CGImageGetHeight(self.CGImage) * CGImageGetBytesPerRow(self.CGImage);
}

Solution 7 - Iphone

Swift 3:

let image = UIImage(named: "example.jpg")
if let data = UIImageJPEGRepresentation(image, 1.0) {
    print("Size: \(data.count) bytes")
}

Solution 8 - Iphone

Swift 4 & 5:

extension UIImage {
    var sizeInBytes: Int {
        guard let cgImage = self.cgImage else {
            // This won't work for CIImage-based UIImages
            assertionFailure()
            return 0
        }
        return cgImage.bytesPerRow * cgImage.height
    }
}

Solution 9 - Iphone

I'm not sure your situation. If you need the actual byte size, I don't think you do that. You can use UIImagePNGRepresentation or UIImageJPEGRepresentation to get an NSData object of compressed data of the image.

I think you want to get the actual size of uncompressed image(pixels data). You need to convert UIImage* or CGImageRef to raw data. This is an example of converting UIImage to IplImage(from OpenCV). You just need to allocate enough memory and pass the pointer to CGBitmapContextCreate's first arg.

UIImage *image = //Your image
CGImageRef imageRef = image.CGImage;

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
IplImage *iplimage = cvCreateImage(cvSize(image.size.width, image.size.height), IPL_DEPTH_8U, 4);
CGContextRef contextRef = CGBitmapContextCreate(iplimage->imageData, iplimage->width, iplimage->height,
												iplimage->depth, iplimage->widthStep,
												colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);

IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, 3);
cvCvtColor(iplimage, ret, CV_RGBA2BGR);
cvReleaseImage(&iplimage);


Solution 10 - Iphone

SWIFT 4+

let imgData = image?.jpegData(compressionQuality: 1.0)
debugPrint("Size of Image: \(imgData!.count) bytes")

you can use this trick to find out image size.

Solution 11 - Iphone

If needed in human readable form we can use ByteCountFormatter

if let data = UIImageJPEGRepresentation(image, 1.0) {
   let fileSizeStr = ByteCountFormatter.string(fromByteCount: Int64(data.count), countStyle: ByteCountFormatter.CountStyle.memory)
   print(fileSizeStr)
}

Where Int64(data.count) is what you need in numeric format.

Solution 12 - Iphone

I tried to get image size using

let imgData = image.jpegData(compressionQuality: 1.0)

but it gives less than the actual size of image. Then i tried to get size using PNG representation.

let imageData = image.pngData()

but it gives more byte counts than the actual image size.

The only thing that worked perfectly for me.

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    var asset: PHAsset!
    if #available(iOS 11.0, *) {
      asset = info[UIImagePickerControllerPHAsset] as? PHAsset
    } else {
      if let url = info[UIImagePickerControllerReferenceURL] as? URL {
        asset = PHAsset.fetchAssets(withALAssetURLs: [url], options: .none).firstObject!
      }
    }

    if #available(iOS 13, *) {
      PHImageManager.default().requestImageDataAndOrientation(for: asset, options: .none) { data, string, orien, info in
        let imgData = NSData(data:data!)
        var imageSize: Int = imgData.count
        print("actual size of image in KB: %f ", Double(imageSize) / 1024.0)
      }
    } else {
      PHImageManager.default().requestImageData(for: asset, options: .none) { data, string, orientation, info in
        let imgData = NSData(data:data!)
        var imageSize: Int = imgData.count
        print("actual size of image in KB: %f ", Double(imageSize) / 1024.0)
      }
    }
  }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKevinView Question on Stackoverflow
Solution 1 - IphoneMeetView Answer on Stackoverflow
Solution 2 - IphonefbreretoView Answer on Stackoverflow
Solution 3 - IphonemahboudzView Answer on Stackoverflow
Solution 4 - IphoneDarkngsView Answer on Stackoverflow
Solution 5 - IphoneKing-WizardView Answer on Stackoverflow
Solution 6 - IphoneTodd LehmanView Answer on Stackoverflow
Solution 7 - IphonechengsamView Answer on Stackoverflow
Solution 8 - IphoneJohn ScaloView Answer on Stackoverflow
Solution 9 - IphoneMike ChenView Answer on Stackoverflow
Solution 10 - IphoneHamid ShahsavariView Answer on Stackoverflow
Solution 11 - IphoneTheTigerView Answer on Stackoverflow
Solution 12 - Iphoneaqsa arshadView Answer on Stackoverflow