Mac OS X 10.7.4
Je dessine dans un contexte graphique hors écran créé via Quand je tire dans ce contexte graphique Utilisation du Cependant, lorsque je dessine dans ce contexte graphique à l'aide du Pour des raisons pour lesquelles je ne vais pas entrer dans, j'ai vraiment besoin de dessiner à l'aide des fonctions Mon échantillon de code est répertorié ci-dessous. Je tente de dessiner un simple "x". Un trait utilisant + [nsgraphicsContext graphiqueContextwithbitmapimagere:] code>. p>
NSBEZIERPATH CODE> Classe Strong>, tout fonctionne comme prévu. P>
CGCONTEXTREF CODE> C Fonces Strong>, je ne vois aucun résultat de mon dessin. Rien ne fonctionne. P>
CGCONTEXTREF CODE> (plutôt que le cacao
nsbezierpath code> classe) . P>
nsbezierpath code>, une course à l'aide de
CGContexTref code> C. Le premier tour fonctionne, le second ne le fait pas. Qu'est-ce que je fais mal? P>
5 Réponses :
Vous ne spécifiez pas comment vous envisagez les résultats. Je suppose que vous regardez le lorsque vous appelez [img Lockfocus] Code>, vous modifiez le courant au lieu de verrouiller la mise au point sur un NSImage et de le dessiner, créez une nsimage et ajoutez l'offcreenrep comme l'un des ses représentants. P> nsimage code>
img code> et non le
nsbitmapimagere code>
elfreenrep code>.
nsgraphicscontext code> pour être un contexte à dessiner dans
img code>. Ainsi, le dessin code> nsbezierpath code> est dans
img code> et c'est ce que vous voyez. Le dessin CG passe dans
elfreenrep code> que vous ne regardez pas. P>
NSRect imgRect = NSMakeRect(0.0, 0.0, 100.0, 100.0);
NSSize imgSize = imgRect.size;
NSBitmapImageRep *offscreenRep = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:imgSize.width
pixelsHigh:imgSize.height
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bitmapFormat:NSAlphaFirstBitmapFormat
bytesPerRow:0
bitsPerPixel:0] autorelease];
// set offscreen context
NSGraphicsContext *g = [NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:g];
// draw first stroke with Cocoa
NSPoint p1 = NSMakePoint(NSMaxX(imgRect), NSMinY(imgRect));
NSPoint p2 = NSMakePoint(NSMinX(imgRect), NSMaxY(imgRect));
[NSBezierPath strokeLineFromPoint:p1 toPoint:p2];
// draw second stroke with Core Graphics
CGContextRef ctx = [g graphicsPort];
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, 0.0, 0.0);
CGContextAddLineToPoint(ctx, imgSize.width, imgSize.height);
CGContextClosePath(ctx);
CGContextStrokePath(ctx);
// done drawing, so set the current context back to what it was
[NSGraphicsContext restoreGraphicsState];
// create an NSImage and add the rep to it
NSImage *img = [[[NSImage alloc] initWithSize:imgSize] autorelease];
[img addRepresentation:offscreenRep];
// then go on to save or view the NSImage
Merci kurt. Oui, vous avez été correct dans votre hypothèse, je tente d'afficher dans code>. Aussi: votre correctif est correct et corrige le problème. Merci d'avoir refusé cela!
Je me demande pourquoi tout le monde écrit un tel code compliqué pour dessiner à une image. Sauf si vous vous souciez de la représentation de bitmap exacte d'une image (et que vous ne le faites pas!), Il n'est pas nécessaire de le créer un. Vous pouvez simplement créer une image vierge et le dessiner directement. Dans ce cas, le système créera une représentation bitmap appropriée (ou peut-être une représentation PDF ou quel que soit le système croit plus approprié pour le dessin).
La documentation de la méthode init p> qui existe depuis que MacOS 10.0 et n'est toujours pas obsolète, dit clairement: P> Après avoir utilisé cette méthode pour initialiser un objet image, vous êtes
devrait fournir le contenu de l'image avant d'essayer de dessiner la
image. Vous pouvez verrouiller la mise au point sur l'image et dessiner à l'image em> ou vous
pourrait explicitement ajouter une représentation d'image que vous avez créée. P>
BlockQuote> Voici comment j'aurais écrit ce code: p> c'est tout les gens. p> et documenté comme p> < BlockQuote>
Le contexte graphique spécifique à basse plate-forme représenté
par le port graphique. p>
blockQuote> qui peut être à peu près tout, mais la note finale indique p> Dans OS X, il s'agit du contexte graphique principal,
Un objet Cette propriété a été obsolète en 10.10 en faveur de la nouvelle propriété p> qui n'est disponible que dans 10.10 et ultérieure. Si vous devez soutenir les systèmes plus anciens, il convient de toujours utiliser
graphiqueport code> est en fait
vide * code>: p>
CGContextref code> (type opaque). p>
BlockQuote>
graphique code>. P> p>
Voici 3 façons de dessiner la même image (Swift 4).
La méthode suggérée par @Mecki produit une image sans floue code> artefacts (comme des courbes floues). Mais cela peut être corrigé en ajustant les paramètres
CGContext CODE> (non inclus dans cet exemple). P>
public struct ImageFactory {
public static func image(size: CGSize, fillColor: NSColor, rounded: Bool = false) -> NSImage? {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
return drawImage(size: size) { context in
if rounded {
let radius = min(size.height, size.width)
let path = NSBezierPath(roundedRect: rect, xRadius: 0.5 * radius, yRadius: 0.5 * radius).cgPath
context.addPath(path)
context.clip()
}
context.setFillColor(fillColor.cgColor)
context.fill(rect)
}
}
}
extension ImageFactory {
private static func drawImage(size: CGSize, drawingCalls: (CGContext) -> Void) -> NSImage? {
return drawImageInLockedImageContext(size: size, drawingCalls: drawingCalls)
}
private static func drawImageInLockedImageContext(size: CGSize, drawingCalls: (CGContext) -> Void) -> NSImage? {
let image = NSImage(size: size)
image.lockFocus()
guard let context = NSGraphicsContext.current else {
image.unlockFocus()
return nil
}
drawingCalls(context.cgContext)
image.unlockFocus()
return image
}
// Has scalling or antialiasing issues, like blurred curves.
private static func drawImageInBitmapImageContext(size: CGSize, drawingCalls: (CGContext) -> Void) -> NSImage? {
guard let offscreenRep = NSBitmapImageRep(pixelsWide: Int(size.width), pixelsHigh: Int(size.height),
bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true,
isPlanar: false, colorSpaceName: .deviceRGB) else {
return nil
}
guard let context = NSGraphicsContext(bitmapImageRep: offscreenRep) else {
return nil
}
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.current = context
drawingCalls(context.cgContext)
NSGraphicsContext.restoreGraphicsState()
let img = NSImage(size: size)
img.addRepresentation(offscreenRep)
return img
}
// Has scalling or antialiasing issues, like blurred curves.
private static func drawImageInCGContext(size: CGSize, drawingCalls: (CGContext) -> Void) -> NSImage? {
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
guard let context = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: 8,
bytesPerRow: 0, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) else {
return nil
}
drawingCalls(context)
guard let image = context.makeImage() else {
return nil
}
return NSImage(cgImage: image, size: size)
}
}
Swift 4: strong> J'utilise ce code, qui réplique l'API pratique de Uikit (mais exécute sur MacOS): let renderer = UIGraphicsImageRenderer(size: imageSize)
let image = renderer.image { ctx in
// Drawing commands here
}
@ingconti merci, corrigé maintenant. Cela a fonctionné dans mon projet avec UiImage parce que j'ai aussi eu: TypeAmias uiimage = Nsimage
La solution de @Robin Stewart a bien fonctionné pour moi. J'ai pu la condenser à une extension Nsimage. Usage: P> let image = NSImage(size: CGSize(width: 100, height: 100), actions: { ctx in
// Drawing commands here for example:
// ctx.setFillColor(.white)
// ctx.fill(pageRect)
})