我正在编写一个从所选区域进行屏幕拍摄的应用程序。我知道在Mac上可以用 cmd + 命令 + 4 完成,但我需要的功能是记住最后的大小和采取的地区的位置。我需要做很多相同大小区域的屏幕。
所以..当调用一个拍摄区域拍摄的功能时,屏幕应该变得更暗,透明孔,代表区域进行屏幕拍摄。
我实现了这个目的,通过显示一个新的全屏幕窗口半透明,内部有一个洞。
洞的代码如下:
class FullTransparentRect: NSView {
var firstMouseDownPoint: NSPoint = NSZeroPoint
let myLayer = CAShapeLayer()
let borderSize: CGFloat = 2.0
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
self.layer?.backgroundColor = NSColor.lightGray.cgColor
drawHole()
}
func drawHole() {
let path = CGMutablePath()
// Make hole in view's overlay
path.addRect((self.superview?.bounds)!)
path.addRect(NSRect(x: self.frame.origin.x + borderSize,
y: self.frame.origin.y + borderSize,
width: self.frame.size.width - (borderSize * 2),
height: self.frame.size.height - (borderSize * 2)))
myLayer.path = path
myLayer.fillRule = kCAFillRuleEvenOdd
self.superview?.layer?.mask = myLayer
self.layer?.borderColor = NSColor.lightGray.cgColor
self.layer?.borderWidth = borderSize
}
//Decrapted for now
func getHole() -> CGImage {
var rect = self.convert((self.layer?.frame)!, to: self.window?.contentView)
// print("rect \(rect)")
let displayID = CGMainDisplayID()
return CGDisplayCreateImage(displayID, rect: rect)!
}
func setWidth(width: CGFloat) {
var f = self.frame;
f.size.width = width;
self.frame = f;
}
func setHeight(height: CGFloat) {
var f = self.frame;
f.size.height = height;
self.frame = f;
}
override func mouseDown(with event: NSEvent) {
firstMouseDownPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))!
print("Mouse on: \(event.locationInWindow)")
print("Mouse click on : \(firstMouseDownPoint)")
}
override func mouseDragged(with event: NSEvent) {
let newPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))!
let offset = NSPoint(x: newPoint.x - firstMouseDownPoint.x, y: newPoint.y - firstMouseDownPoint.y)
let origin = self.frame.origin
let size = self.frame.size
self.frame = NSRect(x: origin.x + offset.x, y: origin.y + offset.y, width: size.width, height: size.height)
drawHole()
}
}
我遇到的问题是坐标的转换。
在Swift中,坐标(0.0)表示左下角,屏幕左上角。因此,即使我试图转换它也不起作用。我还有一个我需要的其他部分的屏幕。当我的洞位于底部时,CGDisplayCreateImage拍摄的屏幕位于顶部,反之亦然。
@objc func getScreenshotRect() {
var rect = transparentHoleView?.frame
print("Original hole is \(rect)")
rect = screenSemiTransparentController?.view.convert(rect!, to: nil)
print("converted is \(rect)")
rect = screenSemiTransparentController?.view.window?.convertToScreen(rect!)
print(" to screen converted is \(rect)")
let userInfo = ["image": ScreenService.sharedInstance.doRegionScreen(rect!)]
NotificationCenter.default.post(name: .imageNotification, object: nil, userInfo: userInfo)
}
public func doRegionScreen(_ region: CGRect) -> CGImage {
let displayID = CGMainDisplayID()
return CGDisplayCreateImage(displayID, rect: region)!
}
我做错了什么?