Fix mirrored image export with CGBitmapContext renderer
Draw base CGImage without coordinate flip, apply flip+scale only for annotations. Save via direct NSBitmapImageRep access instead of tiffRepresentation to avoid transform issues. Also redirect clipboard images to saveFolder instead of temp directory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,21 +26,39 @@ enum AnnotationRenderer {
|
||||
}
|
||||
|
||||
static func render(annotations: [AnnotationItem], onto image: NSImage) -> NSImage {
|
||||
guard let srcCG = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return image }
|
||||
let w = srcCG.width
|
||||
let h = srcCG.height
|
||||
let size = image.size
|
||||
let result = NSImage(size: size)
|
||||
result.lockFocusFlipped(true)
|
||||
|
||||
image.draw(in: NSRect(origin: .zero, size: size),
|
||||
from: .zero, operation: .sourceOver, fraction: 1,
|
||||
respectFlipped: true, hints: nil)
|
||||
guard let cs = srcCG.colorSpace ?? CGColorSpace(name: CGColorSpace.sRGB),
|
||||
let ctx = CGContext(
|
||||
data: nil, width: w, height: h,
|
||||
bitsPerComponent: 8, bytesPerRow: 0, space: cs,
|
||||
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
|
||||
) else { return image }
|
||||
|
||||
if let context = NSGraphicsContext.current?.cgContext {
|
||||
for item in annotations {
|
||||
draw(item, in: context)
|
||||
}
|
||||
ctx.draw(srcCG, in: CGRect(x: 0, y: 0, width: w, height: h))
|
||||
|
||||
ctx.translateBy(x: 0, y: CGFloat(h))
|
||||
let sx = CGFloat(w) / size.width
|
||||
let sy = CGFloat(h) / size.height
|
||||
ctx.scaleBy(x: sx, y: -sy)
|
||||
|
||||
NSGraphicsContext.saveGraphicsState()
|
||||
NSGraphicsContext.current = NSGraphicsContext(cgContext: ctx, flipped: true)
|
||||
|
||||
for item in annotations {
|
||||
draw(item, in: ctx)
|
||||
}
|
||||
|
||||
result.unlockFocus()
|
||||
NSGraphicsContext.restoreGraphicsState()
|
||||
|
||||
guard let resultCG = ctx.makeImage() else { return image }
|
||||
let bitmapRep = NSBitmapImageRep(cgImage: resultCG)
|
||||
bitmapRep.size = size
|
||||
let result = NSImage(size: size)
|
||||
result.addRepresentation(bitmapRep)
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user