首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSImage不能扩展

NSImage不能扩展
EN

Stack Overflow用户
提问于 2012-10-03 04:06:05
回答 2查看 5.2K关注 0票数 8

我正在开发一个快速的应用程序,在其中我有一个方法,可以将@2x图像重新缩放为常规图像。问题是它没有:(

为什么?

代码语言:javascript
复制
-(BOOL)createNormalImage:(NSString*)inputRetinaImagePath {

    NSImage *inputRetinaImage = [[NSImage alloc] initWithContentsOfFile:inputRetinaImagePath];



    NSSize size = NSZeroSize;
    size.width = inputRetinaImage.size.width*0.5;
    size.height = inputRetinaImage.size.height*0.5;

    [inputRetinaImage setSize:size];


    NSLog(@"%f",inputRetinaImage.size.height);


    NSBitmapImageRep *imgRep = [[inputRetinaImage representations] objectAtIndex: 0];

    NSData *data = [imgRep representationUsingType: NSPNGFileType properties: nil];

    NSString *outputFilePath = [[inputRetinaImagePath substringToIndex:inputRetinaImagePath.length - 7] stringByAppendingString:@".png"];

    NSLog([@"Normal version file path: " stringByAppendingString:outputFilePath]);
    [data writeToFile:outputFilePath atomically: NO];
    return true;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-21 03:18:10

您必须非常小心NSImage的大小属性。它不一定是指bitmapRepresentation的像素大小,例如它可以指显示的大小。NSImage可以具有多个用于不同输出大小的bitmapRepresentations。

同样,更改NSImage的大小属性也不会改变bitmapRepresentations

因此,您需要做的是计算出您希望输出图像的大小,然后使用源NSImage中的bitmapRepresentation以该大小绘制一个新图像。

获得这个大小取决于你如何获得你的输入图像以及你对它的了解。例如,如果你确信你的输入图像只有一个类别,你可以使用这种类型的东西(作为NSImage上的一个bitmapImageRep )

代码语言:javascript
复制
  - (NSSize) pixelSize
{
    NSBitmapImageRep* bitmap = [[self representations] objectAtIndex:0];
    return NSMakeSize(bitmap.pixelsWide,bitmap.pixelsHigh);
}

即使你有一些bitmapImageReps,第一个应该是最大的一个,如果这是你创建视网膜图像的大小,它应该是你想要的视网膜大小。

当你计算出你的最终尺寸后,你可以制作图像:

代码语言:javascript
复制
- (NSImage*) resizeImage:(NSImage*)sourceImage size:(NSSize)size
{

    NSRect targetFrame = NSMakeRect(0, 0, size.width, size.height);     
    NSImage* targetImage = nil;
    NSImageRep *sourceImageRep =
    [sourceImage bestRepresentationForRect:targetFrame
                                   context:nil
                                     hints:nil];

    targetImage = [[NSImage alloc] initWithSize:size];

    [targetImage lockFocus];
    [sourceImageRep drawInRect: targetFrame];
    [targetImage unlockFocus];

return targetImage; 

}

更新

这是NSImage上像素大小获取类别的一个更精致的版本...让我们假设图像没有任何信息,它有多少个imageReps,是否有任何bitmapImageReps……这将返回它能找到的最大像素尺寸。如果它找不到bitMapImageRep像素尺寸,它将使用它能获得的任何其他尺寸,这些尺寸最有可能是边界框尺寸(由eps和pdf使用)。

NSImage+PixelSize.h

代码语言:javascript
复制
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>

@interface NSImage (PixelSize)

- (NSInteger) pixelsWide;
- (NSInteger) pixelsHigh;
- (NSSize) pixelSize;

@end

NSImage+PixelSize.m

代码语言:javascript
复制
#import "NSImage+PixelSize.h"

@implementation NSImage (Extensions)

- (NSInteger) pixelsWide
{
    /*
     returns the pixel width of NSImage.
     Selects the largest bitmapRep by preference
     If there is no bitmapRep returns largest size reported by any imageRep.
     */
    NSInteger result = 0;
    NSInteger bitmapResult = 0;

    for (NSImageRep* imageRep in [self representations]) {
        if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
            if (imageRep.pixelsWide > bitmapResult)
                bitmapResult = imageRep.pixelsWide;
        } else {
            if (imageRep.pixelsWide > result)
                result = imageRep.pixelsWide;
        }
    }
    if (bitmapResult) result = bitmapResult;
    return result;

}

- (NSInteger) pixelsHigh
{
    /*
     returns the pixel height of NSImage.
     Selects the largest bitmapRep by preference
     If there is no bitmapRep returns largest size reported by any imageRep.
     */
    NSInteger result = 0;
    NSInteger bitmapResult = 0;

    for (NSImageRep* imageRep in [self representations]) {
        if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
            if (imageRep.pixelsHigh > bitmapResult)
                bitmapResult = imageRep.pixelsHigh;
        } else {
            if (imageRep.pixelsHigh > result)
                result = imageRep.pixelsHigh;
        }
    }
    if (bitmapResult) result = bitmapResult;
    return result;
}

