【问题标题】:How to compress/resize image on iOS before uploading to a server?如何在上传到服务器之前在 iOS 上压缩/调整图像大小?
【发布时间】:2011-05-22 14:58:32
【问题描述】:

我目前正在使用 iOS 上的 Imgur 使用以下代码将图像上传到服务器:

NSData* imageData = UIImagePNGRepresentation(image);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* fullPathToFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SBTempImage.png"];
[imageData writeToFile:fullPathToFile atomically:NO];

[uploadRequest setFile:fullPathToFile forKey:@"image"];

代码在模拟器中运行并从模拟器的照片库上传文件时运行良好,因为我使用的是快速以太网连接。但是,在选择使用iPhone拍摄的图像时,iPhone上的代码超时。因此,我通过从网络上保存一张小图片并尝试上传它进行了尝试,这很有效。

这让我相信 iPhone 拍摄的大图像在速度有点慢的 3G 网络上会超时。有什么方法可以在发送之前从 iPhone 压缩/调整图像大小?

【问题讨论】:

    标签: ios file-upload ios4 uiimage nsdata


    【解决方案1】:

    这个 sn-p 将调整图像大小:

    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

    变量newSizeCGSize,可以这样定义:

    CGSize newSize = CGSizeMake(100.0f, 100.0f);
    

    【讨论】:

    • 这个解决方案似乎确实有效(图像数据大小从 145k 变为 30k)。
    • "newSize" 是 CGSize 例如。 CGSize newSize = CGSizeMake(100.0f, 100.0f);
    • 太棒了!不要急于压缩技术,最简单和好的解决方案:)
    • 但是这会改变图片的大小,如果我需要将图片上传到原始规格的服务器,那么这将不起作用,对吧?
    • 这是 Size "newSize" ImageSize 的像素吗?
    【解决方案2】:

    一个独立的解决方案:

    - (UIImage *)compressForUpload:(UIImage *)original scale:(CGFloat)scale
    {
        // Calculate new size given scale factor.
        CGSize originalSize = original.size;
        CGSize newSize = CGSizeMake(originalSize.width * scale, originalSize.height * scale);
    
        // Scale the original image to match the new size.
        UIGraphicsBeginImageContext(newSize);
        [original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
        UIImage *compressedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return compressedImage;
    }
    

    感谢@Tuan Nguyen。

    【讨论】:

      【解决方案3】:

      作为对@Tuan Nguyen 的补充,这可能是最快、最优雅的方式。

      要链接到 John Muchow's post at iphonedevelopertips.com ,向 UIImage 添加类别是一种非常方便的快速缩放方式。 只是打电话

          UIImage *_image = [[[UIImage alloc] initWithData:SOME_NSDATA] scaleToSize:CGSizeMake(640.0,480.0)];
      

      返回您的 NSDATA 的 640x480 表示图像(可能是在线图像),无需任何更多代码行。

      【讨论】:

      • 它实际上缩小了像素。所以它也减少了图片的大小。但它本身并没有进行“重新压缩”。如果这就是你在这里提到的。
      【解决方案4】:

      Matt Gemmell 的 MGImageUtilities 非常好,可以有效地调整大小并采用一些省力的方法。

      【讨论】:

        【解决方案5】:

        在此代码中,0.5 表示 50% ...

        UIImage *original = image;
        UIImage *compressedImage = UIImageJPEGRepresentation(original, 0.5f);
        

        【讨论】:

        • 这正是我所需要的。
        【解决方案6】:

        使用这个简单的方法NSData *data = UIImageJPEGRepresentation(chosenImage, 0.2f);

        【讨论】:

          【解决方案7】:

          Zorayr 函数的 Swift 实现(稍作改动,包括按实际单位而非比例的高度或宽度约束):

          class func compressForUpload(original:UIImage, withHeightLimit heightLimit:CGFloat, andWidthLimit widthLimit:CGFloat)->UIImage{
          
              let originalSize = original.size
              var newSize = originalSize
          
              if originalSize.width > widthLimit && originalSize.width > originalSize.height {
          
                  newSize.width = widthLimit
                  newSize.height = originalSize.height*(widthLimit/originalSize.width)
              }else if originalSize.height > heightLimit && originalSize.height > originalSize.width {
          
                  newSize.height = heightLimit
                  newSize.width = originalSize.width*(heightLimit/originalSize.height)
              }
          
              // Scale the original image to match the new size.
              UIGraphicsBeginImageContext(newSize)
              original.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
              let compressedImage = UIGraphicsGetImageFromCurrentImageContext();
              UIGraphicsEndImageContext();
          
              return compressedImage
          }
          

          【讨论】:

          • 这个解决方案很好,但它不适用于方形图像。因为 originalSize.width > originalSize.height 和 originalSize.height > originalSize.width 所以最好改为 >= :-)
          【解决方案8】:
          #import <ImageIO/ImageIO.h>
          #import <MobileCoreServices/MobileCoreServices.h>
          
          + (UIImage *)resizeImage:(UIImage *)image toResolution:(int)resolution {
          NSData *imageData = UIImagePNGRepresentation(image);
          CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
          CFDictionaryRef options = (__bridge CFDictionaryRef) @{
                                                                 (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
                                                                 (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
                                                                 (id) kCGImageSourceThumbnailMaxPixelSize : @(resolution)
                                                                 };
          CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
          CFRelease(src);
          UIImage *img = [[UIImage alloc]initWithCGImage:thumbnail];
          return img;
          }
          

          【讨论】:

            【解决方案9】:

            Swift 2.0 版本的 Jagandeep Singh 方法但需要将数据转换为图像,因为 NSData?不会自动转换 UIImage。

            let orginalImage:UIImage = image
            
            let compressedData = UIImageJPEGRepresentation(orginalImage, 0.5)
            let compressedImage = UIImage(data: compressedData!)
            

            【讨论】:

              【解决方案10】:
              NsData *data=UiImageJPEGRepresentation(Img.image,0.2f);
              

              【讨论】:

              • 详细说明这样的答案通常会有所帮助。提供文档链接、该文档的引用以及您的代码回答问题的原因的解释。
              【解决方案11】:
              UIImage *image = [UIImage imageNamed:@"image.png"];
              NSData *imgData1 = UIImageJPEGRepresentation(image, 1);
              NSLog(@"Original --- Size of Image(bytes):%d",[imgData1 length]);
              
              NSData *imgData2 = UIImageJPEGRepresentation(image, 0.5);
              NSLog(@"After --- Size of Image(bytes):%d",[imgData2 length]);
              image = [UIImage imageWithData:imgData2];
              imgTest.image = image;
              

              尝试按比例因子转换 JPG。这里我使用 0.5 就我而言: 原始 --- 图像大小(字节):85KB 及之后 --- 图像大小(字节):23KB

              【讨论】:

                【解决方案12】:
                -(UIImage *) resizeImage:(UIImage *)orginalImage resizeSize:(CGSize)size
                {
                CGFloat actualHeight = orginalImage.size.height;
                CGFloat actualWidth = orginalImage.size.width;
                //  if(actualWidth <= size.width && actualHeight<=size.height)
                //  {
                //      return orginalImage;
                //  }
                float oldRatio = actualWidth/actualHeight;
                float newRatio = size.width/size.height;
                if(oldRatio < newRatio)
                {
                    oldRatio = size.height/actualHeight;
                    actualWidth = oldRatio * actualWidth;
                    actualHeight = size.height;
                }
                else
                {
                    oldRatio = size.width/actualWidth;
                    actualHeight = oldRatio * actualHeight;
                    actualWidth = size.width;
                }
                
                CGRect rect = CGRectMake(0.0,0.0,actualWidth,actualHeight);
                UIGraphicsBeginImageContext(rect.size);
                [orginalImage drawInRect:rect];
                orginalImage = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
                return orginalImage;
                 }
                

                这是调用方法

                 UIImage *compimage=[appdel resizeImage:imagemain resizeSize:CGSizeMake(40,40)];      
                

                它返回图像这个图像你可以在任何地方显示............

                【讨论】:

                  【解决方案13】:

                  您应该能够通过执行以下操作来制作更小的图像

                  UIImage *small = [UIImage imageWithCGImage:original.CGImage scale:0.25 orientation:original.imageOrientation];
                  

                  (对于四分之一大小的图像)然后将较小的图像转换为 PNG 或您需要的任何格式。

                  【讨论】:

                  • 这改变了缩放图像的报告大小,但实际上并没有改变图像数据。在原始图像和缩放图像上生成的 NSData 的数据长度几乎相同。
                  • 这行不通!这不应该是公认的答案!我刚刚在我的应用程序中实现它只是发现压缩到原始图像大小的 25% 的图像仍然具有与原始图像相同的字节大小。我不知道为什么会有这么多的赞成票或这个无效的答案!
                  • 不起作用。缩放图像,但保留完整大小的数据。
                  • 再次,不起作用。请删除/更新此答案,以免浪费更多时间。
                  • 它不会改变文件大小,因为 UIImage 的深层副本是 CGImage 并且调整大小不会改变图像。请参阅苹果文档,以更改您使用缩放版本创建新图像的文件大小。了解什么是指针。还要知道缩小然后放大会导致图像丢失,如果您将它用于任何重要的事情,它稍后会看起来很模糊。压缩它并使用 JPegCompress 或任何调用函数并发送它。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-09-22
                  • 2016-09-16
                  • 1970-01-01
                  • 2020-09-15
                  • 2020-07-30
                  相关资源
                  最近更新 更多