Bạn phải rất cảnh giác với các thuộc tính kích thước của một NSImage. Nó không nhất thiết phải đề cập đến kích thước pixel của bitmapRepresentation, nó có thể tham khảo các kích thước hiển thị ví dụ. một NSImage có thể có một số bitmapRepresentations để sử dụng với kích thước đầu ra khác nhau.
Tương tự như vậy, thay đổi thuộc tính kích thước của một NSImage không có gì để làm thay đổi bitmapRepresentations
Vậy điều gì bạn cần làm là làm việc ra kích thước bạn muốn hình ảnh đầu ra của bạn được, và sau đó vẽ một hình ảnh mới ở kích thước đó bằng cách sử dụng một bitmapRepresentation từ nguồn NSImage.
Việc nhận kích thước đó phụ thuộc vào cách bạn đã có được hình ảnh đầu vào và những gì bạn biết về nó. Ví dụ, nếu bạn tự tin rằng hình ảnh đầu vào của bạn chỉ có một bitmapImageRep bạn có thể sử dụng loại điều (như một phạm trù trên NSImage)
- (NSSize) pixelSize
{
NSBitmapImageRep* bitmap = [[self representations] objectAtIndex:0];
return NSMakeSize(bitmap.pixelsWide,bitmap.pixelsHigh);
}
Thậm chí nếu bạn có một số bitmapImageReps, là đầu tiên nên lớn nhất, và nếu đó là kích thước mà hình ảnh Retina của bạn đã được tạo ra tại, nó phải là kích thước Retina bạn đang sau.
Khi bạn đã tìm ra kích thước cuối cùng của bạn, bạn có thể làm cho hình ảnh:
- (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;
}
cập nhật
Đây là một phiên bản phức tạp hơn của một pixel-size- nhận được danh mục trên NSImage ... hãy giả sử không có gì về hình ảnh, có bao nhiêu imageRep mà nó có, cho dù có bất kỳ bitmapImageReps ... điều này sẽ trả về kích thước pixel lớn nhất i t có thể tìm thấy. Nếu nó không thể tìm thấy kích thước pixel bitMapImageRep, nó sẽ sử dụng bất kỳ thứ gì khác mà nó có thể nhận được, mà rất có thể sẽ là giới hạn kích thước hộp (được sử dụng bởi eps và pdf).
NSImage + PixelSize.h
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
@interface NSImage (PixelSize)
- (NSInteger) pixelsWide;
- (NSInteger) pixelsHigh;
- (NSSize) pixelSize;
@end
NSImage + PixelSize.m
#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
Bạn sẽ #import "NSImage+PixelSize.h"
trong tập tin hiện tại của bạn để làm cho nó dễ tiếp cận.
Với điều này loại hình ảnh và thay đổi kích cỡ: phương pháp, bạn sẽ thay đổi phương pháp của bạn như sau:
//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];
Đó nên sửa chữa điều cho bạn (điều kiện: Tôi đã không thử nghiệm nó trên mã của bạn)
Dưới đây là một giải pháp mà * sẽ không * làm việc: 'setScalesWhenResized:'.Đó từng là cách bạn đã làm điều này, nhưng nó không được chấp nhận từ Snow Leopard và không hoạt động như Lion. –
Bạn không thể chỉ vẽ nó trong một rect nhỏ hơn? Hoặc chuyển NSAffineTransform làm gợi ý? –
@RamyAlZuhouri: Có vẻ như ứng dụng này có nghĩa là giảm độ phân giải của hình ảnh và lưu kết quả, để tạo nội dung ở 2x và sản xuất 1x nội dung từ cùng một. –