Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

swift - NSImage Getting Resized when I draw Text on it

I have the following code to draw a text over an NSImage. But the resulting image is getting resized to smaller one when I save it to disk.

What i'm i doing wrong? Please advice

func drawText(image :NSImage) ->NSImage
{
    let text = "Sample Text"
    let font = NSFont.boldSystemFont(ofSize: 18)
    let imageRect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)

    let textRect = CGRect(x: 5, y: 5, width: image.size.width - 5, height: image.size.height - 5)
    let textStyle = NSMutableParagraphStyle.default().mutableCopy() as! NSMutableParagraphStyle
    let textFontAttributes = [
        NSFontAttributeName: font,
        NSForegroundColorAttributeName: NSColor.white,
        NSParagraphStyleAttributeName: textStyle
    ]

    let im:NSImage = NSImage(size: image.size)

    let rep:NSBitmapImageRep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(image.size.width), pixelsHigh: Int(image.size.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: NSCalibratedRGBColorSpace, bytesPerRow: 0, bitsPerPixel: 0)!

    im.addRepresentation(rep)

    im.lockFocus()

    image.draw(in: imageRect)
    text.draw(in: textRect, withAttributes: textFontAttributes)

    im.unlockFocus()

    return im
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is a different approach using a temporary NSView to draw the image and the text and cache the result in a new image (code is Swift 4). The benefit it you don't need to deal with pixels

class ImageView : NSView  {

    var image : NSImage
    var text : String

    init(image: NSImage, text: String)
    {
        self.image = image
        self.text = text
        super.init(frame: NSRect(origin: NSZeroPoint, size: image.size))
    }

    required init?(coder decoder: NSCoder) { fatalError() }

    override func draw(_ dirtyRect: NSRect) {
        let font = NSFont.boldSystemFont(ofSize: 18)
        let textRect = CGRect(x: 5, y: 5, width: image.size.width - 5, height: image.size.height - 5)
        image.draw(in: dirtyRect)
        text.draw(in: textRect, withAttributes: [.font: font, .foregroundColor: NSColor.white])
    }

    var outputImage : NSImage  {
        let imageRep = bitmapImageRepForCachingDisplay(in: frame)!
        cacheDisplay(in: frame, to:imageRep)
        let tiffData = imageRep.tiffRepresentation!
        return NSImage(data : tiffData)!
    }
}

To use it, initialize a view

let image = ... // get some image
let view = ImageView(image: image, text: "Sample Text")

and get the new image

let imageWithText = view.outputImage

Note:

The paragraph style is not used at all, but if you want to create a mutable paragraph style just write

let textStyle = NSMutableParagraphStyle()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...