如何压缩和缩小NSImage?

时间:2013-03-18 11:18:22

标签: objective-c macos cocoa nsimage

这是我的压缩代码

NSBitmapImageRep* tmpRep = [[_image representations] objectAtIndex:0];
[tmpRep setPixelsWide:512];
[tmpRep setPixelsHigh:512];
[tmpRep setSize:NSMakeSize(SmallThumbnailWidth, SmallThumbnailHeight)];
NSDictionary* imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.3] forKey:NSImageCompressionFactor];
NSData* outputImageData = [tmpRep
                           representationUsingType:NSJPEGFileType properties:imageProps];
NSString* imageFilePath = [NSString stringWithFormat:@"%@/thumbnail.jpg",imagePath];
[outputImageData writeToFile:imageFilePath atomically:YES];

原始图像尺寸为960 * 960.我想将原始图像压缩为512 * 512.但是当我在取景器中检查时输出图像的尺寸是960 * 960,并且与原始图像相比的位置大小确实被压缩了。任何人都可以告诉我为什么?谢谢

3 个答案:

答案 0 :(得分:8)

试试这个:

这将减少kbs中的保存大小:

-(NSImage *)imageCompressedByFactor:(float)factor{
    NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:[self TIFFRepresentation]];
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:factor] forKey:NSImageCompressionFactor];
    NSData *compressedData = [imageRep representationUsingType:NSJPEGFileType properties:options];
    return [[NSImage alloc] initWithData:compressedData];
}

这将减少文件大小(以像素为单位): here

复制
@implementation NSImage (ProportionalScaling)

- (NSImage*)imageByScalingProportionallyToSize:(NSSize)targetSize{
  NSImage* sourceImage = self;
  NSImage* newImage = nil;

  if ([sourceImage isValid]){
    NSSize imageSize = [sourceImage size];
    float width  = imageSize.width;
    float height = imageSize.height;

    float targetWidth  = targetSize.width;
    float targetHeight = targetSize.height;

    float scaleFactor  = 0.0;
    float scaledWidth  = targetWidth;
    float scaledHeight = targetHeight;

    NSPoint thumbnailPoint = NSZeroPoint;

    if ( NSEqualSizes( imageSize, targetSize ) == NO )
    {

      float widthFactor  = targetWidth / width;
      float heightFactor = targetHeight / height;

      if ( widthFactor < heightFactor )
        scaleFactor = widthFactor;
      else
        scaleFactor = heightFactor;

      scaledWidth  = width  * scaleFactor;
      scaledHeight = height * scaleFactor;

      if ( widthFactor < heightFactor )
        thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;

      else if ( widthFactor > heightFactor )
        thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
    }
    newImage = [[NSImage alloc] initWithSize:targetSize];
    [newImage lockFocus];
      NSRect thumbnailRect;
      thumbnailRect.origin = thumbnailPoint;
      thumbnailRect.size.width = scaledWidth;
      thumbnailRect.size.height = scaledHeight;
      [sourceImage drawInRect: thumbnailRect
                     fromRect: NSZeroRect
                    operation: NSCompositeSourceOver
                     fraction: 1.0];
    [newImage unlockFocus];
  }
  return [newImage autorelease];
}
@end

答案 1 :(得分:1)

创建一个类似的类别方法,以便逐步压缩图像,直到达到所需的文件大小:

- (NSImage*) compressUnderMegaBytes:(CGFloat)megabytes {
  CGFloat compressionRatio = 1.0;

  NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:[self TIFFRepresentation]];
  NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:compressionRatio] forKey:NSImageCompressionFactor];
  NSData *compressedData = [imageRep representationUsingType:NSJPEGFileType properties:options];

  while ([compressedData length]>(megabytes*1024*1024)) {
    @autoreleasepool {
      compressionRatio = compressionRatio * 0.9;
      options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:compressionRatio] forKey:NSImageCompressionFactor];
      compressedData = [imageRep representationUsingType:NSJPEGFileType properties:options];

      // Safety check, 0.4 is a reasonable compression size, anything below will become blurry
      if (compressionRatio <= 0.4) {
        break;
      }
    }
  }
  return [[NSImage alloc] initWithData: compressedData];
}

然后您可以像这样使用它:

NSImage *compressedImage = [myImage compressUnderMegaBytes: 0.5];

答案 2 :(得分:0)

级别从0.0到1.0

func getImageQualityWithLevel(image: NSImage, level: CGFloat) -> NSImage {
    let _image = image
    var newRect: NSRect = NSMakeRect(0, 0, _image.size.width, _image.size.height)

    let imageSizeH: CGFloat = _image.size.height * level
    let imageSizeW: CGFloat = _image.size.width * level


    var newImage = NSImage(size: NSMakeSize(imageSizeW, imageSizeH))
    newImage.lockFocus()
    NSGraphicsContext.currentContext()?.imageInterpolation = NSImageInterpolation.Low


    _image.drawInRect(NSMakeRect(0, 0, imageSizeW, imageSizeH), fromRect: newRect, operation: NSCompositingOperation.CompositeSourceOver, fraction: 1)
    newImage.unlockFocus()


    return newImage
}