【发布时间】:2012-11-24 20:56:41
【问题描述】:
我正在尝试显示一个简单的 NSImageView,它的图像居中而不像这样缩放:
就像 iOS 设置 UIView 的 contentMode = UIViewContentModeCenter
所以我尝试了所有 NSImageScaling 值,这是我选择 NSScaleNone
时得到的我真的不明白发生了什么:-/
【问题讨论】:
标签: cocoa nsimageview
我正在尝试显示一个简单的 NSImageView,它的图像居中而不像这样缩放:
就像 iOS 设置 UIView 的 contentMode = UIViewContentModeCenter
所以我尝试了所有 NSImageScaling 值,这是我选择 NSScaleNone
时得到的我真的不明白发生了什么:-/
【问题讨论】:
标签: cocoa nsimageview
您可以手动生成正确大小和内容的图像,并将其设置为 NSImageView 的图像,这样 NSImageView 就不需要做任何事情了。
NSImage *newImg = [self resizeImage:sourceImage size:newSize];
[aNSImageView setImage:newImg];
以下函数调整图像大小以适应新大小,同时保持纵横比不变。如果图像小于新尺寸,则将其放大并用新框架填充。如果图像大于新尺寸,则缩小尺寸,并用新框架填充
- (NSImage*) resizeImage:(NSImage*)sourceImage size:(NSSize)size{
NSRect targetFrame = NSMakeRect(0, 0, size.width, size.height);
NSImage* targetImage = [[NSImage alloc] initWithSize:size];
NSSize sourceSize = [sourceImage size];
float ratioH = size.height/ sourceSize.height;
float ratioW = size.width / sourceSize.width;
NSRect cropRect = NSZeroRect;
if (ratioH >= ratioW) {
cropRect.size.width = floor (size.width / ratioH);
cropRect.size.height = sourceSize.height;
} else {
cropRect.size.width = sourceSize.width;
cropRect.size.height = floor(size.height / ratioW);
}
cropRect.origin.x = floor( (sourceSize.width - cropRect.size.width)/2 );
cropRect.origin.y = floor( (sourceSize.height - cropRect.size.height)/2 );
[targetImage lockFocus];
[sourceImage drawInRect:targetFrame
fromRect:cropRect //portion of source image to draw
operation:NSCompositeCopy //compositing operation
fraction:1.0 //alpha (transparency) value
respectFlipped:YES //coordinate system
hints:@{NSImageHintInterpolation:
[NSNumber numberWithInt:NSImageInterpolationLow]}];
[targetImage unlockFocus];
return targetImage;}
【讨论】:
这是一个很棒的 NSImage 类别:NSImage+ContentMode
它支持 iOS 中的内容模式,效果很好。
【讨论】:
UIGraphicsGetCurrentContext() 替换为 [NSGraphicsContext currentContext].CGContext。在 High Sierra 在 CABasicAnimation 期间弄乱 NSImageView 内容后特别有用
if (contentMode == UIViewContentModeScaleAspectFit) { CGSize imageSize = CGSizeMake(self.size.width, self.size.height); CGSize containerSize = rect.size; CGFloat widthRaport = containerSize.width/imageSize.width; CGFloat heightRaport = containerSize.height/imageSize.height; CGFloat scale = MIN(widthRaport, heightRaport); imageSize.width = imageSize.width * scale; imageSize.height = imageSize.height * scale;
将图像缩放属性设置为 NSImageScaleAxesIndependently,它将缩放图像以填充矩形。这不会保留纵横比。
【讨论】:
@Shagru 答案的 Swift 版本(没有提示)
func resizeImage(_ sourceImage:NSImage, size:CGSize) -> NSImage
{
let targetFrame = CGRect(origin: CGPoint.zero, size: size);
let targetImage = NSImage.init(size: size)
let sourceSize = sourceImage.size
let ratioH = size.height / sourceSize.height;
let ratioW = size.width / sourceSize.width;
var cropRect = CGRect.zero;
if (ratioH >= ratioW) {
cropRect.size.width = floor (size.width / ratioH);
cropRect.size.height = sourceSize.height;
} else {
cropRect.size.width = sourceSize.width;
cropRect.size.height = floor(size.height / ratioW);
}
cropRect.origin.x = floor( (sourceSize.width - cropRect.size.width)/2 );
cropRect.origin.y = floor( (sourceSize.height - cropRect.size.height)/2 );
targetImage.lockFocus()
sourceImage.draw(in: targetFrame, from: cropRect, operation: .copy, fraction: 1.0, respectFlipped: true, hints: nil )
targetImage.unlockFocus()
return targetImage;
}
【讨论】: