我想在NSImage上添加十字,下面是我的代码:
-(NSSize)convertPixelSizeToPointSize:(NSSize)px
{
CGFloat displayScale = [[NSScreen mainScreen] backingScaleFactor];
NSSize res;
res.width = px.width / displayScale;
res.height = px.height / displayScale;
return res;
}
-(void)awakeFromNib
{
CGFloat scale = [[NSScreen mainScreen] backingScaleFactor];
NSLog(@"backingScaleFactor : %f",scale);
NSImage *img = [[[NSImage alloc]initWithContentsOfFile:@"/Users/support/Pictures/cat.JPG"] autorelease];
NSBitmapImageRep *imgRep = [NSBitmapImageRep imageRepWithData:[img TIFFRepresentation]];
NSSize imgPixelSize = NSMakeSize([imgRep pixelsWide],[imgRep pixelsHigh]);
NSSize imgPointSize = [self convertPixelSizeToPointSize:imgPixelSize];
[img setSize:imgPointSize];
NSLog(@"imgPixelSize.width: %f , imgPixelSize.height:%f",imgPixelSize.width,imgPixelSize.height);
NSLog(@"imgPointSize.width: %f , imgPointSize.height:%f",imgPointSize.width,imgPointSize.height);
[img lockFocus];
NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
[trans scaleBy:1.0 / scale];
[trans set];
NSBezierPath *path = [NSBezierPath bezierPath];
[[NSColor redColor] setStroke];
[path moveToPoint:NSMakePoint(0.0, 0.0)];
[path lineToPoint:NSMakePoint(imgPixelSize.width, imgPixelSize.height)];
[path moveToPoint:NSMakePoint(0.0, imgPixelSize.height)];
[path lineToPoint:NSMakePoint(imgPixelSize.width, 0.0)];
[path setLineWidth:1];
[path stroke];
[img unlockFocus];
[imageView setImage:img];
imgRep = [NSBitmapImageRep imageRepWithData:[img TIFFRepresentation]];
NSData *imageData = [imgRep representationUsingType:NSJPEGFileType properties:nil];
[imageData writeToFile:@"/Users/support/Pictures/11-5.JPG" atomically:NO];
}在非视网膜显示器上,结果是:

并显示控制台:
2012-07-06 00:53:09.889 RetinaTest[8074:403] backingScaleFactor : 1.000000
2012-07-06 00:53:09.901 RetinaTest[8074:403] imgPixelSize.width: 515.000000 , imgPixelSize.height:600.000000
2012-07-06 00:53:09.902 RetinaTest[8074:403] imgPointSize.width: 515.000000 , imgPointSize.height:600.000000但在视网膜显示屏上(我没有使用真正的视网膜显示屏,而是hidpi模式):

控制台:
2012-07-06 00:56:05.071 RetinaTest[8113:403] backingScaleFactor : 2.000000
2012-07-06 00:56:05.083 RetinaTest[8113:403] imgPixelSize.width: 515.000000 , imgPixelSize.height:600.000000
2012-07-06 00:56:05.084 RetinaTest[8113:403] imgPointSize.width: 257.500000 , imgPointSize.height:300.000000如果我省略这几行:
NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
[trans scaleBy:1.0 / scale];
[trans set];

但是,如果我将NSAffineTransform scaleBy更改为1.0,结果是正确的
NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
[trans scaleBy:1.0];
[trans set];

控制台:
2012-07-06 01:01:03.420 RetinaTest[8126:403] backingScaleFactor : 2.000000
2012-07-06 01:01:03.431 RetinaTest[8126:403] imgPixelSize.width: 515.000000 , imgPixelSize.height:600.000000
2012-07-06 01:01:03.432 RetinaTest[8126:403] imgPointSize.width: 257.500000 , imgPointSize.height:300.000000有谁能解释一下吗?hidpi模式与视网膜显示是否不同?
发布于 2012-07-09 20:40:53
我想我已经找到答案了。如果NSAffineTransform设置为NSImage的上下文,它会将坐标系转换为像素维度,即2 x点维度。即使它像这样是空的:
NSAffineTransform *trans = [[[NSAffineTransform alloc] init] autorelease];
[trans set];我不知道这是一个bug,还是它的工作方式。
发布于 2013-01-25 06:46:35
重置转换是没有问题的(参考您自己的答案)。使用hidpi可以使默认转换成为让大多数高级代码按原样正常工作的转换。重置为标识变换将撤消此操作,以便将坐标系1:1与像素对齐。
不过,人们应该很少需要这样做。简化您的代码以删除图像表示和转换更改会得到以下结果:
NSImage *img = [[[NSImage alloc]initWithContentsOfFile:@"/Users/support/Pictures/cat.JPG"] autorelease];
NSSize size = img.size;
NSBezierPath *path = [NSBezierPath bezierPath];
[[NSColor redColor] setStroke];
[path moveToPoint:NSMakePoint(0.0, 0.0)];
[path lineToPoint:NSMakePoint(size.width, size.height)];
[path moveToPoint:NSMakePoint(0.0, size.height)];
[path lineToPoint:NSMakePoint(size.width, 0.0)];
[path setLineWidth:1];
[path stroke];
[img unlockFocus];
[imageView setImage:img];
...这应该是可行的,除非线条将改为2个物理像素宽(但当然与常规屏幕上的图像的宽度相似)。尝试这个更简单的特殊情况来解决这个问题:
[path setLineWidth:(img.scale > 1) ? 0.5 : 1.0];https://stackoverflow.com/questions/11350070
复制相似问题