Par*_*waj 1 cocoa nsbezierpath swift
我想创建一个像素大小的点。我假设这样做的方法是使用 NSBezierPath 画一条线,起点等于终点(参见下面的代码),但这样做会产生一个完全空的窗口。
func drawPoint() {
let path = NSBezierPath()
NSColor.blue.set()
let fromPoint = NSMakePoint(CGFloat(100) , CGFloat(100))
let toPoint = NSMakePoint(CGFloat(100) , CGFloat(100))
path.move(to: fromPoint)
path.line(to: toPoint)
path.lineWidth = 1.0
path.stroke()
path.fill()
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将 toPoint 坐标从 100,100 更改为 101,101(或 100,100 以外的任何坐标集),则会显示蓝色形状。有谁知道为什么会这样?
我发现的另一个问题是,如果您将 toPoint 的坐标设置为等于(例如)101,101,那么它将创建一个长度为两个像素的正方形,但还会添加另一个像素长度的模糊层(请参见下图,放大为细节)。
然而,我想做的只是放置一个像素大小的单个蓝色小方块,没有模糊。有谁知道我该怎么做?
你有几个问题:
\n\n\n\n\n我想创建一个像素大小的点。
\n
你确定吗?如果您使用的是 Retina 显示屏怎么办?如果您正在绘制要在 600 dpi 激光打印机上打印的 PDF,该怎么办?
\n\n\n\n\n我假设这样做的方法是使用 NSBezierPath 画一条线,起点等于终点
\n
如果将属性设置为或lineWidth,则这是一种绘制 - 大小的点的方法。默认值为,这会导致空笔画。如果您设置为或,您将得到一个非空笔画。lineCap.round.squarelineCap.buttlineCap.round.square
\n\n\nRun Code Online (Sandbox Code Playgroud)\nlet fromPoint = NSMakePoint(CGFloat(100) , CGFloat(100))\nlet toPoint = NSMakePoint(CGFloat(100) , CGFloat(100))\npath.move(to: fromPoint)\npath.line(to: toPoint)\n
您需要了解坐标网格与像素的关系:
\n\n在非视网膜屏幕上,整数坐标默认位于像素边缘,而不是像素中心。沿着整数坐标的笔划跨越像素之间的边界,因此(使用lineWidth = 1.0)您会得到多个部分填充的像素。要填充单个像素,您需要使用以.5(像素中心)结束的坐标。
在视网膜屏幕上,整数和半整数坐标默认位于像素的边缘,而不是像素的中心。沿着整数或半整数坐标的笔划跨越像素之间的边界。使用 时lineWidth = 1.0,两侧的像素都被完全填充。如果只想填充单个像素,则需要使用.25以 or.75和 a lineWidthof结尾的坐标0.5。
在未缩放的 PDF 环境中,alineWidth名义上1.0对应于 1/72 英寸,填充像素的数量取决于输出设备。
\n\n\nRun Code Online (Sandbox Code Playgroud)\npath.lineWidth = 1.0\n
这只能在非 Retina 屏幕上为您提供 \xe2\x80\x9ca 单个像素大小的点\xe2\x80\x9d(或者如果您缩放了图形上下文)。如果您确实想要在视网膜屏幕上显示单个像素点,则需要调整它。但你最好坚持使用点而不是像素。
\n\n综上所述,以下是创建和描边NSBezierPath以填充一个像素的方法:
import AppKit\n\nfunc dotImage() -> CGImage {\n let gc = CGContext(data: nil, width: 20, height: 20, bitsPerComponent: 8, bytesPerRow: 0, space: CGColorSpace(name: CGColorSpace.sRGB)!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!\n let nsGc = NSGraphicsContext(cgContext: gc, flipped: false)\n NSGraphicsContext.current = nsGc; do {\n\n let path = NSBezierPath()\n path.move(to: .init(x: 10.5, y: 10.5))\n path.line(to: .init(x: 10.5, y: 10.5))\n path.lineWidth = 1\n path.lineCapStyle = .round\n NSColor.blue.set()\n path.stroke()\n\n }; NSGraphicsContext.current = nil\n return gc.makeImage()!\n}\n\nlet image = dotImage()\nRun Code Online (Sandbox Code Playgroud)\n\n结果:
\n\n\n\n但是,您可能更喜欢直接填充矩形:
\n\nfunc dotImage2() -> CGImage {\n let gc = CGContext(data: nil, width: 20, height: 20, bitsPerComponent: 8, bytesPerRow: 0, space: CGColorSpace(name: CGColorSpace.sRGB)!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!\n let nsGc = NSGraphicsContext(cgContext: gc, flipped: false)\n NSGraphicsContext.current = nsGc; do {\n\n NSColor.blue.set()\n CGRect(x: 10, y: 10, width: 1, height: 1).fill()\n\n }; NSGraphicsContext.current = nil\n return gc.makeImage()!\n}\n\nlet image2 = dotImage2()\nRun Code Online (Sandbox Code Playgroud)\n\n结果:
\n\n\n