【问题标题】:Get size of a UIImage (bytes length) not height and width获取 UIImage 的大小(字节长度)而不是高度和宽度
【发布时间】:2009-08-18 21:43:42
【问题描述】:

我正在尝试获取UIImage 的长度。不是图像的宽度或高度,而是数据的大小。

【问题讨论】:

    标签: iphone uiimage


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

    【讨论】:

    • 应该放 1.0 而不是 0;这是原始图像的质量。
    • 在 UIImageJPEGRepresentation 中为压缩质量传递的正确值应该是多少? 1.0 使计算出的尺寸大于原始尺寸。
    • @Nisarg,1.0 提供最高质量和最小压缩。尝试使用 0.6,它具有更好的质量和显着的压缩效果。
    • NSData *imgData = UIImageJPEGRepresentation(img, 1);
    • 如果希望查看图像占用了多少内存,为什么要获得压缩后的大小?通过使用 UIImageJPEGRepresentation,您正在创建一个新图像,它占用空间并复制位;如果您不想消耗更多内存或性能受到挤压,请不要这样做。
    【解决方案2】:

    UIImage 的基础数据可能会有所不同,因此对于同一个“图像”,可以有不同大小的数据。您可以做的一件事是使用UIImagePNGRepresentationUIImageJPEGRepresentation 来获得等效的NSData 构造,然后检查其大小。

    【讨论】:

    • 如我们所料,UIImageJPEGRepresentation 可能会返回使用 UIImagePNGRepresentation 时的一半大小
    • UIImageJPEGRepresentationUIImagePNGRepresentation 不会返回原始大小
    【解决方案3】:

    使用 UIImage 的 CGImage 属性。然后使用 CGImageGetBytesPerRow *
    的组合 CGImageGetHeight,加上UIImage的sizeof,你应该在实际大小的几个字节之内。

    这将返回未压缩的图像大小,如果您想将其用于 malloc 等目的以准备位图操作(假设 4 字节像素格式,RGB 为 3 字节,Alpha 为 1 字节):

    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;
    

    【讨论】:

    • 这里有几个问题; (1) image.size.heightimage.size.width 会给你 CG 单位的大小,不一定是像素。如果 .scale 属性不是 1,那么您将得到错误的答案。 (2) 您假设每个像素有 4 个字节,这对于 RGBA 图像是正确的,但对于灰度图像不是。
    【解决方案4】:
    - (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];
       }
    }
    

    【讨论】:

    • 我认为这是处理 UIImagePickerController 时更优雅的解决方案
    • 这是使用 UIIImagePickerController 的最佳答案
    • 令人惊叹的解决方案兄弟....完美工作...每个人都建议使用 JPEGRepresentation 或 PNGRepresentation...那些导致不正确的图像尺寸...谢谢很多..你节省了我很多时间.
    • 你已经给出了很好的解决方案,使用 imageURL 来找出图像大小。是否有可能使用上述代码中的“图像”从新捕获的图像中获取它?
    【解决方案5】:

    Swift 中的示例:

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

    【讨论】:

    • 如果希望查看图像占用了多少内存,为什么要获得压缩后的大小?并且通过使用 UIImageJPEGRepresentation,您正在创建一个新图像,它占用空间并复制位;如果您不想消耗更多内存或性能受到挤压,请不要这样做。
    【解决方案6】:

    以下是获得答案的最快、最简洁、最通用且最不容易出错的方法。在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;
    }
    

    或者如果你只想要实际的位图而不是 UIImage 实例容器,那么它真的就这么简单:

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

    【讨论】:

      【解决方案7】:

      斯威夫特 3:

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

      【讨论】:

        【解决方案8】:

        我不确定你的情况。如果您需要实际的字节大小,我认为您不会这样做。您可以使用 UIImagePNGRepresentation 或 UIImageJPEGRepresentation 来获取图像压缩数据的 NSData 对象。

        我认为您想获得未压缩图像(像素数据)的实际大小。您需要将 UIImage* 或 CGImageRef 转换为原始数据。这是将 UIImage 转换为 IplImage(来自 OpenCV)的示例。您只需要分配足够的内存并将指针传递给 CGBitmapContextCreate 的第一个参数。

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

        【讨论】:

          【解决方案9】:

          SWIFT 4+

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

          你可以使用这个技巧来找出图像的大小。

          【讨论】:

            【解决方案10】:

            斯威夫特 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
                }
            }
            

            【讨论】:

              【解决方案11】:

              如果需要人类可读的形式,我们可以使用ByteCountFormatter

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

              Int64(data.count) 是您需要的数字格式。

              【讨论】:

                【解决方案12】:

                我尝试使用

                获取图像大小
                let imgData = image.jpegData(compressionQuality: 1.0)
                

                但它提供的图像小于实际大小。然后我尝试使用 PNG 表示来获取大小。

                let imageData = image.pngData()
                

                但它提供的字节数比实际图像大小更多。

                唯一对我来说完美的东西

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

                【讨论】:

                  猜你喜欢
                  • 2011-07-12
                  • 2017-02-02
                  • 1970-01-01
                  • 2021-12-28
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-08-03
                  • 2013-11-29
                  • 2015-12-14
                  相关资源
                  最近更新 更多