Мне нужно захватить мой NSView на изображение.Сделать снимок NSWindow также будет хорошо - я могу просто обрезать необходимый вид позже.
У меня есть два требования: (1) у меня есть полупрозрачные кнопки на виде;(2) Мне нужно получить снимок, даже если изображение частично выходит за пределы экрана.
Это изображение, которое я хочу захватить:
Я попробовал эти четыре метода, и ни один из них не может сделать то, что я хочу.
Метод 1.
NSImage *image = [[NSImage alloc] initWithData:[view dataWithPDFInsideRect:viewRect]];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];
Этот метод сохраняет прозрачность кнопки, но игнорирует ее слойдополнения, такие как причудливая рамка:
Метод 2.
Это рекомендуемый метод для захвата содержимого NSView:
NSBitmapImageRep *imageRep = [view bitmapImageRepForCachingDisplayInRect:viewRect];
[view cacheDisplayInRect:viewRect toBitmapImageRep:imageRep];
NSImage *image = [[NSImage alloc] initWithSize:viewRect.size];
[image addRepresentation:imageRep];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];
Этот метод сохраняет элементы слоя, но игнорирует прозрачность кнопки:
Метод 3.
Этот метод просто отображаетпросмотр слоя в изображении:
NSImage *image = [[NSImage alloc] initWithSize:viewRect.size];
[image lockFocus];
CGContextRef ctx = [NSGraphicsContext currentContext].graphicsPort;
[view.layer renderInContext:ctx];
[image unlockFocus];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];
Этот метод также сохраняет элементы слоя, но игнорирует прозрачность кнопки:
Метод 4.
CGImageRef cgimg = CGWindowListCreateImage(CGRectZero, kCGWindowListOptionIncludingWindow, (int)self.window.windowNumber, kCGWindowImageBoundsIgnoreFraming);
NSImage *image = [[NSImage alloc] initWithCGImage:cgimg size:viewRect.size];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];
Этот метод сохраняет как свойства слоя, так и прозрачность кнопок, но если представление частично выходит за пределы экрана, тогдане отображать ту часть, которая находится вне экрана:
Итак, что я делаю не так?Как получить снимок экрана так же, как это делает системная утилита захвата экрана?