【问题标题】:NSBezierPath AddClip to mask NSImage - Size issueNSBezierPath AddClip 以掩盖 NSImage - 大小问题
【发布时间】:2018-12-31 21:52:57
【问题描述】:

在 macOS (OSX) 桌面应用程序上,我使用 NSBezierPath 绘制一个看起来像这样的随机闭合形状。

如您所见,虚线显示了绘制的闭合路径。

现在我正在尝试按照此路径提取蒙版图像。 但我得到了图像的一小部分。蒙版图像似乎正确地从 BezierPath 获取轮廓。但是尺寸是个问题。

这是返回蒙版/剪辑图像的方法。 此图的 sourceImage.size - 1021 * 1031

  - (NSImage *)imageByApplyingClippingBezierPath:(NSImage *)sourceImage
                                bezierPath:(NSBezierPath *)bezierPath
                                  newFrame:(NSRect)newFrame
  {
    NSImage* newImage = [[NSImage alloc] initWithSize:newFrame.size];
    NSBitmapImageRep* rep = [[NSBitmapImageRep alloc]
                             initWithBitmapDataPlanes:NULL
                             pixelsWide:newFrame.size.width
                             pixelsHigh:newFrame.size.height
                             bitsPerSample:8
                             samplesPerPixel:4
                             hasAlpha:YES
                             isPlanar:NO
                             colorSpaceName:NSCalibratedRGBColorSpace
                             bytesPerRow:0
                             bitsPerPixel:0];

    [newImage addRepresentation:rep];

    [newImage lockFocus];

    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
    CGContextSaveGState(context);

    [bezierPath addClip];

    NSRect targetFrame = NSMakeRect(0, 0, newFrame.size.width, newFrame.size.height);
    [sourceImage drawInRect:targetFrame];

    [newImage unlockFocus];

    CGContextRestoreGState(context);

    return newImage;
}

如何获得由 BezierPath 勾勒出的完美尺寸的图像? 任何提示将不胜感激!

更新

只是澄清一下,我是如何绘制图像的。 我得到了贝塞尔路径的矩形边界和像这样裁剪的矩形图像。

CGRect bezierBounds = CGPathGetPathBoundingBox([self.smartLassoWavyBezierPath quartzPath]);
 NSRect targetFrame = NSMakeRect(0, 0, bezierBounds.size.width, bezierBounds.size.height);
 NSImage *targetImage = [[NSImage alloc initWithSize:targetFrame.size];
[targetImage lockFocus];
[self.view.originalLoadImageOnCanvas 
drawInRect:targetFrame fromRect:bezierBounds operation:NSCompositeCopy 
 fraction:1.0f];
[targetImage unlockFocus];

【问题讨论】:

  • 你是如何绘制图像的?
  • @Willeke 我更新了答案 - 向您展示代码。我得到了从 BezierPath 的边界裁剪的矩形图像。然后我将此矩形图像发送到“imageByApplyingClippingBezierPath”函数。
  • 如何绘制要在其上绘制的图像?是否按比例缩放?
  • @Willeke - 不知道你的意思是什么?能具体点吗?
  • 当你在一张图片上绘制路径时,如何显示这张图片?我的意思是建筑物问题中的第一张图片。看起来屏幕上的图像按 40% 缩放,而蒙版按 100% 缩放。

标签: macos cocoa mask nsimage nsbezierpath


【解决方案1】:

对于 Swift 5;

func imageByApplyingClippingBezierPath(source: NSImage, path: NSBezierPath, frame: NSRect) -> NSImage? {
    let new = NSImage(size: frame.size)
    guard let rep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(frame.size.width), pixelsHigh: Int(frame.size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSColorSpaceName.calibratedRGB, bitmapFormat: .alphaFirst, bytesPerRow: 0, bitsPerPixel: 0) else { return nil}

    new.addRepresentation(rep)
    new.lockFocus()

    let context = NSGraphicsContext.current?.cgContext
    context?.saveGState()
    path.addClip()

    let targetFrame = NSRect(x: 0, y: 0, width: Int(frame.size.width), height: Int(frame.size.height))

    source.draw(in: targetFrame)
    new.unlockFocus()
    context?.restoreGState()

    return new
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    • 1970-01-01
    相关资源
    最近更新 更多