- (NSSize) pixelSize
{
    return NSMakeSize(self.pixelsWide,self.pixelsHigh);
}

@end

您可以在当前文件中使用#import "NSImage+PixelSize.h"命令以使其可访问。

有了这个图像类别和resize:方法,您可以修改您的方法,如下所示:

代码语言:javascript
复制
//size.width = inputRetinaImage.size.width*0.5;
//size.height = inputRetinaImage.size.height*0.5;
size.width  = inputRetinaImage.pixelsWide*0.5;
size.height = inputRetinaImage.pixelsHigh*0.5;

//[inputRetinaImage setSize:size];
NSImage* outputImage = [self resizeImage:inputRetinaImage size:size];

//NSBitmapImageRep *imgRep = [[inputRetinaImage representations] objectAtIndex: 0];
NSBitmapImageRep *imgRep = [[outputImage representations] objectAtIndex: 0];

这应该会帮你解决问题(但书:我还没有在你的代码上测试过它)

票数 11
EN

Stack Overflow用户

发布于 2012-12-21 04:24:14

我修改了我用来为你缩小图像的脚本:)

代码语言:javascript
复制
-(BOOL)createNormalImage:(NSString*)inputRetinaImagePath {

    NSImage *inputRetinaImage = [[NSImage alloc] initWithContentsOfFile:inputRetinaImagePath];

    //determine new size
    NSBitmapImageRep* bitmapImageRep = [[inputRetinaImage representations] objectAtIndex:0];
    NSSize size = NSMakeSize(bitmapImageRep.pixelsWide * 0.5,bitmapImageRep.pixelsHigh * 0.5);

    NSLog(@"size = %@", NSStringFromSize(size));

    //get CGImageRef
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)[inputRetinaImage TIFFRepresentation], NULL);
    CGImageRef oldImageRef =  CGImageSourceCreateImageAtIndex(source, 0, NULL);
    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(oldImageRef);
    if (alphaInfo == kCGImageAlphaNone) alphaInfo = kCGImageAlphaNoneSkipLast;

    // Build a bitmap context
    CGContextRef bitmap = CGBitmapContextCreate(NULL, size.width, size.height, 8, 4 * size.width, CGImageGetColorSpace(oldImageRef), alphaInfo);

    // Draw into the context, this scales the image
    CGContextDrawImage(bitmap, CGRectMake(0, 0, size.width, size.height), oldImageRef);

    // Get an image from the context
    CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);

    //this does not work in my test.
    NSString *outputFilePath = [[inputRetinaImagePath substringToIndex:inputRetinaImagePath.length - 7] stringByAppendingString:@".png"];

    //but this does!
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* docsDirectory = [paths objectAtIndex:0];
    NSString *newfileName = [docsDirectory stringByAppendingFormat:@"/%@", [outputFilePath lastPathComponent]];

    CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:newfileName];
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL);
    CGImageDestinationAddImage(destination, newImageRef, nil);

    if (!CGImageDestinationFinalize(destination)) {
        NSLog(@"Failed to write image to %@", newfileName);
    }

    CFRelease(destination);

    return true;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12697465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档