2

这是我到目前为止所得到的:

NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:
               [file.image TIFFRepresentation]];
// Resize image to 200x200
CGFloat maxSize = 200.0;
NSSize imageSize = imageRep.size;
if (imageSize.height>maxSize || imageSize.width>maxSize) {
    // Find the aspect ratio
    CGFloat aspectRatio = imageSize.height/imageSize.width;
    CGSize newImageSize;
    if (aspectRatio > 1.0) {
        newImageSize = CGSizeMake(maxSize / aspectRatio, maxSize);
    } else if (aspectRatio < 1.0) {
        newImageSize = CGSizeMake(maxSize, maxSize * aspectRatio);
    } else {
        newImageSize = CGSizeMake(maxSize, maxSize);
    }
    [imageRep setSize:NSSizeFromCGSize(newImageSize)];
}


NSData *imageData = [imageRep representationUsingType:NSPNGFileType properties:nil];
NSString *outputFilePath = [@"~/Desktop/output.png" stringByExpandingTildeInPath];
[imageData writeToFile:outputFilePath atomically:NO];

该代码假定 200x200 PNG 将小于 128K,这是我的大小限制。200x200 足够大,但如果可能的话,我更愿意将尺寸最大化。

这是我的两个问题:

  1. 代码不起作用。我检查了导出文件的大小,它与原始文件大小相同。
  2. 有没有办法在我导出之前预测输出文件的大小,所以我可以最大化尺寸但仍然得到小于 128K 的图像?

这是工作代码。它相当草率,可能会使用一些优化,但此时它运行得足够快,我不在乎。它对大多数图片进行了 100 倍以上的迭代,并且以毫秒为单位结束。此外,此方法是在 上的类别中声明的NSImage

- (NSData *)resizeImageWithBitSize:(NSInteger)size 
                      andImageType:(NSBitmapImageFileType)fileType {

    CGFloat maxSize = 500.0;
    NSSize originalImageSize = self.size;
    NSSize newImageSize;
    NSData *returnImageData;
    NSInteger imageIsTooBig = 1000;

    while (imageIsTooBig > 0) {
            if (originalImageSize.height>maxSize || originalImageSize.width>maxSize) {
            // Find the aspect ratio
            CGFloat aspectRatio = originalImageSize.height/originalImageSize.width;
            if (aspectRatio > 1.0) {
                newImageSize = NSMakeSize(maxSize / aspectRatio, maxSize);
            } else if (aspectRatio < 1.0) {
                newImageSize = NSMakeSize(maxSize, maxSize * aspectRatio);
            } else {
                newImageSize = NSMakeSize(maxSize, maxSize);
            }
        } else {
            newImageSize = originalImageSize;
        }

        NSImage *resizedImage = [[NSImage alloc] initWithSize:newImageSize];

        [resizedImage lockFocus];
        [self drawInRect:NSMakeRect(0, 0, newImageSize.width, newImageSize.height)
                fromRect: NSMakeRect(0, 0, originalImageSize.width, originalImageSize.height) 
               operation: NSCompositeSourceOver 
                fraction: 1.0];
        [resizedImage unlockFocus];

        NSData *tiffData = [resizedImage TIFFRepresentation];
        [resizedImage release];

        NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:tiffData];
        NSDictionary *imagePropDict = [NSDictionary 
                                       dictionaryWithObject:[NSNumber numberWithFloat:0.85] 
                                                     forKey:NSImageCompressionFactor];

        returnImageData = [imageRep representationUsingType:fileType properties:imagePropDict];
        [imageRep release];

        if ([returnImageData length] > size) {
            maxSize = maxSize * 0.99;
            imageIsTooBig--;
        } else {
            imageIsTooBig = 0;
        }

    }

    return returnImageData;
}
4

2 回答 2

0

[imageData length]应该给你 NSData 内容的长度,据我所知,这是写入磁盘时的最终文件大小。这应该让您有机会在实际编写文件之前最大化文件的大小。

至于为什么图像没有缩小或增长,根据setSize 的文档

图像表示的大小与图像数据的物理尺寸相结合,决定了图像的分辨率。

因此,通过设置大小而不改变分辨率,您可能不会修改任何像素,而只是解释像素的方式。

于 2009-10-13T22:59:51.980 回答
0

为 1。

正如另一张海报所提到的, setSize 只改变图像的显示大小,而不是底层图像文件的实际像素数据。

要调整大小,您可能希望将源图像重绘到另一个 NSImageRep 上,然后将其写入文件。

此博客文章包含一些有关如何以这种方式调整大小的示例代码。

如何调整 NSImage 的大小

对于 2。

我认为你不能至少在内存中创建对象并检查图像的长度。实际使用的字节数取决于图像类型。带有 ARGB 的位图很容易预测它们的大小,但 PNG 和 JPEG 会更难预测。

于 2009-10-14T05:00:28.420 回答